diff options
author | Matti Picus <matti.picus@gmail.com> | 2017-08-23 21:28:09 +0300 |
---|---|---|
committer | Matti Picus <matti.picus@gmail.com> | 2017-08-23 21:28:09 +0300 |
commit | 00a3cc7d14ba3cbc23ecf3a6f5d6ed0e52519ef9 (patch) | |
tree | 941abd95e4b6d718622c23e6cd771b38629a80f9 /pypy | |
parent | (fijal, arigo) (diff) | |
download | pypy-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.py | 53 | ||||
-rw-r--r-- | pypy/module/cpyext/userslot.py | 8 |
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) |