Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Doc/c-api/init.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1438,7 +1438,7 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
.. versionadded:: 3.8


.. c:type:: PyObject* (*_PyFrameEvalFunction)(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwflag)
.. c:type:: PyObject* (*PyUnstable_FrameEvalFunction)(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwflag)

Type of a frame evaluation function.

Expand All @@ -1451,21 +1451,21 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
.. versionchanged:: 3.11
The *frame* parameter changed from ``PyFrameObject*`` to ``_PyInterpreterFrame*``.

.. c:function:: _PyFrameEvalFunction _PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp)
.. c:function:: PyUnstable_FrameEvalFunction PyUnstable_InterpreterState_GetEvalFrameFunc(PyInterpreterState *interp)

Get the frame evaluation function.

See the :pep:`523` "Adding a frame evaluation API to CPython".

.. versionadded:: 3.9
.. versionadded:: next

.. c:function:: void _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp, _PyFrameEvalFunction eval_frame)
.. c:function:: void PyUnstable_InterpreterState_SetEvalFrameFunc(PyInterpreterState *interp, PyUnstable_FrameEvalFunction eval_frame)

Set the frame evaluation function.

See the :pep:`523` "Adding a frame evaluation API to CPython".

.. versionadded:: 3.9
.. versionadded:: next


.. c:function:: PyObject* PyThreadState_GetDict()
Expand Down
7 changes: 7 additions & 0 deletions Doc/deprecations/c-api-pending-removal-in-3.20.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,10 @@ Pending removal in Python 3.20
representation.

* Macros :c:macro:`!Py_MATH_PIl` and :c:macro:`!Py_MATH_El`.

* :c:func:`!_PyInterpreterState_GetEvalFrameFunc` and
:c:func:`!_PyInterpreterState_SetEvalFrameFunc` functions are deprecated
and will be removed in Python 3.20. Use
:c:func:`PyUnstable_InterpreterState_GetEvalFrameFunc` and
:c:func:`PyUnstable_InterpreterState_SetEvalFrameFunc` instead.
(Contributed by Victor Stinner in :gh:`141518`.)
2 changes: 1 addition & 1 deletion Doc/whatsnew/3.11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2305,7 +2305,7 @@ Porting to Python 3.11
be used for ``size``.
(Contributed by Kumar Aditya in :issue:`46608`.)

* :c:func:`_PyFrameEvalFunction` now takes ``_PyInterpreterFrame*``
* :c:func:`!_PyFrameEvalFunction` now takes ``_PyInterpreterFrame*``
as its second parameter, instead of ``PyFrameObject*``.
See :pep:`523` for more details of how to use this function pointer type.

Expand Down
17 changes: 17 additions & 0 deletions Doc/whatsnew/3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,16 @@ New features
* Add :c:func:`PyTuple_FromArray` to create a :class:`tuple` from an array.
(Contributed by Victor Stinner in :gh:`111489`.)

* Add a PyUnstable API for :pep:`523`:

* :c:type:`PyUnstable_FrameEvalFunction` type
* :c:func:`PyUnstable_InterpreterState_GetEvalFrameFunc`
* :c:func:`PyUnstable_InterpreterState_SetEvalFrameFunc`

(Contributed by Victor Stinner in :gh:`141518`.)

Patch by Victor Stinner.

* Add :c:func:`PyUnstable_ThreadState_SetStackProtection` and
:c:func:`PyUnstable_ThreadState_ResetStackProtection` functions to set
the stack protection base address and stack protection size of a Python
Expand Down Expand Up @@ -1223,6 +1233,13 @@ Deprecated C APIs
since 3.15 and will be removed in 3.20.
(Contributed by Sergey B Kirpichev in :gh:`141004`.)

* :c:func:`!_PyInterpreterState_GetEvalFrameFunc` and
:c:func:`!_PyInterpreterState_SetEvalFrameFunc` functions are deprecated
and will be removed in Python 3.20. Use
:c:func:`PyUnstable_InterpreterState_GetEvalFrameFunc` and
:c:func:`PyUnstable_InterpreterState_SetEvalFrameFunc` instead.
(Contributed by Victor Stinner in :gh:`141518`.)


.. Add C API deprecations above alphabetically, not here at the end.

Expand Down
24 changes: 20 additions & 4 deletions Include/cpython/pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,10 +302,26 @@ PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void);

/* Frame evaluation API */

typedef PyObject* (*_PyFrameEvalFunction)(PyThreadState *tstate, struct _PyInterpreterFrame *, int);
typedef PyObject* (*PyUnstable_FrameEvalFunction)(PyThreadState *tstate, struct _PyInterpreterFrame *, int);

PyAPI_FUNC(_PyFrameEvalFunction) _PyInterpreterState_GetEvalFrameFunc(
PyAPI_FUNC(PyUnstable_FrameEvalFunction) PyUnstable_InterpreterState_GetEvalFrameFunc(
PyInterpreterState *interp);
PyAPI_FUNC(void) _PyInterpreterState_SetEvalFrameFunc(
PyAPI_FUNC(void) PyUnstable_InterpreterState_SetEvalFrameFunc(
PyInterpreterState *interp,
_PyFrameEvalFunction eval_frame);
PyUnstable_FrameEvalFunction eval_frame);

// Deprecated aliases kept for backward compatibility
#define _PyFrameEvalFunction PyUnstable_FrameEvalFunction

Py_DEPRECATED(3.15) static inline PyUnstable_FrameEvalFunction
_PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp)
{
return PyUnstable_InterpreterState_GetEvalFrameFunc(interp);
}

