Skip to content

gh-123856: Fix PyREPL failure when a keyboard interrupt is triggered after using a history search - #124396

Merged
ambv merged 8 commits into
python:mainfrom
emilyemorehouse:bug/gh-123856-pyrepl-search-ctrl-c-fail
Sep 25, 2024
Merged

gh-123856: Fix PyREPL failure when a keyboard interrupt is triggered after using a history search#124396
ambv merged 8 commits into
python:mainfrom
emilyemorehouse:bug/gh-123856-pyrepl-search-ctrl-c-fail

Conversation

@emilyemorehouse

@emilyemorehouse emilyemorehouse commented Sep 23, 2024

Copy link
Copy Markdown
Member

The original check in Lib/_pyrepl/simple_interact.py for handling the manual clean up when a KeyboardInterrupt is received would result in duplicate calls to clean up the search translator in some scenarios. When the search translator is allowed to exit cleanly without a KeyboardInterrupt, it calls its clean-up function (isearch_end) on its own. If a KeyboardInterrupt was triggered immediately after, the most recent command was still isearch, which would trigger a similar clean-up routine incorrectly. This now ensures that the clean-up is only executed once.

I've also added tests – we had to make modifications to the way the full version of the REPL is run – this now allows the necessary control characters to pass through. Additional overrides for other control characters may be required here as the test suite is bolstered.

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM.

I confirm that this change fix #123856. The fix works with forward and backward isearch.

Moreover, CTRL+C in an interactive search (CTRL+S or CTRL+R) still resets the prompt to >>> as expected.

Using r.isearch_trans looks safe to me since r is created by _ReadlineWrapper.get_reader() which returns a ReadlineAlikeReader and ReadlineAlikeReader inherits from HistoricalReader.

@ambv
ambv marked this pull request as ready for review September 24, 2024 18:31
@emilyemorehouse

Copy link
Copy Markdown
Member Author

@vstinner thanks for reviewing the draft version of this - I refactored the clean-up process to better mimic what happens when the search is allowed to clean up after itself (see the PR description for a little more info)

@emilyemorehouse
emilyemorehouse force-pushed the bug/gh-123856-pyrepl-search-ctrl-c-fail branch from 5bf83d6 to 7389752 Compare September 24, 2024 18:40

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM. The fix still works as expected. I tried different scenario and it just works.

I just have minor comments on the test, you can ignore them.

self.assertNotIn("\\040", pathlib.Path(hfile.name).read_text())

def test_keyboard_interrupt_after_isearch(self):
output, exit_code = self.run_repl(["\x12", "\x03", "exit"])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Would it be possible to add (module-level) constants for "\x12" and "\x03"?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We'll do that later as part of more tests for control characters.

Comment thread Lib/test/test_pyrepl/test_pyrepl.py Outdated
cmd.extend(cmdline_args)

term_attr = termios.tcgetattr(slave_fd)
term_attr[6][termios.VREPRINT] = 0 # pass through CTRL-R

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What is the hardcoded constant 6?

Comment thread Lib/test/test_pyrepl/test_pyrepl.py Outdated
@ambv

ambv commented Sep 24, 2024

Copy link
Copy Markdown
Contributor

Address sanitizer is failing test_pyrepl with:

warning: can't use pyrepl: setupterm: could not find terminfo database

@ambv

ambv commented Sep 25, 2024

Copy link
Copy Markdown
Contributor

After trying to find which TERM's on address sanitizer, we're still seeing

warning: can't use pyrepl: setupterm: could not find terminfo database

which suggests TERM is unset or empty. Let's just add that case to our TestMain ignore.

@ambv ambv left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Excellent!

self.assertNotIn("\\040", pathlib.Path(hfile.name).read_text())

def test_keyboard_interrupt_after_isearch(self):
output, exit_code = self.run_repl(["\x12", "\x03", "exit"])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We'll do that later as part of more tests for control characters.

Comment on lines +165 to +166
if r.input_trans is r.isearch_trans:
r.do_cmd(("isearch-end", [""]))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This reads much better 👍🏻

@ambv
ambv merged commit c1600c7 into python:main Sep 25, 2024
@miss-islington-app

Copy link
Copy Markdown

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

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Sep 25, 2024
…gered after using a history search (pythonGH-124396)

(cherry picked from commit c1600c7)

Co-authored-by: Emily Morehouse <emily@cuttlesoft.com>
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
@bedevere-app

bedevere-app Bot commented Sep 25, 2024

Copy link
Copy Markdown

GH-124530 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 Sep 25, 2024
Yhg1s pushed a commit that referenced this pull request Sep 26, 2024
…ggered after using a history search (GH-124396) (#124530)

gh-123856: Fix PyREPL failure when a keyboard interrupt is triggered after using a history search (GH-124396)
(cherry picked from commit c1600c7)

Co-authored-by: Emily Morehouse <emily@cuttlesoft.com>
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants