A possible clever trick for extension writing

Augie Fackler durin42 at gmail.com
Sun Nov 27 17:43:29 CST 2011


On Nov 27, 2011, at 10:49 AM, Greg Ward wrote:

> On Sat, Nov 26, 2011 at 9:17 PM, I wrote:
>> A common pattern in Mercurial extensions is the "dynamic subclass"
>> trick. E.g. here is the world's simplest extension using that trick:
> [...]
>> But of course, this doesn't solve the *real* problem. The *real*
>> problem is that I first heard about metaclasses in 1998, back when Jim
>> Fulton was still trying convince people there was a problem with
>> Python's type system. Ever since Python 2.2 came out I've been looking
>> for an excuse to write a metaclass. I may have finally found my
>> excuse: Mercurial extensions.
> 
> Hahaha never mind. Metaclasses are *still* a solution looking for
> problems. This problem is solvable with that good-old fashioned
> workhorse of code refactoring, the subroutine:
> 
> """
> def makesubclass(repo, name, classtemplate):
>    '''Make a new repository subclass and insert it into the class
>    hierarchy of repo, dynamically changing the type of
>    repo. classtemplate is an object whose __dict__ attribute will be
>    used as source of attributes for the new subclass: typically it's
>    a "classic" class that just provides instance methods, some of
>    which override methods of localrepository.'''
>    newclass = type(name,
>                    (repo.__class__,),
>                    classtemplate.__dict__)
>    repo.__class__ = newclass
> 
> def reposetup(ui, repo):
>    makesubclass(repo, 'simplerepo', simplerepo_template)
> """
> 
> The idea is:
> 
>  * add makesubclass() to mercurial/extensions.py
>  * modify existing extensions (e.g. mq, largefiles, ...):
>    - pull the localrepository subclass up to module scope
>    - change references to 'ui' (closure dependent) to 'self.ui'
>    - make reposetup call makesubclass()
> 
> Benefits:
>  * less indented code
>  * a common bit of magic is factored out to extensions.py
> 
> Drawback: the "template" class that implements a lot of essential
> extension logic isn't a real class (it's never instantiated or
> subclassed) -- it's just a namespace created with the convenient
> "class" syntax. The real class is hidden away behind the scenes.

As an abuser of the extension API, I guess I'd find this a little useful.

> 
> Greg
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel



More information about the Mercurial-devel mailing list