@@ -45,7 +45,10 @@ my_fgets(PyThreadState* tstate, char *buf, int len, FILE *fp)
45
45
#endif
46
46
47
47
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
+ {
49
52
(void )(PyOS_InputHook )();
50
53
}
51
54
@@ -131,7 +134,10 @@ _PyOS_WindowsConsoleReadline(PyThreadState *tstate, HANDLE hStdIn)
131
134
wbuf = wbuf_local ;
132
135
wbuflen = sizeof (wbuf_local ) / sizeof (wbuf_local [0 ]) - 1 ;
133
136
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
+ {
135
141
(void )(PyOS_InputHook )();
136
142
}
137
143
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)
389
395
* a tty. This can happen, for example if python is run like
390
396
* this: python -i < test1.py
391
397
*/
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
+ }
397
415
Py_END_ALLOW_THREADS
398
416
399
417
PyThread_release_lock (_PyOS_ReadlineLock );
0 commit comments