[poky] [PATCH 3/7] bb: add bb.fetcher as dynamic fetch module instance for fetch/fetch2

Richard Purdie richard.purdie at linuxfoundation.org
Mon Jan 10 12:19:35 PST 2011


On Mon, 2011-01-10 at 16:43 +0000, Richard Purdie wrote:
> On Mon, 2011-01-10 at 11:42 +0000, Richard Purdie wrote:
> > On Mon, 2011-01-10 at 10:13 +0000, Joshua Lock wrote:
> > > On Sat, 2011-01-08 at 15:15 +0800, Yu Ke wrote:
> > > > +import bb
> > > > +from bb import fetch, fetch2
> > > > +
> > > > +# switch between fetch and fetch2
> > > > +instance = bb.fetch
> > > > +__version__ = "1"
> > > > +
> > > > +#instance = bb.fetch2
> > > > +#__version__ = "2"
> > > 
> > > I'm not very happy with this, it doesn't feel right. Can we not add some
> > > runtime determination of which module to use (a variable in
> > > bitbake.conf?) and then use some dynamic Python magic to add it to the
> > > imported modules list?
> > > 
> > > A quick Google makes me thing we could do something more dynamic with
> > > the __import__() function.
> > 
> > Agreed, I was also thinking about this but wanted to come up with a
> > suggestion about how to better handle it. There is some interesting info
> > in this webpage:
> > 
> > http://stackoverflow.com/questions/1096216/override-namespace-in-python
> > 
> > This example in particular looks useful:
> > 
> > def weirdimport(fullpath):
> >   global project
> > 
> >   import os
> >   import sys
> >   sys.path.append(os.path.dirname(fullpath))
> >   try:
> >       project = __import__(os.path.basename(fullpath))
> >       sys.modules['project'] = project
> >   finally:
> >       del sys.path[-1]
> > 
> > Although we shouldn't need to manipulate sys.path in our case.
> > 
> > As Joshua mentions, overriding the __import__ builtin should also work
> > and might avoid some ordering issues we'd have with the above.
> 
> I did come up with this code inserted at the start of bin/bitbake:
> 
> origimport = __builtins__.__import__
> def bbimport(name, *args, **kwargs):
>     newname = name
>     if name.find("bb.fetch") != -1:
>         newname = name.replace("bb.fetch", "bb.fetch2")
>     ret = origimport(newname, *args, **kwargs)
>     if name != newname:
>         sys.modules[name] = sys.modules[newname]
>         if name == "bb.fetch":
>             bb.fetch = sys.modules[newname]
>     return ret
> if os.environ.get('BBFETCH2'):
>     __builtins__.__import__ = bbimport
> 
> which is pretty ugly :(. The big advantage of this is that it does
> redirect any bb.fetch calls into bb.fetch2 calls, even within the
> bb.fetch2 codebase.
> 
> I'm working through some other ideas as time permits.

If we assume bb.fetch2 will not make calls to bb.fetch we can simplify
this to:

if os.environ.get("BBFETCH2"):
    from bb import fetch2 as fetch
    sys.modules['bb.fetch'] = sys.modules['bb.fetch2']

so from the environment you can trigger the new fetcher code. For Poky,
I've added something to hardcode that behaviour since I don't want it to
break.

I've pushed this both into Poky and bitbake upstream so we're in sync
and can move forward on improving the fetcher code :).

Cheers,

Richard









More information about the poky mailing list