attrs
attrs copied to clipboard
TypeError when calling super() in decorated method
Following code:
import attrs
def decorated(method):
def wrapped(self, *args, **kwargs):
return method(self, *args, **kwargs)
return wrapped
@attrs.define()
class A:
def f(self):
pass
@attrs.define()
class B(A):
@decorated
def f(self):
super().f()
B().f()
raises following error
TypeError: super(type, obj): obj must be an instance or subtype of type
If I use super(B, self)
, everything works just fine.
This problem is related to cell rewriting for slotted classes. Put simply we have to cheat a bit to make them work by rewriting method contents.
You get the same behavior with dataclasses:
@dataclasses.dataclass(slots=True)
@attrs.define
class C:
@decorated
def f(self):
super().f()
TypeError: super(type, obj): obj must be an instance or subtype of type
Short fixes:
- don't use super that way
- disable slots (
@attrs.define(slots=False)
)
Long-term fixes:
- open a bug on CPython for the dataclasses case and we'll steal it from them
- convince @Tinche to fix it for attrs right away ;)
I'm a bit dubious if it's actually possible to fix tho. :-/ Maybe, if functools.wraps
is used and we follow the __wrapped__
attributes?
Thanks for the quick response! I'll use super(B, self)
for now.