You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Python >= 3.13 Attempt to execute all the commands sent, without requiring manual 'Enter' keypress #24565
During November iteration, we fixed indentation error for #24256
After the fix is merged, user is saying there are difference in how Run selection/line works for terminal -
In previous versions of Python extension, we executed all of the Python code that is sent to terminal, as opposed to mimicking REPL from cpython itself's behavior where it sometimes have trailing ... and requires an additional or two key presses of "Enter"
This is across all the different version of REPL in external terminal (using REPL from cpython):
Since the command is "Run selection/line" we should aim to execute without having user to go down to terminal and press enter.
changed the title [-]Attempt to execute all the commands sent, without trailing ... in REPL[/-][+]Attempt to execute all the commands sent, without requiring manual 'Enter' keypress[/+]on Dec 9, 2024
changed the title [-]Attempt to execute all the commands sent, without requiring manual 'Enter' keypress[/-][+]Python >= 3.13 Attempt to execute all the commands sent, without requiring manual 'Enter' keypress[/+]on Feb 6, 2025
After almost two years it is a bit frustrating that this issue still exists today. I'm still hoping that it will be fixed, as I rely on this workflow a lot, so here I'll provide a summary of the current status and potential fixes.
Behavior
After ShiftEnter on a selection, the code is pasted into the terminal REPL but not executed. The REPL shows the code followed by a ... line and waits until I press Enter manually.
I see the same behaviour with python.terminal.shellIntegration.enabled set to true and to false on every OS (I only tested on macOS and Linux, but I assume it also occurs on Windows).
Steps to reproduce
Case 1 – single line (Python 3.14 and 3.15)
print("hello")
Put the cursor on the line and press ShiftEnter. The terminal shows
>>> print("hello")
...
and waits. One additional Enter in the terminal prints hello.
Case 2 – two (or more) statements (Python 3.13, 3.14 and 3.15)
x=1print(x)
Select both lines and press ShiftEnter. The terminal shows
>>> x = 1
... print(x)
...
and waits. One additional Enter runs it.
Analysis
I used Claude to replay the exact bytes the extension sends into a real REPL in a pty (outside VS Code), using the extension's own normalizeSelection.py. I ran everything twice: once without PYTHONSTARTUP (setting false) and once with PYTHONSTARTUP pointing at the extension's pythonrc.py (setting true). The results were identical in both modes. For Python ≥ 3.13 the extension sends ESC[200~<code>ESC[201~ and then a separate sendText("\r", false) (sendPythonShellCommand).
Results (executed without a manual Enter / number of trials; same for shellIntegration.enabled true and false):
Payload
Python
paste + immediate \r (current)
paste, 0.3 s pause, \r
paste, \r, \r
print("hello")
3.13
10/10
5/5
5/5
print("hello")
3.14
0/10
4/4
4/4
x = 1 / print(x)
3.13
0/3
0/3
3/3
x = 1 / print(x)
3.14
0/3
0/3
3/3
print("hello")
3.15.0rc3
0/3
3/3
3/3
x = 1 / print(x)
3.15.0rc3
0/3
0/3
3/3
3.14 and 3.15, single line: the \r is lost or swallowed when it arrives immediately after ESC[201~; a short delay makes it work. This looks like a race in how PyREPL handles the end of a bracketed paste.
Multiple statements (3.13, 3.14, 3.15): PyREPL treats the pasted text as a multi-line block, so one \r only adds a line and a second Enter is needed.
I only tested Python 3.13 and 3.14 in VS Code. Below 3.13 the extension sends plain text without paste markers; in the replay that path ran without an extra Enter.
Note that the single line case worked in 3.13 and stopped working in 3.14, whereas the multiline case does not work in 3.13, 3.14, and 3.15.
Possible fix
In sendPythonShellCommand, the final \r is sent right after the paste. I tested candidate changes with the same pty replay (3.13, 3.14, 3.15; PYTHONSTARTUP set and unset):
Don't send the \r immediately after ESC[201~. With no pause it fails on 3.14/3.15 (0/3); with any pause, even 5 ms, a single line executes (3/3).
For multi-line selections, send a second \r after a pause. A pause alone does not help there, because one Enter only adds a line to PyREPL's buffer. Keeping the normalizer's trailing \n inside the paste, followed by the delayed \r, works as well.
With both changes, every payload I tried (single line, two statements, multi-line call, for, def, if/else) executed without a manual Enter, 2/2 per version.
I have not tested a patched extension inside VS Code. The 50 ms is a heuristic; waiting for the terminal's next output after the paste would be more robust. flushReplQueue would need to await each call.
Activity
[-]Attempt to execute all the commands sent, without trailing ... in REPL[/-][+]Attempt to execute all the commands sent, without requiring manual 'Enter' keypress[/+]anthonykim1 commentedon Feb 4, 2025
Related: #22469
[-]Attempt to execute all the commands sent, without requiring manual 'Enter' keypress[/-][+]Python >= 3.13 Attempt to execute all the commands sent, without requiring manual 'Enter' keypress[/+]cbrnr commentedon Oct 8, 2026
After almost two years it is a bit frustrating that this issue still exists today. I'm still hoping that it will be fixed, as I rely on this workflow a lot, so here I'll provide a summary of the current status and potential fixes.
Behavior
After ShiftEnter on a selection, the code is pasted into the terminal REPL but not executed. The REPL shows the code followed by a
...line and waits until I press Enter manually.I see the same behaviour with
python.terminal.shellIntegration.enabledset totrueand tofalseon every OS (I only tested on macOS and Linux, but I assume it also occurs on Windows).Steps to reproduce
Case 1 – single line (Python 3.14 and 3.15)
Put the cursor on the line and press ShiftEnter. The terminal shows
and waits. One additional Enter in the terminal prints
hello.Case 2 – two (or more) statements (Python 3.13, 3.14 and 3.15)
Select both lines and press ShiftEnter. The terminal shows
and waits. One additional Enter runs it.
Analysis
I used Claude to replay the exact bytes the extension sends into a real REPL in a pty (outside VS Code), using the extension's own
normalizeSelection.py. I ran everything twice: once withoutPYTHONSTARTUP(settingfalse) and once withPYTHONSTARTUPpointing at the extension'spythonrc.py(settingtrue). The results were identical in both modes. For Python ≥ 3.13 the extension sendsESC[200~<code>ESC[201~and then a separatesendText("\r", false)(sendPythonShellCommand).Results (executed without a manual Enter / number of trials; same for
shellIntegration.enabledtrue and false):paste+ immediate\r(current)paste, 0.3 s pause,\rpaste,\r,\rprint("hello")print("hello")x = 1/print(x)x = 1/print(x)print("hello")x = 1/print(x)\ris lost or swallowed when it arrives immediately afterESC[201~; a short delay makes it work. This looks like a race in how PyREPL handles the end of a bracketed paste.\ronly adds a line and a second Enter is needed.Possible fix
In
sendPythonShellCommand, the final\ris sent right after the paste. I tested candidate changes with the same pty replay (3.13, 3.14, 3.15;PYTHONSTARTUPset and unset):\rimmediately afterESC[201~. With no pause it fails on 3.14/3.15 (0/3); with any pause, even 5 ms, a single line executes (3/3).\rafter a pause. A pause alone does not help there, because one Enter only adds a line to PyREPL's buffer. Keeping the normalizer's trailing\ninside the paste, followed by the delayed\r, works as well.With both changes, every payload I tried (single line, two statements, multi-line call,
for,def,if/else) executed without a manual Enter, 2/2 per version.I have not tested a patched extension inside VS Code. The 50 ms is a heuristic; waiting for the terminal's next output after the paste would be more robust.
flushReplQueuewould need to await each call.Possibly related
#24565 (multi-line case, Python ≥ 3.13), #25713, #26176 (paste markers, fixed in 2026.6.x nightly), #25937 (macOS).