Skip to content

Conversation

deepwzh
Copy link
Contributor

@deepwzh deepwzh commented May 11, 2025

Fixed Ctrl+D (^D) behavior in :mod:_pyrepl module:

  • Now properly exits multiline mode when pressed in multiline section
  • Added test cases to verify the behavior in both multiline and single line modes

@StanFromIreland
Copy link
Member

StanFromIreland commented May 11, 2025

This is not ideal:

>>> if True:
...     
  File "<python-input-2>", line 1
    if True:
            ^
IndentationError: expected an indented block after 'if' statement on line 1
>>>

@deepwzh
Copy link
Contributor Author

deepwzh commented May 11, 2025

This is not ideal:

>>> if True:
...     
  File "<python-input-2>", line 1
    if True:
            ^
IndentationError: expected an indented block after 'if' statement on line 1
>>>

This fix is ​​to correctly handle the issue of Ctrl+D to exit multi-line mode. What do you think the expected behavior should be?
@StanFromIreland

@ZeroIntensity ZeroIntensity added topic-repl Related to the interactive shell needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes labels May 11, 2025
@feoh
Copy link
Contributor

feoh commented May 19, 2025

@ambv FWIW I tested this PR on my Mac (main branch, latest, MacOS latest) and it works great. I tried throwing a bunch of other unclosed constructs (e.g. {, [, etc.) and none exhibited this error either.

@feoh
Copy link
Contributor

feoh commented May 19, 2025

@StanFromIreland Are you suggesting that the error message in the if True: case could be more clear?

The fact that the user isn't supplying a valid indented block after the if True: is indeed a problem the language needs to flag, so I'm curious what specific wording you think might be more clear. Also it seems to me like this could be a separate Github issue. Do you agree?

@adqm
Copy link
Contributor

adqm commented Jul 20, 2025

Looking at those lines again, I would probably refactor to bring the check for self.event[-1] == "\004" out in front, replacing the current if/elif structure with something like the following:

        if self.event[-1] == "\004":
            if b and b[-1].endswith("\n"):
                self.finish = True
            elif (
                r.pos == 0
                and len(b) == 0  # this is something of a hack
            ):
                r.update_screen()
                r.console.finish()
                raise EOFError

I tried looking at the test cases a little bit, but I haven't been able to figure out how best to add the tests yet. What I wanted to test was that the following happens:

  • ^D in the middle of a line deletes the current character
  • ^D at the end of a nonempty line does nothing
  • ^D on a blank line with no preceding lines raises EOFError
  • ^D on a blank line with preceding lines runs the code up to that point

I tested that at my own terminal (using the version of the code I pasted above), but I'm not sure the best way to encode that as test cases since multiline_input is unhappy with what I tried to feed it to simulate those cases.


@StanFromIreland, this behavior would be consistent with the pre-3.13 REPL, which is what I think we should be aiming for here.

@deepwzh deepwzh force-pushed the fix-issue-133400 branch from 92bb608 to d0dc732 Compare July 20, 2025 09:03
@deepwzh
Copy link
Contributor Author

deepwzh commented Jul 20, 2025

Looking at those lines again, I would probably refactor to bring the check for self.event[-1] == "\004" out in front, replacing the current if/elif structure with something like the following:

        if self.event[-1] == "\004":
            if b and b[-1].endswith("\n"):
                self.finish = True
            elif (
                r.pos == 0
                and len(b) == 0  # this is something of a hack
            ):
                r.update_screen()
                r.console.finish()
                raise EOFError

I tried looking at the test cases a little bit, but I haven't been able to figure out how best to add the tests yet. What I wanted to test was that the following happens:

  • ^D in the middle of a line deletes the current character
  • ^D at the end of a nonempty line does nothing
  • ^D on a blank line with no preceding lines raises EOFError
  • ^D on a blank line with preceding lines runs the code up to that point

I tested that at my own terminal (using the version of the code I pasted above), but I'm not sure the best way to encode that as test cases since multiline_input is unhappy with what I tried to feed it to simulate those cases.

@StanFromIreland, this behavior would be consistent with the pre-3.13 REPL, which is what I think we should be aiming for here.

I tried to make some modifications and add more tests based on what you just said

@adqm
Copy link
Contributor

adqm commented Jul 21, 2025

I tried to make some modifications and add more tests based on what you just said

Thanks! I just tested this out and it feels right to me (at least if the goal is indeed to mimic the behavior of the old pre-3.13 REPL, which I think is the right thing to do here).

Unfortunately I don't have any authority here, but hopefully you'll get some additional code review 🙂

@ambv ambv merged commit 81959a0 into python:main Oct 9, 2025
49 checks passed
@miss-islington-app
Copy link

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

@miss-islington-app
Copy link

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

cherry_picker 81959a0364f5bc15414d5bd61c5c0d019d486fe5 3.14

@miss-islington-app
Copy link

Sorry, @deepwzh 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 81959a0364f5bc15414d5bd61c5c0d019d486fe5 3.13

ambv pushed a commit to ambv/cpython that referenced this pull request Oct 9, 2025
…module (pythonGH-133883)

(cherry picked from commit 81959a0)

Co-authored-by: DeepWzh <[email protected]>
Co-authored-by: adam j hartz <[email protected]>
@bedevere-app
Copy link

bedevere-app bot commented Oct 9, 2025

GH-139850 is a backport of this pull request to the 3.14 branch.

@bedevere-app bedevere-app bot removed the needs backport to 3.14 bugs and security fixes label Oct 9, 2025
ambv pushed a commit to ambv/cpython that referenced this pull request Oct 9, 2025
…module (pythonGH-133883)

(cherry picked from commit 81959a0)

Co-authored-by: DeepWzh <[email protected]>
Co-authored-by: adam j hartz <[email protected]>
@bedevere-app
Copy link

bedevere-app bot commented Oct 9, 2025

GH-139851 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 Oct 9, 2025
@adqm
Copy link
Contributor

adqm commented Oct 9, 2025

Thanks @ambv!

ambv added a commit that referenced this pull request Oct 9, 2025
…GH-133883) (GH-139851)

(cherry picked from commit 81959a0)

Co-authored-by: DeepWzh <[email protected]>
Co-authored-by: adam j hartz <[email protected]>
ambv added a commit that referenced this pull request Oct 9, 2025
…GH-133883) (GH-139850)

(cherry picked from commit 81959a0)

Co-authored-by: DeepWzh <[email protected]>
Co-authored-by: adam j hartz <[email protected]>
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.

6 participants