[pypy-commit] pypy py3.5: add PyStopIterationObject
arigo
pypy.commits at gmail.com
Thu Mar 9 11:25:38 EST 2017
Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r90610:f8357b98a4c2
Date: 2017-03-09 17:24 +0100
http://bitbucket.org/pypy/pypy/changeset/f8357b98a4c2/
Log: add PyStopIterationObject
diff --git a/pypy/module/cpyext/include/pyerrors.h b/pypy/module/cpyext/include/pyerrors.h
--- a/pypy/module/cpyext/include/pyerrors.h
+++ b/pypy/module/cpyext/include/pyerrors.h
@@ -36,6 +36,11 @@
PyAPI_FUNC(int) PyOS_snprintf(char *str, size_t size, const char *format, ...);
PyAPI_FUNC(int) PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va);
+typedef struct {
+ PyObject_HEAD /* xxx PyException_HEAD in CPython */
+ PyObject *value;
+} PyStopIterationObject;
+
#ifdef __cplusplus
}
#endif
diff --git a/pypy/module/cpyext/pyerrors.py b/pypy/module/cpyext/pyerrors.py
--- a/pypy/module/cpyext/pyerrors.py
+++ b/pypy/module/cpyext/pyerrors.py
@@ -4,13 +4,47 @@
from pypy.interpreter.error import OperationError, oefmt, strerror as _strerror
from pypy.interpreter import pytraceback
from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL, CONST_STRING
+from pypy.module.cpyext.api import PyObjectFields, cpython_struct
+from pypy.module.cpyext.api import bootstrap_function, slot_function
+from pypy.module.cpyext.pyobject import make_typedescr
from pypy.module.exceptions.interp_exceptions import W_RuntimeWarning
+from pypy.module.exceptions.interp_exceptions import W_StopIteration
from pypy.module.cpyext.pyobject import (
PyObject, PyObjectP, make_ref, from_ref, Py_DecRef)
from pypy.module.cpyext.state import State
from pypy.module.cpyext.import_ import PyImport_Import
from rpython.rlib import rposix, jit
+PyStopIterationObjectStruct = lltype.ForwardReference()
+PyStopIterationObject = lltype.Ptr(PyStopIterationObjectStruct)
+PyStopIterationObjectFields = PyObjectFields + \
+ (("value", PyObject), )
+cpython_struct("PyStopIterationObject", PyStopIterationObjectFields,
+ PyStopIterationObjectStruct)
+
+ at bootstrap_function
+def init_stopiterationobject(space):
+ "Type description of PyStopIterationObject"
+ make_typedescr(W_StopIteration.typedef,
+ basestruct=PyStopIterationObject.TO,
+ attach=stopiteration_attach,
+ dealloc=stopiteration_dealloc)
+
+def stopiteration_attach(space, py_obj, w_obj, w_userdata=None):
+ py_stopiteration = rffi.cast(PyStopIterationObject, py_obj)
+ assert isinstance(w_obj, W_StopIteration)
+ # note: assumes that w_value is read-only; changes on one side won't
+ # be reflected on the other side
+ py_stopiteration.c_value = make_ref(space, w_obj.w_value)
+
+ at slot_function([PyObject], lltype.Void)
+def stopiteration_dealloc(space, py_obj):
+ py_stopiteration = rffi.cast(PyStopIterationObject, py_obj)
+ Py_DecRef(space, py_stopiteration.c_value)
+ from pypy.module.cpyext.object import _dealloc
+ _dealloc(space, py_obj)
+
+
@cpython_api([PyObject, PyObject], lltype.Void)
def PyErr_SetObject(space, w_type, w_value):
"""This function is similar to PyErr_SetString() but lets you specify an
diff --git a/pypy/module/cpyext/test/test_pyerrors.py b/pypy/module/cpyext/test/test_pyerrors.py
--- a/pypy/module/cpyext/test/test_pyerrors.py
+++ b/pypy/module/cpyext/test/test_pyerrors.py
@@ -443,3 +443,15 @@
module.test()
assert len(l) == 1
assert "foo 42 bar" in str(l[0])
+
+ def test_StopIteration_value(self):
+ module = self.import_extension('foo', [
+ ("test", "METH_O",
+ '''
+ PyObject *o = ((PyStopIterationObject *)args)->value;
+ Py_INCREF(o);
+ return o;
+ '''),
+ ])
+ res = module.test(StopIteration("foo!"))
+ assert res == "foo!"
More information about the pypy-commit
mailing list