Py_DEPRECATED(3.15) static inline void
_PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp,
PyUnstable_FrameEvalFunction eval_frame)
{
PyUnstable_InterpreterState_SetEvalFrameFunc(interp, eval_frame);
}
4 changes: 2 additions & 2 deletions Include/internal/pycore_interp_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ struct _ceval_runtime_state {
struct trampoline_api_st trampoline_api;
FILE *map_file;
Py_ssize_t persist_after_fork;
_PyFrameEvalFunction prev_eval_frame;
PyUnstable_FrameEvalFunction prev_eval_frame;
#else
int _not_used;
#endif
Expand Down Expand Up @@ -860,7 +860,7 @@ struct _is {
PyObject *sysdict_copy;
PyObject *builtins_copy;
// Initialized to _PyEval_EvalFrameDefault().
_PyFrameEvalFunction eval_frame;
PyUnstable_FrameEvalFunction eval_frame;

PyFunction_WatchCallback func_watchers[FUNC_MAX_WATCHERS];
// One bit is set for each non-NULL entry in func_watchers
Expand Down
6 changes: 3 additions & 3 deletions Misc/NEWS.d/3.9.0a5.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1305,6 +1305,6 @@ and undefined PY_SSIZE_T_CLEAN whwn an exception is set.
.. section: C API

Add a private API to get and set the frame evaluation function: add
:c:func:`_PyInterpreterState_GetEvalFrameFunc` and
:c:func:`_PyInterpreterState_SetEvalFrameFunc` C functions. The
:c:type:`_PyFrameEvalFunction` function type now takes a *tstate* parameter.
:c:func:`!_PyInterpreterState_GetEvalFrameFunc` and
:c:func:`!_PyInterpreterState_SetEvalFrameFunc` C functions. The
:c:type:`!_PyFrameEvalFunction` function type now takes a *tstate* parameter.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Add a PyUnstable API for :pep:`523`:

* :c:type:`PyUnstable_FrameEvalFunction` type
* :c:func:`PyUnstable_InterpreterState_GetEvalFrameFunc`
* :c:func:`PyUnstable_InterpreterState_SetEvalFrameFunc`

Patch by Victor Stinner.
6 changes: 4 additions & 2 deletions Modules/_testinternalcapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,8 @@ static PyObject *
set_eval_frame_default(PyObject *self, PyObject *Py_UNUSED(args))
{
module_state *state = get_module_state(self);
_PyInterpreterState_SetEvalFrameFunc(_PyInterpreterState_GET(), _PyEval_EvalFrameDefault);
PyUnstable_InterpreterState_SetEvalFrameFunc(_PyInterpreterState_GET(),
_PyEval_EvalFrameDefault);
Py_CLEAR(state->record_list);
Py_RETURN_NONE;
}
Expand Down Expand Up @@ -689,7 +690,8 @@ set_eval_frame_record(PyObject *self, PyObject *list)
return NULL;
}
Py_XSETREF(state->record_list, Py_NewRef(list));
_PyInterpreterState_SetEvalFrameFunc(_PyInterpreterState_GET(), record_eval);
PyUnstable_InterpreterState_SetEvalFrameFunc(_PyInterpreterState_GET(),
record_eval);
Py_RETURN_NONE;
}

Expand Down
8 changes: 4 additions & 4 deletions Python/perf_trampoline.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,12 +486,12 @@ _PyPerfTrampoline_Init(int activate)
#ifdef PY_HAVE_PERF_TRAMPOLINE
PyThreadState *tstate = _PyThreadState_GET();
if (!activate) {
_PyInterpreterState_SetEvalFrameFunc(tstate->interp, prev_eval_frame);
PyUnstable_InterpreterState_SetEvalFrameFunc(tstate->interp, prev_eval_frame);
perf_status = PERF_STATUS_NO_INIT;
}
else if (tstate->interp->eval_frame != py_trampoline_evaluator) {
prev_eval_frame = _PyInterpreterState_GetEvalFrameFunc(tstate->interp);
_PyInterpreterState_SetEvalFrameFunc(tstate->interp, py_trampoline_evaluator);
prev_eval_frame = PyUnstable_InterpreterState_GetEvalFrameFunc(tstate->interp);
PyUnstable_InterpreterState_SetEvalFrameFunc(tstate->interp, py_trampoline_evaluator);
extra_code_index = _PyEval_RequestCodeExtraIndex(NULL);
if (extra_code_index == -1) {
return -1;
Expand All @@ -517,7 +517,7 @@ _PyPerfTrampoline_Fini(void)
}
PyThreadState *tstate = _PyThreadState_GET();
if (tstate->interp->eval_frame == py_trampoline_evaluator) {
_PyInterpreterState_SetEvalFrameFunc(tstate->interp, NULL);
PyUnstable_InterpreterState_SetEvalFrameFunc(tstate->interp, NULL);
}
if (perf_status == PERF_STATUS_OK) {
trampoline_api.free_state(trampoline_api.state);
Expand Down
8 changes: 4 additions & 4 deletions Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -2896,8 +2896,8 @@ PyGILState_Release(PyGILState_STATE oldstate)
/* Other API */
/*************/

_PyFrameEvalFunction
_PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp)
PyUnstable_FrameEvalFunction
PyUnstable_InterpreterState_GetEvalFrameFunc(PyInterpreterState *interp)
{
if (interp->eval_frame == NULL) {
return _PyEval_EvalFrameDefault;
Expand All @@ -2907,8 +2907,8 @@ _PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp)


void
_PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp,
_PyFrameEvalFunction eval_frame)
PyUnstable_InterpreterState_SetEvalFrameFunc(PyInterpreterState *interp,
PyUnstable_FrameEvalFunction eval_frame)
{
if (eval_frame == _PyEval_EvalFrameDefault) {
eval_frame = NULL;
Expand Down
Loading