aboutsummaryrefslogtreecommitdiff
path: root/pypy
diff options
context:
space:
mode:
authorMatti Picus <matti.picus@gmail.com>2017-08-23 21:28:09 +0300
committerMatti Picus <matti.picus@gmail.com>2017-08-23 21:28:09 +0300
commit00a3cc7d14ba3cbc23ecf3a6f5d6ed0e52519ef9 (patch)
tree941abd95e4b6d718622c23e6cd771b38629a80f9 /pypy
parent(fijal, arigo) (diff)
downloadpypy-00a3cc7d14ba3cbc23ecf3a6f5d6ed0e52519ef9.tar.gz
pypy-00a3cc7d14ba3cbc23ecf3a6f5d6ed0e52519ef9.tar.bz2
pypy-00a3cc7d14ba3cbc23ecf3a6f5d6ed0e52519ef9.zip
test, fix for missing userslot tp_iter, tp_iternext, this time via PyObject_Call
Diffstat (limited to 'pypy')
-rw-r--r--pypy/module/cpyext/test/test_eval.py53
-rw-r--r--pypy/module/cpyext/userslot.py8
2 files changed, 61 insertions, 0 deletions
diff --git a/pypy/module/cpyext/test/test_eval.py b/pypy/module/cpyext/test/test_eval.py
index 66716aec5b..8a31ed96bd 100644
--- a/pypy/module/cpyext/test/test_eval.py
+++ b/pypy/module/cpyext/test/test_eval.py
@@ -362,3 +362,56 @@ class AppTestCall(AppTestCpythonExtensionBase):
assert 'while calling recurse' in str(e)
else:
assert False, "expected RuntimeError"
+
+ def test_build_class(self):
+ # make sure PyObject_Call generates a proper PyTypeObject,
+ # along the way verify that userslot has iter and next
+ module = self.import_extension('foo', [
+ ("object_call", "METH_O",
+ '''
+ return PyObject_Call((PyObject*)&PyType_Type, args, NULL);
+ '''),
+ ('iter', "METH_O",
+ '''
+ if (NULL == args->ob_type->tp_iter)
+ {
+ PyErr_SetString(PyExc_TypeError, "NULL tp_iter");
+ return NULL;
+ }
+ return args->ob_type->tp_iter(args);
+ '''),
+ ('next', "METH_O",
+ '''
+ if (NULL == args->ob_type->tp_iternext)
+ {
+ PyErr_SetString(PyExc_TypeError, "NULL tp_iternext");
+ return NULL;
+ }
+ return args->ob_type->tp_iternext(args);
+ '''),])
+ def __init__(self, N):
+ self.N = N
+ self.i = 0
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ if self.i < self.N:
+ i = self.i
+ self.i += 1
+ return i
+ raise StopIteration
+
+ d = {'__init__': __init__, '__iter__': __iter__, 'next': __next__,
+ '__next__': next}
+ C = module.object_call(('Iterable', (object,), d))
+ c = C(5)
+ i = module.iter(c)
+ out = []
+ try:
+ while 1:
+ out.append(module.next(i))
+ except StopIteration:
+ pass
+ assert out == [0, 1, 2, 3, 4]
diff --git a/pypy/module/cpyext/userslot.py b/pypy/module/cpyext/userslot.py
index 45f37161a6..96946a3c33 100644
--- a/pypy/module/cpyext/userslot.py
+++ b/pypy/module/cpyext/userslot.py
@@ -122,3 +122,11 @@ def slot_tp_descr_set(space, w_self, w_obj, w_value):
else:
space.delete(w_self, w_obj)
return 0
+
+@slot_function([PyObject], PyObject)
+def slot_tp_iter(space, w_self):
+ return space.iter(w_self)
+
+@slot_function([PyObject], PyObject)
+def slot_tp_iternext(space, w_self):
+ return space.next(w_self)