Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 357bed0

Browse filesBrowse files
authored
pythonGH-104668: Don't call PyOS_* hooks in subinterpreters (pythonGH-104674)
1 parent 2c4e29e commit 357bed0
Copy full SHA for 357bed0

File tree

4 files changed

+47
-7
lines changed
Filter options

4 files changed

+47
-7
lines changed

‎Doc/c-api/veryhigh.rst

Copy file name to clipboardExpand all lines: Doc/c-api/veryhigh.rst
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,10 @@ the same library that the Python runtime is using.
167167
event loops, as done in the :file:`Modules/_tkinter.c` in the
168168
Python source code.
169169
170+
.. versionchanged:: 3.12
171+
This function is only called from the
172+
:ref:`main interpreter <sub-interpreter-support>`.
173+
170174
171175
.. c:var:: char* (*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *)
172176
@@ -187,6 +191,10 @@ the same library that the Python runtime is using.
187191
:c:func:`PyMem_RawRealloc`, instead of being allocated by
188192
:c:func:`PyMem_Malloc` or :c:func:`PyMem_Realloc`.
189193
194+
.. versionchanged:: 3.12
195+
This function is only called from the
196+
:ref:`main interpreter <sub-interpreter-support>`.
197+
190198
.. c:function:: PyObject* PyRun_String(const char *str, int start, PyObject *globals, PyObject *locals)
191199
192200
This is a simplified interface to :c:func:`PyRun_StringFlags` below, leaving

‎Doc/whatsnew/3.12.rst

Copy file name to clipboardExpand all lines: Doc/whatsnew/3.12.rst
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,6 +1476,15 @@ Porting to Python 3.12
14761476
Note that :c:func:`PyType_FromMetaclass` (added in Python 3.12)
14771477
already disallows creating classes whose metaclass overrides ``tp_new``.
14781478

1479+
* :c:var:`PyOS_InputHook` and :c:var:`PyOS_ReadlineFunctionPointer` are no
1480+
longer called in :ref:`subinterpreters <sub-interpreter-support>`. This is
1481+
because clients generally rely on process-wide global state (since these
1482+
callbacks have no way of recovering extension module state).
1483+
1484+
This also avoids situations where extensions may find themselves running in a
1485+
subinterpreter that they don't support (or haven't yet been loaded in). See
1486+
:gh:`104668` for more info.
1487+
14791488
Deprecated
14801489
----------
14811490

+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Don't call :c:var:`PyOS_InputHook` or :c:var:`PyOS_ReadlineFunctionPointer`
2+
in subinterpreters, since it's generally difficult to avoid using global
3+
state in their registered callbacks. This also avoids situations where
4+
extensions may find themselves running in a subinterpreter they don't
5+
support (or haven't yet been loaded in).

‎Parser/myreadline.c

Copy file name to clipboardExpand all lines: Parser/myreadline.c
+25-7Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ my_fgets(PyThreadState* tstate, char *buf, int len, FILE *fp)
4545
#endif
4646

4747
while (1) {
48-
if (PyOS_InputHook != NULL) {
48+
if (PyOS_InputHook != NULL &&
49+
// GH-104668: See PyOS_ReadlineFunctionPointer's comment below...
50+
_Py_IsMainInterpreter(tstate->interp))
51+
{
4952
(void)(PyOS_InputHook)();
5053
}
5154

@@ -131,7 +134,10 @@ _PyOS_WindowsConsoleReadline(PyThreadState *tstate, HANDLE hStdIn)
131134
wbuf = wbuf_local;
132135
wbuflen = sizeof(wbuf_local) / sizeof(wbuf_local[0]) - 1;
133136
while (1) {
134-
if (PyOS_InputHook != NULL) {
137+
if (PyOS_InputHook != NULL &&
138+
// GH-104668: See PyOS_ReadlineFunctionPointer's comment below...
139+
_Py_IsMainInterpreter(tstate->interp))
140+
{
135141
(void)(PyOS_InputHook)();
136142
}
137143
if (!ReadConsoleW(hStdIn, &wbuf[total_read], wbuflen - total_read, &n_read, NULL)) {
@@ -389,11 +395,23 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
389395
* a tty. This can happen, for example if python is run like
390396
* this: python -i < test1.py
391397
*/
392-
if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout)))
393-
rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt);
394-
else
395-
rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
396-
prompt);
398+
if (!isatty(fileno(sys_stdin)) || !isatty(fileno(sys_stdout)) ||
399+
// GH-104668: Don't call global callbacks like PyOS_InputHook or
400+
// PyOS_ReadlineFunctionPointer from subinterpreters, since it seems
401+
// like there's no good way for users (like readline and tkinter) to
402+
// avoid using global state to manage them. Plus, we generally don't
403+
// want to cause trouble for libraries that don't know/care about
404+
// subinterpreter support. If libraries really need better APIs that
405+
// work per-interpreter and have ways to access module state, we can
406+
// certainly add them later (but for now we'll cross our fingers and
407+
// hope that nobody actually cares):
408+
!_Py_IsMainInterpreter(tstate->interp))
409+
{
410+
rv = PyOS_StdioReadline(sys_stdin, sys_stdout, prompt);
411+
}
412+
else {
413+
rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout, prompt);
414+
}
397415
Py_END_ALLOW_THREADS
398416

399417
PyThread_release_lock(_PyOS_ReadlineLock);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.