A possible clever trick for extension writing
Greg Ward
greg at gerg.ca
Sun Nov 27 16:49:07 UTC 2011
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.
Greg
More information about the Mercurial-devel
mailing list