[Zope-Checkins] SVN: Zope/trunk/ Acquisition wrappers now correctly proxy `__iter__`.

Andreas Zeidler az at zitc.de
Wed Jan 21 11:04:11 EST 2009


Log message for revision 94905:
  Acquisition wrappers now correctly proxy `__iter__`.
  

Changed:
  U   Zope/trunk/doc/CHANGES.txt
  U   Zope/trunk/lib/python/Acquisition/_Acquisition.c
  U   Zope/trunk/lib/python/Acquisition/tests.py

-=-
Modified: Zope/trunk/doc/CHANGES.txt
===================================================================
--- Zope/trunk/doc/CHANGES.txt	2009-01-21 14:44:37 UTC (rev 94904)
+++ Zope/trunk/doc/CHANGES.txt	2009-01-21 16:04:11 UTC (rev 94905)
@@ -237,6 +237,8 @@
 
     Bugs Fixed
 
+      - Acquisition wrappers now correctly proxy __iter__.
+
       - Launchpad #174705:  ensure that the error info object exposed to a
         'tal:on_error' handler has attributes visible to restricted code.
 

Modified: Zope/trunk/lib/python/Acquisition/_Acquisition.c
===================================================================
--- Zope/trunk/lib/python/Acquisition/_Acquisition.c	2009-01-21 14:44:37 UTC (rev 94904)
+++ Zope/trunk/lib/python/Acquisition/_Acquisition.c	2009-01-21 16:04:11 UTC (rev 94905)
@@ -39,7 +39,7 @@
   *py__getitem__, *py__setitem__, *py__delitem__,
   *py__getslice__, *py__setslice__, *py__delslice__,  *py__contains__,
   *py__len__, *py__of__, *py__call__, *py__repr__, *py__str__, *py__cmp__,
-  *py__parent__;
+  *py__parent__, *py__iter__;
 
 static PyObject *Acquired=0;
 
@@ -84,6 +84,7 @@
   INIT_PY_NAME(__str__);
   INIT_PY_NAME(__cmp__);
   INIT_PY_NAME(__parent__);
+  INIT_PY_NAME(__iter__);
 #undef INIT_PY_NAME
 }
 
@@ -928,6 +929,12 @@
   return c;
 }
 
+static PyObject * 
+Wrapper_iter(Wrapper *self)
+{
+  return CallMethodO(OBJECT(self), py__iter__, NULL, NULL); 
+}
+
 static PySequenceMethods Wrapper_as_sequence = {
 	(inquiry)Wrapper_length,		/*sq_length*/
 	(binaryfunc)Wrapper_add,		/*sq_concat*/
@@ -1294,7 +1301,7 @@
   /* tp_clear          */ (inquiry)Wrapper_clear,
   /* tp_richcompare    */ (richcmpfunc)Wrapper_richcompare,
   /* tp_weaklistoffset */ (long)0,
-  /* tp_iter           */ (getiterfunc)0,
+  (getiterfunc)Wrapper_iter,		/*tp_iter*/
   /* tp_iternext       */ (iternextfunc)0,
   /* tp_methods        */ Wrapper_methods,
   /* tp_members        */ 0,
@@ -1338,7 +1345,7 @@
   /* tp_clear          */ (inquiry)Wrapper_clear,
   /* tp_richcompare    */ (richcmpfunc)Wrapper_richcompare,
   /* tp_weaklistoffset */ (long)0,
-  /* tp_iter           */ (getiterfunc)0,
+  (getiterfunc)Wrapper_iter,		/*tp_iter*/
   /* tp_iternext       */ (iternextfunc)0,
   /* tp_methods        */ Wrapper_methods,
   /* tp_members        */ 0,

Modified: Zope/trunk/lib/python/Acquisition/tests.py
===================================================================
--- Zope/trunk/lib/python/Acquisition/tests.py	2009-01-21 14:44:37 UTC (rev 94904)
+++ Zope/trunk/lib/python/Acquisition/tests.py	2009-01-21 16:04:11 UTC (rev 94905)
@@ -1699,6 +1699,9 @@
     ...     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:
 
@@ -1709,6 +1712,9 @@
     >>> 5 in c
     contains 5
     True
+    >>> list(c)
+    iterating...
+    [42]
 
     Let's put c in the context of i:
 
@@ -1723,7 +1729,59 @@
     >>> 5 in i.c
     contains 5
     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]
+
     """
 
 



More information about the Zope-Checkins mailing list