sapling/extutil.py
Tony Tung 560631448d extract replaceclass out of manifestdiskcache
Summary: It's an useful function.  Plan to use it in another extension.

Test Plan: python ../../hg-crew/tests/run-tests.py --with-hg ../../hg-crew/hg test-manifestdiskcache.t

Reviewers: #sourcecontrol, lcharignon

Reviewed By: lcharignon

Subscribers: lcharignon, mitrandir

Differential Revision: https://phabricator.fb.com/D2896753

Signature: t1:2896753:1454542605:c660ee3e108b497c4a823bd732f98ebf5e147e02
2016-02-03 16:22:34 -08:00

37 lines
1.3 KiB
Python

# extutil.py - useful utility methods for extensions
#
# Copyright 2016 Facebook
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
def replaceclass(container, classname):
'''Replace a class with another in a module, and interpose it into
the hierarchies of all loaded subclasses. This function is
intended for use as a decorator.
import mymodule
@replaceclass(mymodule, 'myclass')
class mysubclass(mymodule.myclass):
def foo(self):
f = super(mysubclass, self).foo()
return f + ' bar'
Existing instances of the class being replaced will not have their
__class__ modified, so call this function before creating any
objects of the target type.
'''
def wrap(cls):
oldcls = getattr(container, classname)
for subcls in oldcls.__subclasses__():
if subcls is not cls:
assert oldcls in subcls.__bases__
newbases = [oldbase
for oldbase in subcls.__bases__
if oldbase != oldcls]
newbases.append(cls)
subcls.__bases__ = tuple(newbases)
setattr(container, classname, cls)
return cls
return wrap