[PATCH] keyword: make repo.commit use a custom commitctx wrapper

Matt Mackall mpm at selenic.com
Thu Jul 2 09:40:44 CDT 2009


On Thu, 2009-07-02 at 11:18 +0200, Christian Ebert wrote:
> * Christian Ebert on Tuesday, June 30, 2009 at 10:13:28 -0000
> > # HG changeset patch
> > # User Christian Ebert <blacktrash at gmx.net>
> > # Date 1246354203 -7200
> > # Node ID 02f1d60fe9bf5274d5b4cf409963815694c24338
> > # Parent  bacb06d1e8b60b6083e3139fc5fb23355612eef8
> > keyword: make repo.commit use a custom commitctx wrapper
> 
> <snip>
> 
> A question about my own patch ;-)
> 
> > @@ -460,8 +461,14 @@
> > 
> >         def commit(self, text='', user=None, date=None, match=None,
> >                    force=False, editor=None, extra={}):
> > +            # use custom commitctx for user commands
> > +            # other extensions can still wrap repo.commitctx directly
> > +            repo.commitctx = self.kwcommitctx
> 
> The above line works also as:
> 
>              self.commitctx = self.kwcommitctx
> 
> Background:
> 
> In reposetup(ui, repo) I override the repo class:
> 
>     class kwrepo(repo.__class__):
> 
> and later on do things like:
>    
>         lock = self.wlock()
> 
> even though wlock is not defined in kwrepo. Playing around with
> pylint, it complained about that "kwrepo has no wlock member",
> but felt better after I changed the above to
> 
>         lock = repo.wlock()
> 
> as it would have complained if I had
> 
>              self.commitctx = self.kwcommitctx
> 
> instead of
> 
>              repo.commitctx = self.kwcommitctx
> 
> in my patch. 
>
> mq does something similar and uses self consistently (with pylint
> complaining accordingly). Which is the way to go? Is there a
> difference wrt to safety? According to test-keyword it doesn't
> make a difference, but which way should I choose for consistency?

See cset 5726bb290bfe.

However, member functions turn out to be a special issue, see
5726bb290bfe. When you do:

 a = object.func

you're effectively doing:

 a = lambda *args, **kwargs: object.func(*args, **kwargs)

which binds a reference to object up inside of a. So when you do:

 self.func2 = self.func1

you're effectively making a reference cycle inside self and making self
immortal. A kwrepo wrapping a bundlerepo will thus cause problems
because bundlerepo won't be able to clean up after itself. So how do we
wrap an object's method without introducing a cycle? The best way I know
is to do it at the class level:

class a(b.__class__):
    def func(self, *args):
	super(a, self).func(*args)

-- 
http://selenic.com : development and support for Mercurial and Linux




More information about the Mercurial-devel mailing list