Commit 5a6a6f4f authored by Hanno Schlichting's avatar Hanno Schlichting

Raise `RuntimeError: Recursion detected in acquisition wrapper` if an object...

Raise `RuntimeError: Recursion detected in acquisition wrapper` if an object with a `__parent__` pointer points to a wrapper that in turn points to the original object.
parent 35386343
...@@ -4,6 +4,10 @@ Changelog ...@@ -4,6 +4,10 @@ Changelog
4.0 (unreleased) 4.0 (unreleased)
---------------- ----------------
- Raise `RuntimeError: Recursion detected in acquisition wrapper` if an object
with a `__parent__` pointer points to a wrapper that in turn points to the
original object.
- Prevent wrappers to be created while accessing `__parent__` on types derived - Prevent wrappers to be created while accessing `__parent__` on types derived
from Explicit or Implicit base classes. from Explicit or Implicit base classes.
......
...@@ -545,7 +545,15 @@ Wrapper_findattr(Wrapper *self, PyObject *oname, ...@@ -545,7 +545,15 @@ Wrapper_findattr(Wrapper *self, PyObject *oname,
Py_XDECREF(r); Py_XDECREF(v); Py_XDECREF(tb); Py_XDECREF(r); Py_XDECREF(v); Py_XDECREF(tb);
r=NULL; r=NULL;
} }
/* normal attribute lookup */ /* Deal with mixed __parent__ / aq_parent circles */
else if (self->container && isWrapper(self->container) &&
WRAPPER(self->container)->container &&
self == WRAPPER(WRAPPER(self->container)->container)) {
PyErr_SetString(PyExc_RuntimeError,
"Recursion detected in acquisition wrapper");
return NULL;
}
/* normal attribute lookup */
else if ((r=PyObject_GetAttr(self->obj,oname))) else if ((r=PyObject_GetAttr(self->obj,oname)))
{ {
if (r==Acquired) if (r==Acquired)
......
...@@ -2362,7 +2362,7 @@ def test___parent__aq_parent_circles(): ...@@ -2362,7 +2362,7 @@ def test___parent__aq_parent_circles():
>>> x.__parent__.__parent__ is x >>> x.__parent__.__parent__ is x
True True
>>> x.hello >>> x.hello
'world' 'world'
>>> Acquisition.aq_acquire(x, 'hello') >>> Acquisition.aq_acquire(x, 'hello')
...@@ -2383,20 +2383,17 @@ def test___parent__aq_parent_circles(): ...@@ -2383,20 +2383,17 @@ def test___parent__aq_parent_circles():
>>> Acquisition.aq_acquire(y, 'non_existant_attr') >>> Acquisition.aq_acquire(y, 'non_existant_attr')
Traceback (most recent call last): Traceback (most recent call last):
... ...
AttributeError: non_existant_attr RuntimeError: Recursion detected in acquisition wrapper
>>> x.non_existant_attr >>> x.non_existant_attr
Traceback (most recent call last): Traceback (most recent call last):
... ...
AttributeError: non_existant_attr AttributeError: non_existant_attr
"""
# XXX: disabled
"""
>>> y.non_existant_attr >>> y.non_existant_attr
Traceback (most recent call last): Traceback (most recent call last):
... ...
AttributeError: non_existant_attr RuntimeError: Recursion detected in acquisition wrapper
""" """
def test_unwrapped_implicit_acquirer_unwraps__parent__(): def test_unwrapped_implicit_acquirer_unwraps__parent__():
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment