Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork411
Description
With attrs 24.2.0 and 23.2.0, if you usecached_property and try to override it in a child, and access the parent value, you get anAttributeError. We ran into this in our code when converting some classes to use slots.
I see there was support added in24.2.0 for
Allow super() calls in slotted cached properties
But attrs still doesn't support"super() callsof overridden cached_property's in slotted classes":
fromfunctoolsimportcached_propertyimportattrs@attrs.define(slots=True)classParent:@cached_propertydefname(self)->str:return"Alice"@attrs.define(slots=True)classChild(Parent):@cached_propertydefname(self)->str:returnf"Bob (son of{super().name})"p=Parent()print(p.name)# prints Alicec=Child()print(c.name)# error:
Traceback (most recent call last): File "foo.py", line 23, in <module> print(c.name) ^^^^^^ File "<attrs generated getattr __main__.Child>", line 6, in __getattr__ File "foo.py", line 18, in name return f"Bob (son of {super().name})" ^^^^^^^^^^^^AttributeError: 'Child' object has no attribute 'name'Workarounds:
- disable slots
- don't use cached_property
- don't override the method
Elaboration:
I see the special handling is describedin the docs and I seein the code that it generates a special__getattr__ that sets the generated value in the slot after being called. Perhaps when constructing a class, attrs should also walk the MRO forcached_propertys and handle any overriddencached_property methods — perhaps create some sort of namespaced/name-mangled properties for the parent.