2222
2323
2424__all__ = (
25- 'StringProcessAdapter' , 'GlobalsItemDeletorMetaCls' , 'InheritedTestMethodsOverrideWrapperInstanceDecorator' ,
26- 'InheritedTestMethodsOverrideWrapperMetaClsAutoMixin' ,
25+ 'StringProcessAdapter' , 'GlobalsItemDeletorMetaCls' , 'InheritedTestMethodsOverrideWrapperMetaClsAutoMixin' ,
2726 'with_rw_repo' , 'with_rw_and_rw_remote_repo' , 'TestBase' , 'TestCase' , 'needs_module_or_skip'
2827 )
2928
@@ -239,44 +238,7 @@ def __new__(metacls, name, bases, clsdict):
239238 #END skip case that people import our base without actually using it
240239 #END handle deletion
241240 return new_type
242-
243-
244- class InheritedTestMethodsOverrideWrapperInstanceDecorator (object ):
245- """Utility to wrap all inherited methods into a given decorator and set up new
246- overridden methods on our actual type. This allows to adjust tests which are inherited
247- by our parent type, automatically. The decorator set in a derived type should
248- do what it has to do, possibly skipping the test if some prerequesites are not met.
249-
250- To use it, instatiate it and use it as a wrapper for the __new__ function of your metacls, as in
251-
252- __new__ = @InheritedTestMethodsOverrideWrapperInstanceDecorator(mydecorator)(MyMetaclsBase.__new__)"""
253241
254-
255- def __init__ (self , decorator ):
256- self .decorator = decorator
257-
258- def _patch_methods_recursive (self , bases , clsdict ):
259- """depth-first patching of methods"""
260- for base in bases :
261- self ._patch_methods_recursive (base .__bases__ , clsdict )
262- for name , item in base .__dict__ .iteritems ():
263- if not name .startswith ('test_' ):
264- continue
265- #END skip non-tests
266- clsdict [name ] = self .decorator (item )
267- #END for each item
268- #END for each base
269-
270- def __call__ (self , func ):
271- def wrapper (metacls , name , bases , clsdict ):
272- self ._patch_methods_recursive (bases , clsdict )
273- return func (metacls , name , bases , clsdict )
274- #END wrapper
275- assert func .__name__ == '__new__' , "Can only wrap __new__ function of metaclasses"
276- wrapper .__name__ = func .__name__
277- return wrapper
278-
279-
280242
281243class InheritedTestMethodsOverrideWrapperMetaClsAutoMixin (object ):
282244 """Automatically picks up the actual metaclass of the the type to be created,
@@ -299,11 +261,25 @@ def _find_metacls(metacls, bases):
299261 return metacls ._find_metacls (base .__bases__ )
300262 #END for each base
301263 raise AssertionError ("base class had not metaclass attached" )
302-
264+
265+ @classmethod
266+ def _patch_methods_recursive (metacls , bases , clsdict ):
267+ """depth-first patching of methods"""
268+ for base in bases :
269+ metacls ._patch_methods_recursive (base .__bases__ , clsdict )
270+ for name , item in base .__dict__ .iteritems ():
271+ if not name .startswith ('test_' ):
272+ continue
273+ #END skip non-tests
274+ clsdict [name ] = metacls .decorator [0 ](item )
275+ #END for each item
276+ #END for each base
277+
303278 def __new__ (metacls , name , bases , clsdict ):
304279 assert metacls .decorator , "'decorator' member needs to be set in subclass"
305280 base_metacls = metacls ._find_metacls (bases )
306- return InheritedTestMethodsOverrideWrapperInstanceDecorator (metacls .decorator [0 ])(base_metacls .__new__ )(base_metacls , name , bases , clsdict )
281+ metacls ._patch_methods_recursive (bases , clsdict )
282+ return base_metacls .__new__ (base_metacls , name , bases , clsdict )
307283
308284#} END meta classes
309285
0 commit comments