[pypy-commit] pypy default: test, fix for missing userslot tp_iter, tp_iternext, this time via PyObject_Call
mattip
pypy.commits at gmail.com
Wed Aug 23 15:54:41 EDT 2017
Author: Matti Picus <matti.picus at gmail.com>
Branch:
Changeset: r92239:eb3baada82b7
Date: 2017-08-23 21:28 +0300
http://bitbucket.org/pypy/pypy/changeset/eb3baada82b7/
Log: test, fix for missing userslot tp_iter, tp_iternext, this time via
PyObject_Call
diff --git a/pypy/module/cpyext/test/test_eval.py b/pypy/module/cpyext/test/test_eval.py
--- a/pypy/module/cpyext/test/test_eval.py
+++ b/pypy/module/cpyext/test/test_eval.py
@@ -362,3 +362,56 @@
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
--- a/pypy/module/cpyext/userslot.py
+++ b/pypy/module/cpyext/userslot.py
@@ -122,3 +122,11 @@
else:
space.delete(w_self, w_obj)
return 0
+
+ at slot_function([PyObject], PyObject)
+def slot_tp_iter(space, w_self):
+ return space.iter(w_self)
+
+ at slot_function([PyObject], PyObject)
+def slot_tp_iternext(space, w_self):
+ return space.next(w_self)
More information about the pypy-commit
mailing list