Log message for revision 78318: Merged from old philikon-aq-and-__parent__ branch: Log message for revision 71227: Step 4: Make aq_get aware of __parent__ pointers. (Also some comment cosmetics in _Acquisition.c) Log message for revision 71228: Test aq_parent property as well (in addition to aq_parent function) Log message for revision 71229: Step 5: Make aq_chain aware of __parent__ pointers.
Changed: U Zope/branches/philikon-aq/lib/python/Acquisition/_Acquisition.c U Zope/branches/philikon-aq/lib/python/Acquisition/tests.py -=- Modified: Zope/branches/philikon-aq/lib/python/Acquisition/_Acquisition.c =================================================================== --- Zope/branches/philikon-aq/lib/python/Acquisition/_Acquisition.c 2007-07-24 20:46:33 UTC (rev 78317) +++ Zope/branches/philikon-aq/lib/python/Acquisition/_Acquisition.c 2007-07-24 21:02:03 UTC (rev 78318) @@ -1422,8 +1422,7 @@ WRAPPER(self)->ob_type==(PyTypeObject*)&Wrappertype, explicit, containment); /* Not wrapped; check if we have a __parent__ pointer. If that's - the case, we create a wrapper and pretend it's business as - usual */ + the case, create a wrapper and pretend it's business as usual. */ else if ((result = PyObject_GetAttr(self, py__parent__))) { self = newWrapper(self, result, (PyTypeObject*)&Wrappertype); @@ -1437,8 +1436,8 @@ /* No wrapper and no __parent__, so just getattr. */ else { - /* We need to clean up the AttributeError from the previous - getattr (because it has clearly failed). */ + /* Clean up the AttributeError from the previous getattr + (because it has clearly failed). */ PyErr_Fetch(&result,&v,&tb); if (result && (result != PyExc_AttributeError)) { @@ -1486,13 +1485,35 @@ static PyObject * capi_aq_get(PyObject *self, PyObject *name, PyObject *defalt, int containment) { - PyObject *result = NULL; + PyObject *result = NULL, *v, *tb; /* We got a wrapped object, so business as usual */ if (isWrapper(self)) result=Wrapper_findattr(WRAPPER(self), name, 0, 0, OBJECT(self), 1, 1, 1, - containment); + containment); + /* Not wrapped; check if we have a __parent__ pointer. If that's + the case, create a wrapper and pretend it's business as usual. */ + else if ((result = PyObject_GetAttr(self, py__parent__))) + { + self=newWrapper(self, result, (PyTypeObject*)&Wrappertype); + Py_DECREF(result); /* don't need __parent__ anymore */ + result=Wrapper_findattr(WRAPPER(self), name, 0, 0, OBJECT(self), + 1, 1, 1, containment); + Py_DECREF(self); /* Get rid of temporary wrapper. */ + } else - result=PyObject_GetAttr(self, name); + { + /* Clean up the AttributeError from the previous getattr + (because it has clearly failed). */ + PyErr_Fetch(&result,&v,&tb); + if (result && (result != PyExc_AttributeError)) + { + PyErr_Restore(result,v,tb); + return NULL; + } + Py_XDECREF(result); Py_XDECREF(v); Py_XDECREF(tb); + + result=PyObject_GetAttr(self, name); + } if (! result && defalt) { @@ -1658,7 +1679,7 @@ static PyObject * capi_aq_chain(PyObject *self, int containment) { - PyObject *result; + PyObject *result, *v, *tb; UNLESS (result=PyList_New(0)) return NULL; @@ -1681,9 +1702,28 @@ } } else - if (PyList_Append(result, self) < 0) - goto err; + { + if (PyList_Append(result, self) < 0) + goto err; + if ((self=PyObject_GetAttr(self, py__parent__))) + { + Py_DECREF(self); /* We don't need our own reference. */ + if (self!=Py_None) + continue; + } + else + { + PyErr_Fetch(&self,&v,&tb); + if (self && (self != PyExc_AttributeError)) + { + PyErr_Restore(self,v,tb); + return NULL; + } + Py_XDECREF(self); Py_XDECREF(v); Py_XDECREF(tb); + } + } + break; } Modified: Zope/branches/philikon-aq/lib/python/Acquisition/tests.py =================================================================== --- Zope/branches/philikon-aq/lib/python/Acquisition/tests.py 2007-07-24 20:46:33 UTC (rev 78317) +++ Zope/branches/philikon-aq/lib/python/Acquisition/tests.py 2007-07-24 21:02:03 UTC (rev 78318) @@ -1725,14 +1725,26 @@ >>> Acquisition.aq_acquire(x, 'bar') 3.145 - as does ``aq_parent``: + as does ``aq_get``: + >>> Acquisition.aq_get(x, 'hello') + 'world' + >>> Acquisition.aq_get(x, 'foo') + 42 + >>> Acquisition.aq_get(x, 'bar') + 3.145 + + and ``aq_parent``: + >>> Acquisition.aq_parent(x) is y True >>> Acquisition.aq_parent(y) is z True - TODO aq_chain + as well as ``aq_chain``: + + >>> Acquisition.aq_chain(x) == [x, y, z] + True """ def test_implicit_wrapper_as___parent__(): @@ -1769,13 +1781,27 @@ >>> Acquisition.aq_acquire(x, 'bar') 3.145 - as does ``aq_parent``: + as does ``aq_get``: + >>> Acquisition.aq_get(x, 'hello') + 'world' + >>> Acquisition.aq_get(x, 'foo') + 42 + >>> Acquisition.aq_get(x, 'bar') + 3.145 + + and ``aq_parent``: + >>> Acquisition.aq_parent(x) is y True >>> Acquisition.aq_parent(y) is z True + as well as ``aq_chain``: + + >>> Acquisition.aq_chain(x) == [x, y, z] + True + Note that also the (implicit) acquisition wrapper has a __parent__ pointer, which is automatically computed from the acquisition container (it's identical to aq_parent): @@ -1800,8 +1826,6 @@ Traceback (most recent call last): ... AttributeError: __parent__ - - TODO aq_chain """ def test_explicit_wrapper_as___parent__(): @@ -1836,13 +1860,27 @@ >>> Acquisition.aq_acquire(x, 'bar') 3.145 - as does ``aq_parent``: + as does ``aq_get``: + >>> Acquisition.aq_get(x, 'hello') + 'world' + >>> Acquisition.aq_get(x, 'foo') + 42 + >>> Acquisition.aq_get(x, 'bar') + 3.145 + + and ``aq_parent``: + >>> Acquisition.aq_parent(x) is y True >>> Acquisition.aq_parent(y) is z True + as well as ``aq_chain``: + + >>> Acquisition.aq_chain(x) == [x, y, z] + True + Note that also the (explicit) acquisition wrapper has a __parent__ pointer, which is automatically computed from the acquisition container (it's identical to aq_parent): @@ -1867,8 +1905,6 @@ Traceback (most recent call last): ... AttributeError: __parent__ - - TODO aq_chain """ def test_implicit_wrapper_has_nonwrapper_as_aq_parent(): @@ -1888,7 +1924,7 @@ ... hello = 'world' >>> x = Impl().__of__(y) - Again, acquiring objects work as usual: + Again, acquiring objects works as usual: >>> Acquisition.aq_acquire(x, 'hello') 'world' @@ -1897,13 +1933,33 @@ >>> Acquisition.aq_acquire(x, 'bar') 3.145 - as does ``aq_parent``: + as does ``aq_get``: + >>> Acquisition.aq_get(x, 'hello') + 'world' + >>> Acquisition.aq_get(x, 'foo') + 42 + >>> Acquisition.aq_get(x, 'bar') + 3.145 + + and ``aq_parent``: + >>> Acquisition.aq_parent(x) == y True + >>> x.aq_parent == y + True + >>> x.aq_parent.aq_parent == z + True >>> Acquisition.aq_parent(y) is z True + as well as ``aq_chain``: + + >>> Acquisition.aq_chain(x) == [x, y, z] + True + >>> x.aq_chain == [x, y, z] + True + Because the outmost object, ``x``, is wrapped in an implicit acquisition wrapper, we can also use direct attribute access: @@ -1913,8 +1969,6 @@ 42 >>> x.bar 3.145 - - TODO aq_parent, aq_chain """ def test_explicit_wrapper_has_nonwrapper_as_aq_parent(): @@ -1943,7 +1997,32 @@ >>> Acquisition.aq_acquire(x, 'bar') 3.145 - TODO aq_chain + as does ``aq_get``: + + >>> Acquisition.aq_get(x, 'hello') + 'world' + >>> Acquisition.aq_get(x, 'foo') + 42 + >>> Acquisition.aq_get(x, 'bar') + 3.145 + + and ``aq_parent``: + + >>> Acquisition.aq_parent(x) == y + True + >>> x.aq_parent == y + True + >>> x.aq_parent.aq_parent == z + True + >>> Acquisition.aq_parent(y) is z + True + + as well as ``aq_chain``: + + >>> Acquisition.aq_chain(x) == [x, y, z] + True + >>> x.aq_chain == [x, y, z] + True """ def test___parent__aq_parent_circles(): _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins