Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-119842: Honor PyOS_InputHook in the new REPL #119843

Merged
merged 5 commits into from
Jun 4, 2024
Merged

Conversation

pablogsal
Copy link
Member

@pablogsal pablogsal commented May 31, 2024

@ambv ambv added the topic-repl Related to the interactive shell label May 31, 2024
Copy link
Contributor

@mdboom mdboom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, this doesn't seem to address the bug and restore old behavior, see #119842 (comment)

@mdboom
Copy link
Contributor

mdboom commented May 31, 2024

Since Tkinter's PyOS_InputHook implementation sets the thread state, we need to ALLOW_THREADS around it. We could either do that in Tkinter (but that would be a new requirement on all PyOS_InputHook implementations in the wild), or instead call PyOS_InputHook through a wrapper that allows threads. I have a proof of concept here to show what I mean. This seems to make matplotlib and the simple Tkinter reproducer work as expected (events are handled, the window repaints and resizes etc.)

I share @ambv's concern that this isn't called periodically, but at least for Tkinter it doesn't matter. Maybe it does for other GUI toolkits, though -- it looks like PyQt5 does, for example.

@pablogsal
Copy link
Member Author

or instead call PyOS_InputHook through a wrapper that allows threads.

I think that's our best approach here because it was previously readline dropping the GIL around it so now is us that need to do it and we must to that from C.

@pablogsal
Copy link
Member Author

Ok, I think I have a version that should be backwards compatible with the periodic calls that readline.c does. It may be still have some rough edges but I want to discuss before doing more with this. @ambv @mdboom

@pablogsal pablogsal force-pushed the gh-119842 branch 2 times, most recently from ce1ac80 to ed164d7 Compare June 1, 2024 13:24
Signed-off-by: Pablo Galindo <pablogsal@gmail.com>
@tacaswell
Copy link
Contributor

Things that may be useful references:

The best-case behavior is when the input hook can watch stdin and exit the event loop when there is input to read, second best case is the hook run the loop for some short period and checks if there is input in a hotloop.

Mike is right, the expect expectation is that the window is reasonably responsive (<100ms) and you can type at the prompt (and it is also responsive with tab-complete etc). In general the time scale we need to switch between the two loops is human interaction time so it is OK if the prompt does not work while the user is interacting with the GUI so long as the prompt gets control again by the time the user can change their "focus" there (e.g. move mouse and click, then type).

I suspect that I'm going to be making some upstream bug reports to gtk and wx after this...

Taking a very selfish (from Matplotlib's point of view) position, if you want to re-design the input hook so long as tkinter (which I assume you will do ;) ), riverside (for PyQt) (worst case I can try to put in a patch), and Matplotlib (for macos which I can make sure gets done) provide the new hook we will get back to status quo.

Copy link
Contributor

@mdboom mdboom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks much closer to the original semantics, so I'm a lot more confident this behavior matches the legacy REPL.

I volunteered to do some testing, but I'm starting to think it isn't worth the effort to be extremely comprehensive (unless others strongly disagree).

  • I did test Tkinter on Windows and Linux, and it's working there -- and it's easy to test by creating a window and confirming it's resizable and responsive.
  • matplotlib has a PyOS_InputHook for the macOS Cocoa windowing toolkit -- that should be easy enough to test, but I don't have a Mac.
  • Other GUI frameworks (the important ones are probably PySide6, pygobject-gtk and wxPython) don't use PyOS_InputHook directly, however in the common case, IPython installs input hooks for them. But with IPython, I think by definition aren't using the new CPython REPL anyway so that's a non-issue. (i.e. the input hooks don't usually exist for the default legacy CPython REPL, so if they are broken then, they are still broken in the same way with the new CPython REPL).

Co-authored-by: Michael Droettboom <mdboom@gmail.com>
@tacaswell
Copy link
Contributor

It is probably worth testing PyQt5 and PyQt6 (I do not have time to do this today).

@ambv
Copy link
Contributor

ambv commented Jun 4, 2024

I confirm this PR also fixes the matplotlib example given by Michael in the issue on macOS Sonoma.

@ambv
Copy link
Contributor

ambv commented Jun 4, 2024

PyQt is important to us. We'll test it and adjust the behavior if needed. Now I need to land this to make it into 3.13 beta 2.

@ambv ambv merged commit d909519 into python:main Jun 4, 2024
44 checks passed
@miss-islington-app
Copy link

Thanks @pablogsal for the PR, and @ambv for merging it 🌮🎉.. I'm working now to backport this PR to: 3.13.
🐍🍒⛏🤖

@miss-islington-app
Copy link

Sorry, @pablogsal and @ambv, I could not cleanly backport this to 3.13 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker d9095194dde27eaabfc0b86a11989cdb9a2acfe1 3.13

@ambv
Copy link
Contributor

ambv commented Jun 4, 2024

I'll backport this myself once gh-120062 lands.

ambv added a commit to ambv/cpython that referenced this pull request Jun 4, 2024
…H-119843)

(cherry picked from commit d909519)

Co-authored-by: Pablo Galindo Salgado <Pablogsal@gmail.com>
Signed-off-by: Pablo Galindo <pablogsal@gmail.com>
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
Co-authored-by: Michael Droettboom <mdboom@gmail.com>
@bedevere-app
Copy link

bedevere-app bot commented Jun 4, 2024

GH-120066 is a backport of this pull request to the 3.13 branch.

@bedevere-app bedevere-app bot removed the needs backport to 3.13 bugs and security fixes label Jun 4, 2024
ambv added a commit that referenced this pull request Jun 4, 2024
…H-120066)

(cherry picked from commit d909519)

Signed-off-by: Pablo Galindo <pablogsal@gmail.com>
Co-authored-by: Pablo Galindo Salgado <Pablogsal@gmail.com>
Co-authored-by: Michael Droettboom <mdboom@gmail.com>
@tacaswell
Copy link
Contributor

Thank you @pablogsal @ambv and @mdboom !

barneygale pushed a commit to barneygale/cpython that referenced this pull request Jun 5, 2024
Signed-off-by: Pablo Galindo <pablogsal@gmail.com>
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
Co-authored-by: Michael Droettboom <mdboom@gmail.com>
noahbkim pushed a commit to hudson-trading/cpython that referenced this pull request Jul 11, 2024
Signed-off-by: Pablo Galindo <pablogsal@gmail.com>
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
Co-authored-by: Michael Droettboom <mdboom@gmail.com>
estyxx pushed a commit to estyxx/cpython that referenced this pull request Jul 17, 2024
Signed-off-by: Pablo Galindo <pablogsal@gmail.com>
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
Co-authored-by: Michael Droettboom <mdboom@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic-repl Related to the interactive shell
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants