| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
The usual way to test a C API call directly is add a method to the testcapi module. It seems like you could test this through a call to PyOS_StdioReadline, but it's not exactly trivial to set up the FILE objects and buffer them with data etc. I don't see any other tests in testcapi doing anything like that. |
Sorry, something went wrong.
|
@brandtbucher: Maybe you have enough context to review this since you've been in readline-adjacent things lately? |
Sorry, something went wrong.
|
I'll take a look today next week. Thanks for the PR! |
Sorry, something went wrong.
|
rebased to handle conflicts with the sub-processor work. |
Sorry, something went wrong.
|
Rebased again. |
Sorry, something went wrong.
|
@brandtbucher did you ever get a chance to review this one? |
Sorry, something went wrong.
|
@pablogsal, @ambv: If I understand correctly, users are more likely to hit this bug in 3.14 since the new REPL doesn't use readline. Should we try to get this into the next 3.14 beta? |
Sorry, something went wrong.
This fix doesn't apply to the new REPL, so I don't think how this PR could help here |
Sorry, something went wrong.
Got it. My bad. |
Sorry, something went wrong.
|
@pablogsal Does that mean the new REPL should/will not have this 100 char limit while PyOS_InputHook is installed? |
Sorry, something went wrong.
|
The bug that is fixed is in the readline-replacement implementation that Python carries, not in the input hooks, so if there are bugs in the new repl with long lines, they will be different bugs ;) |
Sorry, something went wrong.
|
I'll take that as a solid maybe ;). Will report if I find similar long-line bugs with active input hooks. Update: re-reading, it seems you mean the bug remains, but that the new REPL has worked around it in another way. Those of us using input-based REPL's the still need this fix. |
Sorry, something went wrong.
|
This bug shows up not only with input() but also with interactive Python when typing commands at the Python prompt. For example, running the commands in this script one-by-one will freeze Python after long_string until the user hits enter one more time: >>> import tkinter
>>> t = tkinter.Tk()
>>> short_string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
>>> long_string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
>>> >>> ^D(as @tacaswell mentioned, the bug only appears on Python without readline). |
Sorry, something went wrong.
|
It would be nice to get this reviewed and merged. For now the only workaround is import readline, which may be undesirable. |
Sorry, something went wrong.
When stdin is unbuffered, then fgets reads directly from stdin and leaves any characters in stdin that do not fit in the fgets buffer. PyOS_InputHook will then see those remaining characters, and return. When stdin is buffered, then fgets reads the data from stdin into an internal buffer. This internal buffer is likely bigger than even the long input line, so it will read the full line into its internal buffer, leaving nothing in stdin. PyOS_InputHook then doesn't find anything in stdin, and will block waiting for new input. |
Sorry, something went wrong.
|
rebased to re-trigger CI. |
Sorry, something went wrong.
This loop happens inside of the PyOS_InputHook function. See the EventHook function in Modules\_tkinter.c, which boils down to while (!stdin_ready) {
int result = Tcl_DoOneEvent(TCL_DONT_WAIT);
if (result == 0)
Sleep(Tkinter_busywaitinterval);
}
There is no need to have such a second loop on top of it outside of PyOS_InputHook. See also pull request #140147 which gets rid of the Windows-specific code in EventHook. |
Sorry, something went wrong.
|
But does it happen inside the function for all function currently in the wild? I have a recent-ish survey here: #119843 (comment) |
Sorry, something went wrong.
In the main packages (matplotlib, PyQt5, PyQt6, PySide, and PyGTK), PyOS_InputHook points to a function that returns once data is available on stdin. PyGObject (which superseded PyGTK) does not use PyOS_InputHook. For wxPython: there was a discussion about it 16 years ago (see https://discuss.wxpython.org/t/interactive-usage-of-wxpython/32128/22, where I was making the same comments). But I did not find any (recent or old) version of wxPython that actually uses PyOS_InputHook, so I guess it was never implemented. Now there may be some module in the wild that assumes that PyOS_InputHook is called repeatedly. I didn't find such a module, but if it exists, its event loop will freeze with Python without readline support. |
Sorry, something went wrong.
|
@mdehoon is correct and we can pull the PyOS_InputHook up a level rather than add code to avoid calling it in the inner loop. |
Sorry, something went wrong.
|
@pablogsal With the new pyrepl what is the future plan for this code? |
Sorry, something went wrong.
|
@tacaswell Thanks, it looks good to me. |
Sorry, something went wrong.
|
This PR is stale because it has been open for 30 days with no activity. |
Sorry, something went wrong.
|
This is still waiting on review from a core developer. This is to my knowledge still both correct and needed. |
Sorry, something went wrong.
|
I pushed a small fix for this in codex/pr-103931-fix-96fa029507a6. Can you take a look? |
Sorry, something went wrong.
|
Merged that commit to this branch. Sorry, thought this was below the threshold of needing a news. |
Sorry, something went wrong.
Documentation build overview424 files changed · + 12 added · ± 412 modified + Added
± Modified |
Sorry, something went wrong.
|
@pablogsal I think this is good to go. |
Sorry, something went wrong.
|
This PR is stale because it has been open for 90 days with no activity. |
Sorry, something went wrong.
|
rebased on current main, still think this is ready to go! |
Sorry, something went wrong.
If: - stdin is in line buffer mode - the readline module is not loaded - not on windows - a GUI toolkit has installd PyOS_InputHook Then, if the user enters lines longer than 98 characters into `input`: - user calls `input(...)` - user types/pastes a line longer than 98 characters + 1 newline - PyOS_InputHook returns - the first 99 characters are returned - the last character is not a new line so we go back to my_fgets - the PyOS_InputHook blocks because despite there being value in the buffer, stdin does not flag itself as ready to be read again - user hits enter again and to finish reading the input - the extra new line comes out the next time the user calls input This fixes this bug by passing the currently read number of characters to `my_fgets` to skip the input hook when reading out a long buffer. closes python#103929
If we have returned from the input hook then there is something to read in the stdin so read it out to the new line before calling the input hook again.
| Back | FazBrowse Home | New Git URL |
If:
Then, if the user enters lines longer than 98 characters into input:
This fixes this bug by passing the currently read number of characters to my_fgets to skip the input hook when reading out a long buffer.
closes #103929
Qustions: