sapling/hgext3rd/extutil.py
Jun Wu 8a3a99ba21 hgext: move single file extensions to hgext3rd
Summary:
Be a better citizen under system python path.

Fix all tests issues and change setup.py to use glob pattern to include
all extensions.

Test Plan:
Run tests and `make local`.
Also build and install the package and run `hg sl` in major repos.

Reviewers: #mercurial, ttung, rmcelroy

Reviewed By: rmcelroy

Subscribers: rmcelroy, durham, mjpieters

Differential Revision: https://phabricator.intern.facebook.com/D3534311

Signature: t1:3534311:1468275426:fe122646c8bd6c541e1889e73e9df28f86747ff2
2016-07-08 13:15:42 +01: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