Commit 7327657c authored by Jason Madden's avatar Jason Madden

Resolve the RuntimeWarning from Cython about PyFrameObject changing size.

By simply not typing it at the Cython level at all. No need since we're directing through functions now.
parent 47feb0b4
......@@ -65,15 +65,27 @@ static PyObject* PyFrame_GetCode(PyFrameObject* frame)
straightforward. Still, it is critical that the cython declaration of
this function use ``object`` as its return type.)
*/
static PyObject* Gevent_PyFrame_GetBack(PyFrameObject* frame)
static PyObject* Gevent_PyFrame_GetBack(PyObject* frame)
{
PyObject* back = (PyObject*)PyFrame_GetBack(frame);
PyObject* back = (PyObject*)PyFrame_GetBack((PyFrameObject*)frame);
if (back) {
return back;
}
Py_RETURN_NONE;
}
/* These are just for typing purposes to appease the compiler. */
static int Gevent_PyFrame_GetLineNumber(PyObject* o)
{
return PyFrame_GetLineNumber((PyFrameObject*)o);
}
static PyObject* Gevent_PyFrame_GetCode(PyObject* o)
{
return (PyObject*)PyFrame_GetCode((PyFrameObject*)o);
}
#ifdef __cplusplus
}
#ifdef __clang__
......
......@@ -53,17 +53,30 @@ cdef inline void greenlet_init():
_greenlet_imported = True
ctypedef object CodeType
ctypedef object FrameType
cdef extern from "_compat.h":
int PyFrame_GetLineNumber(FrameType frame)
CodeType PyFrame_GetCode(FrameType frame)
int Gevent_PyFrame_GetLineNumber(FrameType frame)
CodeType Gevent_PyFrame_GetCode(FrameType frame)
object Gevent_PyFrame_GetBack(FrameType frame)
ctypedef class types.FrameType [object PyFrameObject]:
pass
# We don't do this:
#
# ctypedef class types.FrameType [object PyFrameObject]:
# pass
#
# to avoid "RuntimeWarning: types.FrameType size changed, may
# indicate binary incompatibility. Expected 56 from C header, got
# 120 from PyObject" on Python 3.11. That makes the functions that
# really require that kind of object not safe and capable of crashing the
# interpreter.
#
# However, as of cython 3.0a11, that results in a failure to compile if
# we have a local variable typed as FrameType, so we can't do that.
#
# Also, it removes a layer of type checking and makes it possible to crash
# the interpreter if you call these functions with something that's not a PyFrameObject.
# Don't do that.
@cython.nonecheck(False)
cdef inline object get_f_back(FrameType frame):
return Gevent_PyFrame_GetBack(frame)
cdef void _init()
......@@ -89,7 +102,7 @@ cdef class _Frame:
@cython.final
@cython.locals(frame=FrameType,
@cython.locals(# frame=FrameType, # See above about why we cannot do this
newest_Frame=_Frame,
newer_Frame=_Frame,
older_Frame=_Frame)
......
......@@ -56,9 +56,9 @@ locals()['get_my_hub'] = lambda s: s.parent
locals()['get_generic_parent'] = lambda s: s.parent
# Frame access
locals()['PyFrame_GetCode'] = lambda frame: frame.f_code
locals()['PyFrame_GetLineNumber'] = lambda frame: frame.f_lineno
locals()['get_f_back'] = lambda frame: frame.f_back
locals()['Gevent_PyFrame_GetCode'] = lambda frame: frame.f_code
locals()['Gevent_PyFrame_GetLineNumber'] = lambda frame: frame.f_lineno
locals()['Gevent_PyFrame_GetBack'] = lambda frame: frame.f_back
if _PYPY:
......@@ -159,15 +159,15 @@ def _extract_stack(limit):
# Arguments are always passed to the constructor as Python objects,
# meaning we wind up boxing the f_lineno just to unbox it if we pass it.
# It's faster to simply assign once the object is created.
older_Frame.f_code = PyFrame_GetCode(frame) # pylint:disable=undefined-variable
older_Frame.f_lineno = PyFrame_GetLineNumber(frame) # pylint:disable=undefined-variable
older_Frame.f_code = Gevent_PyFrame_GetCode(frame) # pylint:disable=undefined-variable
older_Frame.f_lineno = Gevent_PyFrame_GetLineNumber(frame) # pylint:disable=undefined-variable
if newer_Frame is not None:
newer_Frame.f_back = older_Frame
newer_Frame = older_Frame
if newest_Frame is None:
newest_Frame = newer_Frame
frame = get_f_back(frame) # pylint:disable=undefined-variable
frame = Gevent_PyFrame_GetBack(frame) # pylint:disable=undefined-variable
return newest_Frame
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment