Python plugins, third round

John A Meinel john at
Thu Jun 16 05:41:22 BST 2005

Aaron Bentley wrote:

> Martin Pool wrote:
> >On 15 Jun 2005, Aaron Bentley < at> wrote:
> >>As for making plugins load fast, I'm not sure that's possible.  Plugins
> >>must import any bzr modules they affect, so if you unconditionally
> >>import a plugin that affects bzrlib.remote_branch (a popular example),
> >>then you are unconditionally importing bzrlib.remote_branch.  And such a
> >>module would probably also want to import bzrlib.branch, in order to
> >>override bzrlib.branch.find_branch.
> >Bear in mind that Python imports are processed when the import
> >statement is executed, not (as for Java) when the module is loaded.
> >So if you import something inside a function or method, it will only
> >be pulled in when that method runs.
> >The main place this is hard to do is that you typically need to import
> >classes at the top level if you want to subclass them.  (I can imagine
> >contortions to avoid that but it's not good.)
> The other case where it's hard is when you want to change module values,
> e.g.
> branch.branch_types['sftp://'] = SftpBranch
> # or monkey-patching example
> _real_find_branch = branch.find_branch
> def find_branch(loc):
>     if loc.startswith('sftp://'):
>         return SftpBranch(loc)
>     else:
>         return _real_find_branch(loc)
> branch.find_branch = find_branch
> So I think most of the time, importing a plugin will mean importing the
> section of bzrlib that the plugin affects, too.

I think that is always the case. Just that normally importing "bzrlib"
will import most of everything anyway. Since there is a lot of stuff
like bzrlib.Inventory (from inventory.Inventory).

> >I think we should also make this default to ~/.bzr/plugins (and
> >perhaps also something system-wide),
> Yes, a system-wide path would be very nice.  If we supported packages in
> there as well as modules, I'd be a happy camper indeed.

When you are saying packages, do you mean:
mypackage/ ?
That is much easier to do (and more reasonable) than doing the single
directory recursion. Since python imports that as "mypackage".

So it is pretty easy to alter my code to support everything of the form:


All of those would be loaded from:
    import plugin

The only one my revised code didn't support was the plugin/
form. Which is easy to add. (Just if it is a directory look for the, if it exists, then import the directory).

> >and allow for it to be extended.
> Or set to empty too, I suppose.
> >As a general principle I wanted to have most options have the same
> >syntax and similar meaning across commands.  I think svn got this
> >right and cvs notably wrong.  But obviously some plugins might want to
> >use options that aren't standard.  Perhaps the Command.takes_options
> >field should be a list of either standard option names, or tuples
> >describing new options.
> Sure.  There is a bit of a chicken-and-egg problem.  Consider
> bzr commit --something --builtin
> If the user specifies --builtin, then we should not import a
> non-standard commit.  But we don't know whether --something takes an
> argument, so --builtin might be an argument, not an option.
The way the current code works is that "builtin" is actually a command,
not an option. So you have:
bzr builtin commit --something
You could also require "--builtin" to be the first option. So it would
always be
bzr --builtin commit --something.

The point is that the builtin gets stripped off before normal argument

> Okay, so it's not all that likely :-)

> Aaron


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 253 bytes
Desc: OpenPGP digital signature
Url : 

More information about the bazaar mailing list