[appy] appy.Hack: bugfix (patch of static methods).
This commit is contained in:
parent
93504cc0f3
commit
cf0309cb26
26
__init__.py
26
__init__.py
|
@ -65,11 +65,12 @@ class Hack:
|
||||||
# On this class, store m_method under its "base" name
|
# On this class, store m_method under its "base" name
|
||||||
name = isStatic and method.func_name or method.im_func.__name__
|
name = isStatic and method.func_name or method.im_func.__name__
|
||||||
baseName = '_base_%s_' % name
|
baseName = '_base_%s_' % name
|
||||||
|
if isStatic:
|
||||||
|
# If "staticmethod" isn't called hereafter, the static functions
|
||||||
|
# will be wrapped in methods.
|
||||||
|
method = staticmethod(method)
|
||||||
|
replacement = staticmethod(replacement)
|
||||||
setattr(klass, baseName, method)
|
setattr(klass, baseName, method)
|
||||||
# Store the replacement method on klass. When doing so, even when
|
|
||||||
# m_method is static, it is wrapped in a method. This is why, in
|
|
||||||
# m_base below, when the method is static, we return method.im_func to
|
|
||||||
# retrieve the original static method.
|
|
||||||
setattr(klass, name, replacement)
|
setattr(klass, name, replacement)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -79,17 +80,21 @@ class Hack:
|
||||||
isStatic = klass
|
isStatic = klass
|
||||||
klass = klass or method.im_class
|
klass = klass or method.im_class
|
||||||
name = isStatic and method.func_name or method.im_func.__name__
|
name = isStatic and method.func_name or method.im_func.__name__
|
||||||
res = getattr(klass, '_base_%s_' % name)
|
return getattr(klass, '_base_%s_' % name)
|
||||||
if isStatic: res = res.im_func
|
|
||||||
return res
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def inject(patchClass, klass, verbose=False):
|
def inject(patchClass, klass, verbose=False):
|
||||||
'''Injects any method or attribute from p_patchClass into klass.'''
|
'''Injects any method or attribute from p_patchClass into klass.'''
|
||||||
patched = []
|
patched = []
|
||||||
added = []
|
added = []
|
||||||
for name, attr in patchClass.__dict__.iteritems():
|
for name, attr in patchClass.__dict__.items():
|
||||||
if name.startswith('__'): continue # Ignore special methods
|
if name.startswith('__'): continue # Ignore special methods
|
||||||
|
# Unwrap functions from static methods
|
||||||
|
if attr.__class__.__name__ == 'staticmethod':
|
||||||
|
attr = attr.__get__(attr)
|
||||||
|
static = True
|
||||||
|
else:
|
||||||
|
static = False
|
||||||
# Is this name already defined on p_klass ?
|
# Is this name already defined on p_klass ?
|
||||||
if hasattr(klass, name):
|
if hasattr(klass, name):
|
||||||
hasAttr = True
|
hasAttr = True
|
||||||
|
@ -99,7 +104,10 @@ class Hack:
|
||||||
klassAttr = None
|
klassAttr = None
|
||||||
if hasAttr and callable(attr) and callable(klassAttr):
|
if hasAttr and callable(attr) and callable(klassAttr):
|
||||||
# Patch this method via Hack.patch
|
# Patch this method via Hack.patch
|
||||||
Hack.patch(klassAttr, attr)
|
if static:
|
||||||
|
Hack.patch(klassAttr, attr, klass)
|
||||||
|
else:
|
||||||
|
Hack.patch(klassAttr, attr)
|
||||||
patched.append(name)
|
patched.append(name)
|
||||||
else:
|
else:
|
||||||
# Simply replace the static attr or add the new static
|
# Simply replace the static attr or add the new static
|
||||||
|
|
Loading…
Reference in a new issue