Make Acquisition.aq_inContextOf aware of __parent__ pointers.

parent 95e69c37
......@@ -1190,54 +1190,8 @@ Wrapper_acquire_method(Wrapper *self, PyObject *args, PyObject *kw)
# endif
}
static PyObject *
capi_aq_inContextOf(PyObject *self, PyObject *o, int inner)
{
PyObject *next, *c;
if (inner) {
/* next = self
o = aq_base(o) */
next = self;
while (isWrapper(o) && WRAPPER(o)->obj)
o=WRAPPER(o)->obj;
/* while 1: */
while (1) {
/* if aq_base(next) is o: return 1 */
c = next;
while (isWrapper(c) && WRAPPER(c)->obj) c = WRAPPER(c)->obj;
if (c == o) return PyInt_FromLong(1);
/* self = aq_inner(next) */
/* if self is None: break */
if (isWrapper(next)) {
self = next;
while (WRAPPER(self)->obj && isWrapper(WRAPPER(self)->obj))
self = WRAPPER(self)->obj;
}
else break;
/* next = aq_parent(self) */
/* if next is None: break */
if (WRAPPER(self)->container)
next = WRAPPER(self)->container;
else break;
}
}
else {
/* Follow wrappers instead. */
c = (PyObject*)self;
while (1) {
if (c==o) return PyInt_FromLong(1);
if (c && isWrapper(c)) c=WRAPPER(c)->container;
else break;
}
}
return PyInt_FromLong(0);
}
/* forward declaration so that we can use it in Wrapper_inContextOf */
static PyObject * capi_aq_inContextOf(PyObject *self, PyObject *o, int inner);
static PyObject *
Wrapper_inContextOf(Wrapper *self, PyObject *args)
......@@ -1752,6 +1706,41 @@ module_aq_chain(PyObject *ignored, PyObject *args)
return capi_aq_chain(self, containment);
}
static PyObject *
capi_aq_inContextOf(PyObject *self, PyObject *o, int inner)
{
PyObject *next, *c;
/* next = self
o = aq_base(o) */
next = self;
while (isWrapper(o) && WRAPPER(o)->obj)
o=WRAPPER(o)->obj;
while (1) {
/* if aq_base(next) is o: return 1 */
c = next;
while (isWrapper(c) && WRAPPER(c)->obj) c = WRAPPER(c)->obj;
if (c == o) return PyInt_FromLong(1);
if (inner)
{
self = capi_aq_inner(next);
Py_DECREF(self); /* We're not holding on to the inner wrapper */
if (self == Py_None) break;
}
else
self = next;
next = capi_aq_parent(self);
Py_DECREF(next); /* We're not holding on to the parent */
if (next == Py_None) break;
}
return PyInt_FromLong(0);
}
static PyObject *
module_aq_inContextOf(PyObject *ignored, PyObject *args)
{
......
......@@ -1232,6 +1232,9 @@ def test_aq_inContextOf():
... def hi(self):
... print "%s()" % self.__class__.__name__, self.color
>>> class Location(object):
... __parent__ = None
>>> b=B()
>>> b.a=A()
>>> b.a.hi()
......@@ -1261,6 +1264,8 @@ def test_aq_inContextOf():
>>> b.c == c
1
>>> l = Location()
>>> l.__parent__ = b.c
>>> def checkContext(self, o):
... # Python equivalent to aq_inContextOf
......@@ -1276,6 +1281,7 @@ def test_aq_inContextOf():
... next = aq_parent(self)
... if next is None:
... break
... return 0
>>> checkContext(b.c, b)
......@@ -1283,13 +1289,27 @@ def test_aq_inContextOf():
>>> not checkContext(b.c, b.a)
1
>>> checkContext(l, b)
1
>>> checkContext(l, b.c)
1
>>> not checkContext(l, b.a)
1
Acquisition.aq_inContextOf works the same way:
>>> Acquisition.aq_inContextOf(b.c, b)
1
>>> not Acquisition.aq_inContextOf(b.c, b.a)
>>> Acquisition.aq_inContextOf(b.c, b.a)
0
>>> Acquisition.aq_inContextOf(l, b)
1
>>> Acquisition.aq_inContextOf(l, b.c)
1
>>> Acquisition.aq_inContextOf(l, b.a)
0
>>> b.a.aq_inContextOf(b)
1
>>> b.c.aq_inContextOf(b)
......@@ -1300,12 +1320,12 @@ def test_aq_inContextOf():
1
>>> b.c.d.aq_inContextOf(b.c)
1
>>> not b.c.aq_inContextOf(foo)
1
>>> not b.c.aq_inContextOf(b.a)
1
>>> not b.a.aq_inContextOf('somestring')
1
>>> b.c.aq_inContextOf(foo)
0
>>> b.c.aq_inContextOf(b.a)
0
>>> b.a.aq_inContextOf('somestring')
0
"""
def test_AqAlg():
......
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