Commit 2d502121 authored by Andreas Zeidler's avatar Andreas Zeidler

backport r94905 to 2.11: Acquisition wrappers now correctly proxy `__iter__`.

parent edf38b23
...@@ -19,6 +19,8 @@ Zope Changes ...@@ -19,6 +19,8 @@ Zope Changes
Bugs Fixed Bugs Fixed
- Acquisition wrappers now correctly proxy __iter__.
- Products.PluginIndexes.PathIndex: backported doc fixes / - Products.PluginIndexes.PathIndex: backported doc fixes /
optiimizations from trunk (and ExtendedPathIndex). optiimizations from trunk (and ExtendedPathIndex).
......
...@@ -38,7 +38,8 @@ static PyObject *py__add__, *py__sub__, *py__mul__, *py__div__, ...@@ -38,7 +38,8 @@ static PyObject *py__add__, *py__sub__, *py__mul__, *py__div__,
*py__long__, *py__float__, *py__oct__, *py__hex__, *py__long__, *py__float__, *py__oct__, *py__hex__,
*py__getitem__, *py__setitem__, *py__delitem__, *py__getitem__, *py__setitem__, *py__delitem__,
*py__getslice__, *py__setslice__, *py__delslice__, *py__contains__, *py__getslice__, *py__setslice__, *py__delslice__, *py__contains__,
*py__len__, *py__of__, *py__call__, *py__repr__, *py__str__, *py__cmp__; *py__len__, *py__of__, *py__call__, *py__repr__, *py__str__, *py__cmp__,
*py__iter__;
static PyObject *Acquired=0; static PyObject *Acquired=0;
...@@ -82,6 +83,7 @@ init_py_names(void) ...@@ -82,6 +83,7 @@ init_py_names(void)
INIT_PY_NAME(__repr__); INIT_PY_NAME(__repr__);
INIT_PY_NAME(__str__); INIT_PY_NAME(__str__);
INIT_PY_NAME(__cmp__); INIT_PY_NAME(__cmp__);
INIT_PY_NAME(__iter__);
#undef INIT_PY_NAME #undef INIT_PY_NAME
} }
...@@ -817,6 +819,12 @@ Wrapper_contains(Wrapper *self, PyObject *v) ...@@ -817,6 +819,12 @@ Wrapper_contains(Wrapper *self, PyObject *v)
return c; return c;
} }
static PyObject *
Wrapper_iter(Wrapper *self)
{
return CallMethodO(OBJECT(self), py__iter__, NULL, NULL);
}
static PySequenceMethods Wrapper_as_sequence = { static PySequenceMethods Wrapper_as_sequence = {
(inquiry)Wrapper_length, /*sq_length*/ (inquiry)Wrapper_length, /*sq_length*/
(binaryfunc)Wrapper_add, /*sq_concat*/ (binaryfunc)Wrapper_add, /*sq_concat*/
...@@ -1222,7 +1230,7 @@ static PyExtensionClass Wrappertype = { ...@@ -1222,7 +1230,7 @@ static PyExtensionClass Wrappertype = {
/* tp_clear */ (inquiry)Wrapper_clear, /* tp_clear */ (inquiry)Wrapper_clear,
/* tp_richcompare */ (richcmpfunc)0, /* tp_richcompare */ (richcmpfunc)0,
/* tp_weaklistoffset */ (long)0, /* tp_weaklistoffset */ (long)0,
/* tp_iter */ (getiterfunc)0, (getiterfunc)Wrapper_iter, /*tp_iter*/
/* tp_iternext */ (iternextfunc)0, /* tp_iternext */ (iternextfunc)0,
/* tp_methods */ Wrapper_methods, /* tp_methods */ Wrapper_methods,
/* tp_members */ 0, /* tp_members */ 0,
...@@ -1266,7 +1274,7 @@ static PyExtensionClass XaqWrappertype = { ...@@ -1266,7 +1274,7 @@ static PyExtensionClass XaqWrappertype = {
/* tp_clear */ (inquiry)Wrapper_clear, /* tp_clear */ (inquiry)Wrapper_clear,
/* tp_richcompare */ (richcmpfunc)0, /* tp_richcompare */ (richcmpfunc)0,
/* tp_weaklistoffset */ (long)0, /* tp_weaklistoffset */ (long)0,
/* tp_iter */ (getiterfunc)0, (getiterfunc)Wrapper_iter, /*tp_iter*/
/* tp_iternext */ (iternextfunc)0, /* tp_iternext */ (iternextfunc)0,
/* tp_methods */ Wrapper_methods, /* tp_methods */ Wrapper_methods,
/* tp_members */ 0, /* tp_members */ 0,
......
...@@ -1636,6 +1636,9 @@ def test_proxying(): ...@@ -1636,6 +1636,9 @@ def test_proxying():
... def __contains__(self, key): ... def __contains__(self, key):
... print 'contains', repr(key) ... print 'contains', repr(key)
... return key == 5 ... return key == 5
... def __iter__(self):
... print 'iterating...'
... return iter((42,))
The naked class behaves like this: The naked class behaves like this:
...@@ -1646,6 +1649,9 @@ def test_proxying(): ...@@ -1646,6 +1649,9 @@ def test_proxying():
>>> 5 in c >>> 5 in c
contains 5 contains 5
True True
>>> list(c)
iterating...
[42]
Let's put c in the context of i: Let's put c in the context of i:
...@@ -1660,6 +1666,58 @@ def test_proxying(): ...@@ -1660,6 +1666,58 @@ def test_proxying():
>>> 5 in i.c >>> 5 in i.c
contains 5 contains 5
True True
>>> list(i.c)
iterating...
[42]
Let's let's test the same again with an explicit wrapper:
>>> import Acquisition
>>> class Impl(Acquisition.Explicit):
... pass
>>> class C(Acquisition.Explicit):
... def __getitem__(self, key):
... print 'getitem', key
... if key == 4:
... raise IndexError
... return key
... def __contains__(self, key):
... print 'contains', repr(key)
... return key == 5
... def __iter__(self):
... print 'iterating...'
... return iter((42,))
The naked class behaves like this:
>>> c = C()
>>> 3 in c
contains 3
False
>>> 5 in c
contains 5
True
>>> list(c)
iterating...
[42]
Let's put c in the context of i:
>>> i = Impl()
>>> i.c = c
Now check that __contains__ is properly used:
>>> 3 in i.c # c.__of__(i)
contains 3
False
>>> 5 in i.c
contains 5
True
>>> list(i.c)
iterating...
[42]
""" """
......
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