mirror of
https://github.com/facebook/sapling.git
synced 2024-10-07 07:17:55 +03:00
96fb5e9e89
Summary: We move wrapfilecache from reflog to extutil to be able to reuse it in fastmanifest Test Plan: Tests pass Reviewers: ttung Subscribers: mjpieters Differential Revision: https://phabricator.intern.facebook.com/D3318762
57 lines
2.0 KiB
Python
57 lines
2.0 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
|
|
|
|
def wrapfilecache(cls, propname, wrapper):
|
|
"""Wraps a filecache property. These can't be wrapped using the normal
|
|
wrapfunction. This should eventually go into upstream Mercurial.
|
|
"""
|
|
origcls = cls
|
|
assert callable(wrapper)
|
|
while cls is not object:
|
|
if propname in cls.__dict__:
|
|
origfn = cls.__dict__[propname].func
|
|
assert callable(origfn)
|
|
def wrap(*args, **kwargs):
|
|
return wrapper(origfn, *args, **kwargs)
|
|
cls.__dict__[propname].func = wrap
|
|
break
|
|
cls = cls.__bases__[0]
|
|
|
|
if cls is object:
|
|
raise AttributeError(_("type '%s' has no property '%s'") % (origcls,
|
|
propname))
|