I am trying to create a wrapper class that behaves almost like the wrapped object. So far, I have come up with the following code:
import functools
import types
method_wrapper = type((None).__str__)
class Box:
def __new__(cls, obj):
attrs = {}
attr_names = dir(obj)
for attr_name in attr_names:
attr = obj.__getattribute__(attr_name)
if isinstance(attr, (types.MethodType, method_wrapper)):
"Attr is a bound method, ignore self"
@functools.wraps(attr)
def wrapped_attr(self, *args, **kwargs):
return attr(*args, **kwargs)
attrs[attr_name] = wrapped_attr
elif isinstance(attr, types.FunctionType):
"attr is a static method"
attrs[attr_name] = staticmethod(attr)
else:
"attr is a property"
attrs[attr_name] = attr
cls = type(type(obj).__name__,
(cls, type(obj)),
attrs)
return object.__new__(cls)
I tried testing it with:
if __name__ == '__main__':
x=Box(object())
However it comes up with the following error message:
TypeError: __init__() should return None, not 'NotImplementedType'
__init__
is being properly dispatched by isinstance(attr, (types.MethodType, method_wrapper))
, and wrapped_attr
seems to be executed. Do you have any idea why this is happening?
The problem is here:
for ...:
attr = ...
...
def wrapped_attr(...):
..attr..
This doesn't work as expected, because attr
is rebound to various values by the for
loop. All subfunctions will see the last value bound, not the value it had in that iteration of the loop. In this case, the last value bound, in alphabetical order, is __subclasshook__
, which tends to return NotImplemented when called with random arguments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With