Skip to content

PyREPL: Send code using bracketed paste markers - #26178

Merged
Eduardo Villalpando Mello (edvilme) merged 4 commits into
mainfrom
pyrepl-bracketed-paste
Oct 2, 2026
Merged

Eduardo Villalpando Mello (edvilme) merged 4 commits into
mainfrom
pyrepl-bracketed-paste

Conversation

@edvilme

@edvilme Eduardo Villalpando Mello (edvilme) commented Oct 1, 2026 •

Copy link
Copy Markdown

Fixes #26176.

Problem

On Python 3.13+, using Shift+Enter to run selected/multiline code in the integrated terminal progressively increased the indentation of continuation lines, eventually raising IndentationError: unexpected indent (regression observed in 2026.6.0).

Root cause

The new Python 3.13 PyREPL auto-indents interactively typed input. Terminal REPL code is delivered via terminal.sendText(...) and never shellIntegration.executeCommand(...) (the Python path in TerminalService.executeCommand returns early), so bracketed paste markers are the only thing that tells the PyREPL "this is pasted text — preserve its whitespace".

CodeExecutionHelper.normalizeLines only attached those markers when shell integration was disabled:

if (object.attach_bracket_paste && !shellIntegrationEnabled && _replType === ReplType.terminal)

But the PyREPL stays active even when shell integration is enabled — shell integration is provided from inside Python via PYTHONSTARTUP / pythonrc.py, which makes the REPL's own PS1 emit OSC 633 sequences (the pink/violet >>> users noticed). So with shell integration on (the default), the markers were skipped, raw multiline code was typed into the auto-indenting REPL, and indentation grew line by line.

Fix

Attach bracketed paste for Python 3.13+ terminal sends regardless of the terminal.shellIntegration.enabled setting, since terminal REPL input always goes through sendText:

if (object.attach_bracket_paste && _replType === ReplType.terminal)

The now-unused shellIntegrationEnabled lookup was removed.

Changes

  • src/client/terminals/codeExecution/helper.ts — drop the !shellIntegrationEnabled guard so bracketed paste is applied for the 3.13+ PyREPL in the terminal whether or not shell integration is enabled; remove the unused setting read.
  • src/test/terminals/codeExecution/helper.test.ts — replace the obsolete "BASIC_REPL does not attach bracketed paste" test (which only passed because reading settings.terminal.shellIntegration threw and hit the catch) with a Shift+Enter progressively changes indentation when running Python code in the terminal #26176 regression test asserting that multiline, indented code sent to a 3.13+ terminal REPL is wrapped in bracketed paste, with indentation preserved verbatim, even when shell integration is enabled.

Note

This supersedes the earlier approach of wrapping inside TerminalService directly, which double-wrapped PyREPL users (the helper already wraps) and risked sending bracketed-paste markers to non-PyREPL interpreters. Those service.ts / service.unit.test.ts changes are reverted.

@edvilme Eduardo Villalpando Mello (edvilme) added the debt Code quality issues label Oct 1, 2026

// For new _pyrepl for Python3.13+ && !shellIntegration, we need to send code via bracketed paste mode.
if (object.attach_bracket_paste && !shellIntegrationEnabled && _replType === ReplType.terminal) {
// For the new _pyrepl in Python 3.13+, send code via bracketed paste mode so the REPL

@anthonykim1 Anthony Kim (anthonykim1) Oct 1, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I don't recall exact detail, but the indentation logic has been funky and probably worth revisiting with newer models. Maybe there were some nuances with PY_REPL flag + shell integration combination.

Also recommend these 4 scenarios when it comes to manually testing and ensuring coverage for run selection of Python code (via shift+enter, or UI):

When I say shell integration, I mean both the terminal.integrated.shellIntegration.enabled and python.terminal.shellIntegration.enabled

  1. >= Python3.13 with shell integration enabled.
  2. < Python 3.13 with shell integration enabled.
  3. >= Python3.13 with shell integration disabled.
  4. < Python 3.13 with shell integration disabled.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

>=3.13 with shell integration enabled

image

>=3.13 with shell integration disabled

image

< 3.13 with shell integration disabled

image

< 3.13 with shell integration enabled

image

Comment thread src/client/common/terminal/service.ts Outdated
Comment thread src/client/common/terminal/service.ts
@edvilme
Eduardo Villalpando Mello (edvilme) merged commit 4c27431 into main Oct 2, 2026
90 checks passed
@edvilme
Eduardo Villalpando Mello (edvilme) deleted the pyrepl-bracketed-paste branch October 2, 2026 00:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

debt Code quality issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Shift+Enter progressively changes indentation when running Python code in the terminal

4 participants