The problem is demonstrated by the following code:
>>> from Acquisition import Implicit
>>> class I(Implicit):
... def add(self, id, o):
... setattr(self, id, o)
... return getattr(self, id)
...
>>> top = I()
>>> f = top.add("f", I())
>>>
>>> i = I()
>>> i.add("f", f)
<__main__.I object at 0x7f7b8acbf668>
>>> i.f.aq_self is f
False
Works in the "C" version.
The problem is caused by Acquisition._Wrapper.__of__:
def __of__(self, parent):
# Based on __of__ in the C code;
# simplify a layer of wrapping.
# We have to call the raw __of__ method or we recurse on our
# own lookup (the C code does not have this issue, it can use
# the wrapped __of__ method because it gets here via the
# descriptor code path)...
wrapper = self._obj.__of__(parent)
if (not isinstance(wrapper, _Wrapper) or
not isinstance(wrapper._container, _Wrapper)):
return wrapper
# but the returned wrapper should be based on this object's
# wrapping chain
wrapper._obj = self
while (isinstance(wrapper._obj, _Wrapper) and
(wrapper._obj._container is wrapper._container._obj)):
# Since we mutate the wrapper as we walk up, we must copy
# XXX: This comes from the C implementation. Do we really need to
# copy?
wrapper = type(wrapper)(wrapper._obj, wrapper._container)
wrapper._obj = wrapper._obj._obj
return wrapper
The problem is demonstrated by the following code:
Works in the "C" version.
The problem is caused by
Acquisition._Wrapper.__of__
:It fails, if
parent
is not a wrapper.