fix glitch in dict.keys/values/items() optimisation for subtype calls under Python...
authorStefan Behnel <stefan_ml@behnel.de>
Sat, 6 Jul 2013 11:11:17 +0000 (13:11 +0200)
committerStefan Behnel <stefan_ml@behnel.de>
Sat, 6 Jul 2013 11:11:17 +0000 (13:11 +0200)
Cython/Utility/Builtins.c
tests/run/builtin_subtype_methods_cy3.pyx [new file with mode: 0644]

index 75432a6..c02a61b 100644 (file)
@@ -273,10 +273,11 @@ static CYTHON_INLINE PyObject* __Pyx_PyDict_Keys(PyObject* d); /*proto*/
 #endif
 
 //////////////////// py_dict_keys ////////////////////
+//@requires: ObjectHandling.c::PyObjectCallMethod
 
 #if PY_MAJOR_VERSION >= 3
 static CYTHON_INLINE PyObject* __Pyx_PyDict_Keys(PyObject* d) {
-    return PyObject_CallMethodObjArgs(d, PYIDENT("keys"), NULL);
+    return __Pyx_PyObject_CallMethod1((PyObject*)&PyDict_Type, PYIDENT("keys"), d);
 }
 #endif
 
@@ -289,10 +290,11 @@ static CYTHON_INLINE PyObject* __Pyx_PyDict_Values(PyObject* d); /*proto*/
 #endif
 
 //////////////////// py_dict_values ////////////////////
+//@requires: ObjectHandling.c::PyObjectCallMethod
 
 #if PY_MAJOR_VERSION >= 3
 static CYTHON_INLINE PyObject* __Pyx_PyDict_Values(PyObject* d) {
-    return PyObject_CallMethodObjArgs(d, PYIDENT("values"), NULL);
+    return __Pyx_PyObject_CallMethod1((PyObject*)&PyDict_Type, PYIDENT("values"), d);
 }
 #endif
 
@@ -305,10 +307,11 @@ static CYTHON_INLINE PyObject* __Pyx_PyDict_Items(PyObject* d); /*proto*/
 #endif
 
 //////////////////// py_dict_items ////////////////////
+//@requires: ObjectHandling.c::PyObjectCallMethod
 
 #if PY_MAJOR_VERSION >= 3
 static CYTHON_INLINE PyObject* __Pyx_PyDict_Items(PyObject* d) {
-    return PyObject_CallMethodObjArgs(d, PYIDENT("items"), NULL);
+    return __Pyx_PyObject_CallMethod1((PyObject*)&PyDict_Type, PYIDENT("items"), d);
 }
 #endif
 
diff --git a/tests/run/builtin_subtype_methods_cy3.pyx b/tests/run/builtin_subtype_methods_cy3.pyx
new file mode 100644 (file)
index 0000000..1cff75f
--- /dev/null
@@ -0,0 +1,52 @@
+# cython: language_level=3
+# mode: run
+# ticket: 653
+
+
+class DictPySubtype(dict):
+    def keys(self):
+        """
+        >>> d = DictPySubtype(one=42, two=17, three=0)
+        >>> for v in sorted(d.keys()):
+        ...     print(v)
+        three
+        two
+        """
+        for key in dict.keys(self):
+            if key != 'one':
+                yield key
+
+    def values(self):
+        """
+        >>> d = DictPySubtype(one=42, two=17, three=0)
+        >>> for v in sorted(d.values()):
+        ...     print(v)
+        17
+        42
+        """
+        for value in dict.values(self):
+            if value:
+                yield value
+
+    def items(self):
+        """
+        >>> d = DictPySubtype(one=42, two=17, three=0)
+        >>> for v in sorted(d.items()):
+        ...     print(v)
+        one
+        two
+        """
+        for key, value in dict.items(self):
+            if value:
+                yield key
+
+
+class ListPySubtype(list):
+    """
+    >>> lst = ListPySubtype([1,2,3])
+    >>> lst.append(4)
+    >>> lst
+    [1, 2, 3, 5]
+    """
+    def append(self, value):
+        list.append(self, value+1)