[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