Reclassing instances like this is done in Mercurial (a distributed revision control system) when extensions (plugins) want to change the object that represent the local repository. The object is called repo
and is initially a localrepo
instance. It is passed to each extension in turn and, when needed, extensions will define a new class which is a subclass of repo.__class__
and change the class of repo
to this new subclass!
It looks like this in code:
def reposetup(ui, repo):
# ...
class bookmark_repo(repo.__class__):
def rollback(self):
if os.path.exists(self.join('undo.bookmarks')):
util.rename(self.join('undo.bookmarks'), self.join('bookmarks'))
return super(bookmark_repo, self).rollback()
# ...
repo.__class__ = bookmark_repo
The extension (I took the code from the bookmarks extension) defines a module level function called reposetup
. Mercurial will call this when initializing the extension and pass a ui
(user interface) and repo
(repository) argument.
The function then defines a subclass of whatever class repo
happens to be. It would not suffice to simply subclass localrepo
since extensions need to be able to extend each other. So if the first extension changes repo.__class__
to foo_repo
, the next extension should change repo.__class__
to a subclass of foo_repo
and not just a subclass of localrepo
. Finally the function changes the instanceø’s class, just like you did in your code.
I hope this code can show a legitimate use of this language feature. I think it’s the only place where I’ve seen it used in the wild.