Acquisition: attribute assignment not faithful
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Zope 2 |
Invalid
|
Low
|
Unassigned |
Bug Description
Usually, when you assign a value to an attribute, you would expect to retrieve the same value later from this attribute. This is not the case for "ExtensionClass" instances, as they may call the attributes "__of__" method (if any) and return its result -- a well documented feature.
The idiom "obj.__
>>> wrapper.attr = value
>>> wrapper.
False
The reason for this: acquisition wrapper attribute assignment explicitely removes the acquisition context before storing the
value on the wrapped object.
Obviously, the implementer thought this a feature -- but forgot to document it.
The feature leads to highly surprising behaviour: usually acquisition wrappers mask themselves very successfully as the wrapped objects. Rarely, developers are concious whether they work with a wrapper or the base object. Now, while acquisition wrapped attributes values can faithfully be stored on the base object (e.g. in the __init__ method), they are no longer faithfully stored when the same object is wrapped. Yesterday, I spent several hours to analyse a problem caused by this behaviour.
As I expect that the feature cannot be removed (for backward compatibility reasons), I suggest to document it clearly.
Here an example for the unfaithful attribute assignment:
>>> from Acquisition import Implicit
>>> class C(Implicit):
... pass
...
>>> c0 = C()
>>> c1 = C().__of__(c0)
>>> c2 = C().__of__(c0)
>>> c1.x = c2
>>> c1.__dict__['x'] is c2
False
Patches for the documentation are welcome.