[pypy-commit] pypy cpyext-ext: Found out that we have space.issequence_w(): move the logic from the

arigo pypy.commits at gmail.com
Mon Apr 18 10:41:02 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: cpyext-ext
Changeset: r83744:3decb320c37e
Date: 2016-04-18 16:40 +0200
http://bitbucket.org/pypy/pypy/changeset/3decb320c37e/

Log:	Found out that we have space.issequence_w(): move the logic from the
	operator module to there. Add space.ismapping_w() and call it from
	PyMapping_Check(). Add tests in cpyext.

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1173,7 +1173,27 @@
         return self.w_False
 
     def issequence_w(self, w_obj):
-        return (self.findattr(w_obj, self.wrap("__getitem__")) is not None)
+        if self.is_oldstyle_instance(w_obj):
+            return (self.findattr(w_obj, self.wrap('__getitem__')) is not None)
+        flag = self.type(w_obj).flag_map_or_seq
+        if flag == 'M':
+            return False
+        elif flag == 'S':
+            return True
+        else:
+            return (self.lookup(w_obj, '__getitem__') is not None)
+
+    def ismapping_w(self, w_obj):
+        if self.is_oldstyle_instance(w_obj):
+            return (self.findattr(w_obj, self.wrap('__getitem__')) is not None)
+        flag = self.type(w_obj).flag_map_or_seq
+        if flag == 'M':
+            return True
+        elif flag == 'S':
+            return False
+        else:
+            return (self.lookup(w_obj, '__getitem__') is not None and
+                    self.lookup(w_obj, '__getslice__') is None)
 
     # The code below only works
     # for the simple case (new-style instance).
diff --git a/pypy/module/cpyext/mapping.py b/pypy/module/cpyext/mapping.py
--- a/pypy/module/cpyext/mapping.py
+++ b/pypy/module/cpyext/mapping.py
@@ -8,7 +8,7 @@
 def PyMapping_Check(space, w_obj):
     """Return 1 if the object provides mapping protocol, and 0 otherwise.  This
     function always succeeds."""
-    return int(space.findattr(w_obj, space.wrap("items")) is not None)
+    return int(space.ismapping_w(w_obj))
 
 @cpython_api([PyObject], Py_ssize_t, error=-1)
 def PyMapping_Size(space, w_obj):
diff --git a/pypy/module/cpyext/test/test_iterator.py b/pypy/module/cpyext/test/test_iterator.py
--- a/pypy/module/cpyext/test/test_iterator.py
+++ b/pypy/module/cpyext/test/test_iterator.py
@@ -37,7 +37,14 @@
                 obj = PyObject_New(PyObject, &Foo_Type);
                 return obj;
             '''
-            )],
+            ),
+           ("check", "METH_O",
+            '''
+                return PyInt_FromLong(
+                    PySequence_Check(args) +
+                    PyMapping_Check(args) * 2);
+            ''')
+            ],
             '''
             static PyObject *
             mp_subscript(PyObject *self, PyObject *key)
@@ -65,6 +72,8 @@
         import operator
         assert not operator.isSequenceType(obj)
         assert operator.isMappingType(obj)
+        #
+        assert module.check(obj) == 2
 
     def test_iterable_nonmapping_object(self):
         module = self.import_extension('foo', [
@@ -78,8 +87,14 @@
                 if (PyType_Ready(&Foo_Type) < 0) return NULL;
                 obj = PyObject_New(PyObject, &Foo_Type);
                 return obj;
+            '''),
+           ("check", "METH_O",
             '''
-            )],
+                return PyInt_FromLong(
+                    PySequence_Check(args) +
+                    PyMapping_Check(args) * 2);
+            ''')
+            ],
             '''
             static PyObject *
             sq_item(PyObject *self, Py_ssize_t size)
@@ -108,3 +123,5 @@
         import operator
         assert operator.isSequenceType(obj)
         assert not operator.isMappingType(obj)
+        #
+        assert module.check(obj) == 1
diff --git a/pypy/module/cpyext/test/test_sequence.py b/pypy/module/cpyext/test/test_sequence.py
--- a/pypy/module/cpyext/test/test_sequence.py
+++ b/pypy/module/cpyext/test/test_sequence.py
@@ -6,6 +6,10 @@
 import py.test
 
 class TestSequence(BaseApiTest):
+    def test_check(self, space, api):
+        assert api.PySequence_Check(space.newlist([]))
+        assert not api.PySequence_Check(space.newdict())
+
     def test_sequence(self, space, api):
         w_l = space.wrap([1, 2, 3, 4])
         assert api.PySequence_Fast(w_l, "message") is w_l
diff --git a/pypy/module/operator/interp_operator.py b/pypy/module/operator/interp_operator.py
--- a/pypy/module/operator/interp_operator.py
+++ b/pypy/module/operator/interp_operator.py
@@ -252,29 +252,8 @@
 
 def isMappingType(space, w_obj):
     'isMappingType(a) -- Return True if a has a mapping type, False otherwise.'
-    if space.is_oldstyle_instance(w_obj):
-        result = (space.findattr(w_obj, space.wrap('__getitem__')) is not None)
-    else:
-        flag = space.type(w_obj).flag_map_or_seq
-        if flag == 'M':
-            result = True
-        elif flag == 'S':
-            result = False
-        else:
-            result = (space.lookup(w_obj, '__getitem__') is not None and
-                      space.lookup(w_obj, '__getslice__') is None)
-    return space.wrap(result)
+    return space.wrap(space.ismapping_w(w_obj))
 
 def isSequenceType(space, w_obj):
     'isSequenceType(a) -- Return True if a has a sequence type, False otherwise.'
-    if space.is_oldstyle_instance(w_obj):
-        result = (space.findattr(w_obj, space.wrap('__getitem__')) is not None)
-    else:
-        flag = space.type(w_obj).flag_map_or_seq
-        if flag == 'M':
-            result = False
-        elif flag == 'S':
-            result = True
-        else:
-            result = (space.lookup(w_obj, '__getitem__') is not None)
-    return space.wrap(result)
+    return space.wrap(space.issequence_w(w_obj))


More information about the pypy-commit mailing list