8000 bpo-44800: unobtrusively rename _PyInterpreterFrame to _Py_frame by ncoghlan · Pull Request #32024 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-44800: unobtrusively rename _PyInterpreterFrame to _Py_frame #32024

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Prev Previous commit
Next Next commit
Compatibility workaround to match 3.11a6 API
  • Loading branch information
ncoghlan committed Mar 21, 2022
commit 32c224fc50d0d52a14b2134cbf6ad032b8f1e925
30 changes: 30 additions & 0 deletions Include/internal/pycore_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,36 @@ typedef struct _Py_frame {
PyObject *localsplus[1];
} _Py_frame;

#if !defined(_PY_FRAME_API_DISABLE_INTERIM_COMPAT_3_11a6)
/* Interim compatibility for the internal frame API as shipped in 3.11a6
* Some projects (Cython, gevent, greenlet) are known to access the private
* frame API in CPython. This API has already changed twice for 3.11 (first
* with the structural split, then with the full object structure becoming
* opaque and internal struct gaining the `_Py` prefix). The recommended
* resolution is expected to change again once a proper public API for the
* required frame operations is defined (as discussed in
* https://github.com/faster-cpython/ideas/issues/309).
*
* This interim compatibility workaround enables the bpo-44800 struct and field
* name changes for CPython maintainability without forcing yet another interim
* code update on the affected projects. Since the workaround affects symbols
* without the `Py` or `_Py` prefix, a preprocessor symbol can be declared to
* disable the workaround: _PY_FRAME_API_DISABLE_INTERIM_COMPAT_3_11a6
*/
// Renamed frame data struct and fields
typedef _Py_frame _PyInterpreterFrame;
#define f_func func
#define f_globals globals
#define f_builtins builtins
#define f_locals locals
#define f_code code
#define f_lasti lasti
#define f_state state
// Renamed frame object fields
#define f_frame f_fdata
#define _f_frame_data _f_owned_fdata
#endif // End internal frame API compatibilty workaround

static inline int _PyFrame_IsRunnable(_Py_frame *f) {
return f->f_state < FRAME_EXECUTING;
}
Expand Down
17 changes: 17 additions & 0 deletions Objects/frameobject.c
7CD4
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,23 @@ static PyMemberDef frame_memberlist[] = {
{NULL} /* Sentinel */
};

// Compile time check of interim Python 3.11a6 API compatibility aliases
// Can be removed once the aliases are removed
static_assert(OFF(f_fdata) == OFF(f_frame), "Incorrect alias for f_frame");
static_assert(OFF(_f_owned_fdata) == OFF(_f_frame_data), "Incorrect alias for _f_frame_data");

#define INTERIM_FRAME_DATA_ALIAS_CHECK(new_field) \
static_assert(offsetof(_Py_frame, new_field) == offsetof(_PyInterpreterFrame, f_##new_field), \
"Incorrect alias for f_" #new_field )

INTERIM_FRAME_DATA_ALIAS_CHECK(func);
INTERIM_FRAME_DATA_ALIAS_CHECK(builtins);
INTERIM_FRAME_DATA_ALIAS_CHECK(globals);
INTERIM_FRAME_DATA_ALIAS_CHECK(locals);
INTERIM_FRAME_DATA_ALIAS_CHECK(code);
INTERIM_FRAME_DATA_ALIAS_CHECK(lasti);
INTERIM_FRAME_DATA_ALIAS_CHECK(state);
// End compatiblity alias check

static PyObject *
frame_getlocals(PyFrameObject *f, void *closure)
Expand Down
0