diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index 6256bf7a1454a9a..eefc6386597b395 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -151,6 +151,8 @@ the same library that the Python runtime is using. event loops, as done in :file:`Modules/_tkinter.c` in the Python source code. + This function should block until stdin is readable. + .. versionchanged:: 3.12 This function is only called from the :ref:`main interpreter `. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-29-00-00-00.gh-issue-103929.InputHook.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-29-00-00-00.gh-issue-103929.InputHook.rst new file mode 100644 index 000000000000000..ebae4b74a2a6c2d --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-29-00-00-00.gh-issue-103929.InputHook.rst @@ -0,0 +1 @@ +Fix repeated calls to :c:var:`PyOS_InputHook` for long input lines. diff --git a/Parser/myreadline.c b/Parser/myreadline.c index ee77479ba7bdccb..1504577ab11de2c 100644 --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -53,12 +53,6 @@ my_fgets(PyThreadState* tstate, char *buf, int len, FILE *fp) #endif while (1) { - if (PyOS_InputHook != NULL && - // GH-104668: See PyOS_ReadlineFunctionPointer's comment below... - _Py_IsMainInterpreter(tstate->interp)) - { - (void)(PyOS_InputHook)(); - } errno = 0; clearerr(fp); @@ -312,6 +306,13 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) fprintf(stderr, "%s", prompt); } fflush(stderr); + // Keep this outside my_fgets(): long lines call my_fgets() repeatedly. + if (PyOS_InputHook != NULL && + // GH-104668: See PyOS_ReadlineFunctionPointer's comment below... + _Py_IsMainInterpreter(tstate->interp)) + { + (void)(PyOS_InputHook)(); + } n = 0; p = NULL;