# HG changeset patch # User Tony Tung # Date 1454545354 28800 # Wed Feb 03 16:22:34 2016 -0800 # Node ID 7d22fc236798ee05ff55054fff060a112c663303 # Parent b5154d03849cebfc01ab0029fc7ae7be756402a2 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 diff --git a/extutil.py b/extutil.py new file mode 100644 --- /dev/null +++ b/extutil.py @@ -0,0 +1,36 @@ +# 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 diff --git a/manifestdiskcache.py b/manifestdiskcache.py --- a/manifestdiskcache.py +++ b/manifestdiskcache.py @@ -44,42 +44,14 @@ import time import traceback +from extutil import replaceclass + CACHE_SUBDIR = 'manifestdiskcache' CONFIG_KEY = 'manifestdiskcache' HEX_SHA_SIZE_BYTES = 40 testedwith = 'internal' -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 extsetup(ui): global logging logging = ui.configbool(CONFIG_KEY, 'logging', False) diff --git a/tests/test-manifestdiskcache.t b/tests/test-manifestdiskcache.t --- a/tests/test-manifestdiskcache.t +++ b/tests/test-manifestdiskcache.t @@ -1,7 +1,6 @@ Setup - $ extpath=`dirname $TESTDIR` - $ cp $extpath/manifestdiskcache.py $TESTTMP # use $TESTTMP substitution in message + $ export PYTHONPATH=$TESTDIR/..:$PYTHONPATH Test functionality is present @@ -10,7 +9,7 @@ $ hg init $ cat >> .hg/hgrc << EOF > [extensions] - > manifestdiskcache=$TESTTMP/manifestdiskcache.py + > manifestdiskcache= > [manifestdiskcache] > logging=True > enabled=True @@ -46,7 +45,7 @@ $ hg init $ cat >> .hg/hgrc << EOF > [extensions] - > manifestdiskcache=$TESTTMP/manifestdiskcache.py + > manifestdiskcache= > [manifestdiskcache] > logging=True > enabled=True @@ -98,7 +97,7 @@ $ hg init $ cat >> .hg/hgrc << EOF > [extensions] - > manifestdiskcache=$TESTTMP/manifestdiskcache.py + > manifestdiskcache= > [manifestdiskcache] > enabled=True > EOF @@ -139,7 +138,7 @@ OK $ cat >> .hg/hgrc << EOF > [extensions] - > manifestdiskcache=$TESTTMP/manifestdiskcache.py + > manifestdiskcache= > [manifestdiskcache] > cache-size=0 > runs-between-prunes=1