From 0a7931b25615126e71e212ff564b859930fa6d59 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Fri, 18 Sep 2026 09:46:54 -0700 Subject: [PATCH 01/16] REPL: Change names --- python_files/pythonrc.py | 103 ++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 44 deletions(-) diff --git a/python_files/pythonrc.py b/python_files/pythonrc.py index 817add379162..189cc69a0830 100644 --- a/python_files/pythonrc.py +++ b/python_files/pythonrc.py @@ -1,14 +1,10 @@ def _initialize(): - import platform import sys - from enum import Enum if sys.platform != "win32": import readline - original_ps1 = ">>> " - is_wsl = "microsoft-standard-WSL" in platform.release() - + original_ps1 = sys.ps1 # PYTHONSTARTUP executes this file's code inside the user's __main__ # namespace, so PS1.__str__'s globals are the user's globals. If the # user later shadows a name we rely on at prompt-render time (e.g. @@ -21,25 +17,46 @@ def _initialize(): # user code to reassign and break in the first place. _int = int _bool = bool - _str = str - - class ShellIntegrationSequence(str, Enum): - SOH = "\001" - STX = "\002" - COMMAND_EXECUTED = "\x1b]633;C\x07" - COMMAND_LINE = "\x1b]633;E;" - COMMAND_FINISHED = "\x1b]633;D;" - PROMPT_STARTED = "\x1b]633;A\x07" - COMMAND_START = "\x1b]633;B\x07" - TERMINATOR = "\x07" - def __str__(self): - return self.value + # https://code.visualstudio.com/docs/terminal/shell-integration#_supported-escape-sequences + class ShellIntegrationSequence: + soh = "\001" + stx = "\002" + + @staticmethod + def _create(code: str, *arguments: object) -> str: + parameters = "".join(f";{argument}" for argument in arguments) + return f"\x1b]633;{code}{parameters}\x07" + + # Before the prompt (>>>) is displayed + @classmethod + def prompt_start(cls) -> str: + return cls._create("A") + + # After the prompt (>>>) is displayed + @classmethod + def prompt_end(cls) -> str: + return cls._create("B") + + # After the user has typed a command but before it is executed + @classmethod + def pre_execution(cls) -> str: + return cls._create("C") + + @classmethod + def execution_finished(cls, exit_code: int) -> str: + """Mark execution as finished with its exit code.""" + return cls._create("D", exit_code) + + @classmethod + def command_line(cls, command: object) -> str: + """Explicitly set the command line interpreted by the shell.""" + return cls._create("E", command) class REPLHooks: def __init__(self): self.global_exit = None - self.failure_flag = False + self.last_failure_flag = False self.original_excepthook = sys.excepthook self.original_displayhook = sys.displayhook sys.excepthook = self.vscode_excepthook @@ -47,12 +64,12 @@ def __init__(self): def vscode_displayhook(self, value): if value is None: - self.failure_flag = False + self.last_failure_flag = False self.original_displayhook(value) def vscode_excepthook(self, type_, value, traceback): self.global_exit = value - self.failure_flag = True + self.last_failure_flag = True self.original_excepthook(type_, value, traceback) def get_last_command(): @@ -67,44 +84,42 @@ class PS1: # str will get called for every prompt with exit code to show success/failure def __str__(self): - exit_code = _int(_bool(self.hooks.failure_flag)) - self.hooks.failure_flag = False + last_exit_code = _int(_bool(self.hooks.last_failure_flag)) + self.hooks.last_failure_flag = False # Guide following official VS Code doc for shell integration sequence: result = "" # For non-windows allow recent_command history. + # fmt: off if sys.platform != "win32": - result = "{soh}{command_executed}{command_line}{command_finished}{prompt_started}{stx}{prompt}{soh}{command_start}{stx}".format( - soh=ShellIntegrationSequence.SOH, - stx=ShellIntegrationSequence.STX, - command_executed=ShellIntegrationSequence.COMMAND_EXECUTED, - command_line=ShellIntegrationSequence.COMMAND_LINE - + _str(get_last_command()) - + ShellIntegrationSequence.TERMINATOR, - command_finished=ShellIntegrationSequence.COMMAND_FINISHED - + _str(exit_code) - + ShellIntegrationSequence.TERMINATOR, - prompt_started=ShellIntegrationSequence.PROMPT_STARTED, + result = "{soh}{pre_execution}{command_line}{execution_finished}{prompt_start}{stx}{prompt}{soh}{prompt_end}{stx}".format( # noqa: UP032 + soh=ShellIntegrationSequence.soh, + pre_execution=ShellIntegrationSequence.pre_execution(), + command_line=ShellIntegrationSequence.command_line(get_last_command()), + execution_finished=ShellIntegrationSequence.execution_finished(last_exit_code), + prompt_start=ShellIntegrationSequence.prompt_start(), + stx=ShellIntegrationSequence.stx, prompt=original_ps1, - command_start=ShellIntegrationSequence.COMMAND_START, + prompt_end=ShellIntegrationSequence.prompt_end(), ) else: - result = "{command_finished}{prompt_started}{prompt}{command_start}{command_executed}".format( - command_finished=ShellIntegrationSequence.COMMAND_FINISHED - + _str(exit_code) - + ShellIntegrationSequence.TERMINATOR, - prompt_started=ShellIntegrationSequence.PROMPT_STARTED, + result = "{execution_finished}{prompt_start}{prompt}{prompt_end}{pre_execution}".format( # noqa: UP032 + execution_finished=ShellIntegrationSequence.execution_finished(last_exit_code), + prompt_start=ShellIntegrationSequence.prompt_start(), prompt=original_ps1, - command_start=ShellIntegrationSequence.COMMAND_START, - command_executed=ShellIntegrationSequence.COMMAND_EXECUTED, + prompt_end=ShellIntegrationSequence.prompt_end(), + pre_execution=ShellIntegrationSequence.pre_execution(), ) + # fmt: on return result def __repr__(self): return "" - if sys.platform != "win32" and (not is_wsl): - sys.ps1 = PS1() + # if sys.platform != "win32" and (not is_wsl): + # sys.ps1 = PS1() + + sys.ps1 = PS1() ctrl_key = "Cmd" if sys.platform == "darwin" else "Ctrl" From 3468a49dc594f9b32d5c8d7fccd09426e078b1a0 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Mon, 21 Sep 2026 10:18:29 -0700 Subject: [PATCH 02/16] Update escape sequence ordering --- python_files/pythonrc.py | 6 +++--- python_files/tests/test_shell_integration.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/python_files/pythonrc.py b/python_files/pythonrc.py index 189cc69a0830..f4a083a864c0 100644 --- a/python_files/pythonrc.py +++ b/python_files/pythonrc.py @@ -4,7 +4,7 @@ def _initialize(): if sys.platform != "win32": import readline - original_ps1 = sys.ps1 + original_ps1 = getattr(sys, "ps1", ">>> ") # PYTHONSTARTUP executes this file's code inside the user's __main__ # namespace, so PS1.__str__'s globals are the user's globals. If the # user later shadows a name we rely on at prompt-render time (e.g. @@ -91,10 +91,10 @@ def __str__(self): # For non-windows allow recent_command history. # fmt: off if sys.platform != "win32": - result = "{soh}{pre_execution}{command_line}{execution_finished}{prompt_start}{stx}{prompt}{soh}{prompt_end}{stx}".format( # noqa: UP032 + result = "{soh}{command_line}{pre_execution}{execution_finished}{prompt_start}{stx}{prompt}{soh}{prompt_end}{stx}".format( # noqa: UP032 soh=ShellIntegrationSequence.soh, - pre_execution=ShellIntegrationSequence.pre_execution(), command_line=ShellIntegrationSequence.command_line(get_last_command()), + pre_execution=ShellIntegrationSequence.pre_execution(), execution_finished=ShellIntegrationSequence.execution_finished(last_exit_code), prompt_start=ShellIntegrationSequence.prompt_start(), stx=ShellIntegrationSequence.stx, diff --git a/python_files/tests/test_shell_integration.py b/python_files/tests/test_shell_integration.py index ac7fb3d2118d..cb246a201641 100644 --- a/python_files/tests/test_shell_integration.py +++ b/python_files/tests/test_shell_integration.py @@ -28,7 +28,7 @@ def test_decoration_success(): result = str(ps1) assert ( result - == "\x01\x1b]633;C\x07\x1b]633;E;None\x07\x1b]633;D;0\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02" + == "\x01\x1b]633;E;None\x07\x1b]633;C\x07\x1b]633;D;0\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02" ) @@ -40,7 +40,7 @@ def test_decoration_failure(): result = str(ps1) assert ( result - == "\x01\x1b]633;C\x07\x1b]633;E;None\x07\x1b]633;D;1\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02" + == "\x01\x1b]633;E;None\x07\x1b]633;C\x07\x1b]633;D;1\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02" ) @@ -103,7 +103,7 @@ def test_prompt_survives_shadowed_builtins_under_pythonstartup(): result = str(ps1) assert ( result - == "\x01\x1b]633;C\x07\x1b]633;E;None\x07\x1b]633;D;0\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02" + == "\x01\x1b]633;E;None\x07\x1b]633;C\x07\x1b]633;D;0\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02" ) From 127cb34a7295bc93c7782fc2ec42243ef39e24d9 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 22 Sep 2026 14:28:58 -0700 Subject: [PATCH 03/16] Refactor --- python_files/pythonrc.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/python_files/pythonrc.py b/python_files/pythonrc.py index f4a083a864c0..0ae0c93cc39d 100644 --- a/python_files/pythonrc.py +++ b/python_files/pythonrc.py @@ -22,36 +22,32 @@ def _initialize(): class ShellIntegrationSequence: soh = "\001" stx = "\002" - - @staticmethod - def _create(code: str, *arguments: object) -> str: - parameters = "".join(f";{argument}" for argument in arguments) - return f"\x1b]633;{code}{parameters}\x07" + template = "\x1b]633;{}\x07" # Before the prompt (>>>) is displayed @classmethod def prompt_start(cls) -> str: - return cls._create("A") + return cls.template.format("A") # After the prompt (>>>) is displayed @classmethod def prompt_end(cls) -> str: - return cls._create("B") + return cls.template.format("B") # After the user has typed a command but before it is executed @classmethod def pre_execution(cls) -> str: - return cls._create("C") + return cls.template.format("C") @classmethod def execution_finished(cls, exit_code: int) -> str: """Mark execution as finished with its exit code.""" - return cls._create("D", exit_code) + return cls.template.format(f"D;{exit_code}") @classmethod def command_line(cls, command: object) -> str: """Explicitly set the command line interpreted by the shell.""" - return cls._create("E", command) + return cls.template.format(f"E;{command}") class REPLHooks: def __init__(self): From 63df5536321899319ba9f6b606038d9555bb3259 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 29 Sep 2026 15:17:37 -0700 Subject: [PATCH 04/16] Update REGEX --- python_files/pythonrc.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/python_files/pythonrc.py b/python_files/pythonrc.py index 0ae0c93cc39d..4b39bca06bfd 100644 --- a/python_files/pythonrc.py +++ b/python_files/pythonrc.py @@ -1,9 +1,16 @@ def _initialize(): + import re import sys + import _pyrepl.utils if sys.platform != "win32": import readline + # Override regex to support OSC codes + _pyrepl.utils.ANSI_ESCAPE_SEQUENCE = re.compile( + r"\x1b(?:\[[ -@]*[A-~]|\][^\x1b\x07]*(?:\x07|\x1b\\))" + ) + original_ps1 = getattr(sys, "ps1", ">>> ") # PYTHONSTARTUP executes this file's code inside the user's __main__ # namespace, so PS1.__str__'s globals are the user's globals. If the From 71cd3e7ae3507e2de32ccd6a33ffcb1e27c09211 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 29 Sep 2026 15:22:25 -0700 Subject: [PATCH 05/16] Reset osc order --- python_files/pythonrc.py | 4 ++-- python_files/tests/test_shell_integration.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/python_files/pythonrc.py b/python_files/pythonrc.py index 4b39bca06bfd..334bcbc7ab79 100644 --- a/python_files/pythonrc.py +++ b/python_files/pythonrc.py @@ -94,10 +94,10 @@ def __str__(self): # For non-windows allow recent_command history. # fmt: off if sys.platform != "win32": - result = "{soh}{command_line}{pre_execution}{execution_finished}{prompt_start}{stx}{prompt}{soh}{prompt_end}{stx}".format( # noqa: UP032 + result = "{soh}{pre_execution}{command_line}{execution_finished}{prompt_start}{stx}{prompt}{soh}{prompt_end}{stx}".format( # noqa: UP032 soh=ShellIntegrationSequence.soh, - command_line=ShellIntegrationSequence.command_line(get_last_command()), pre_execution=ShellIntegrationSequence.pre_execution(), + command_line=ShellIntegrationSequence.command_line(get_last_command()), execution_finished=ShellIntegrationSequence.execution_finished(last_exit_code), prompt_start=ShellIntegrationSequence.prompt_start(), stx=ShellIntegrationSequence.stx, diff --git a/python_files/tests/test_shell_integration.py b/python_files/tests/test_shell_integration.py index cb246a201641..ac7fb3d2118d 100644 --- a/python_files/tests/test_shell_integration.py +++ b/python_files/tests/test_shell_integration.py @@ -28,7 +28,7 @@ def test_decoration_success(): result = str(ps1) assert ( result - == "\x01\x1b]633;E;None\x07\x1b]633;C\x07\x1b]633;D;0\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02" + == "\x01\x1b]633;C\x07\x1b]633;E;None\x07\x1b]633;D;0\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02" ) @@ -40,7 +40,7 @@ def test_decoration_failure(): result = str(ps1) assert ( result - == "\x01\x1b]633;E;None\x07\x1b]633;C\x07\x1b]633;D;1\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02" + == "\x01\x1b]633;C\x07\x1b]633;E;None\x07\x1b]633;D;1\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02" ) @@ -103,7 +103,7 @@ def test_prompt_survives_shadowed_builtins_under_pythonstartup(): result = str(ps1) assert ( result - == "\x01\x1b]633;E;None\x07\x1b]633;C\x07\x1b]633;D;0\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02" + == "\x01\x1b]633;C\x07\x1b]633;E;None\x07\x1b]633;D;0\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02" ) From 7a94609bc5aaadb03ff70fdcdb3a3043c947f1ba Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 29 Sep 2026 15:23:33 -0700 Subject: [PATCH 06/16] Enable everywhere --- python_files/pythonrc.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/python_files/pythonrc.py b/python_files/pythonrc.py index 334bcbc7ab79..98feb6d3cee6 100644 --- a/python_files/pythonrc.py +++ b/python_files/pythonrc.py @@ -119,9 +119,6 @@ def __str__(self): def __repr__(self): return "" - # if sys.platform != "win32" and (not is_wsl): - # sys.ps1 = PS1() - sys.ps1 = PS1() ctrl_key = "Cmd" if sys.platform == "darwin" else "Ctrl" From 05e83658a3142b6a143ce08d757641b44c01e54c Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 29 Sep 2026 15:31:30 -0700 Subject: [PATCH 07/16] Import _pyrepl conditionally Import _pyrepl conditionally Import _pyrepl conditionally --- python_files/pythonrc.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/python_files/pythonrc.py b/python_files/pythonrc.py index 98feb6d3cee6..b0c7a8d31695 100644 --- a/python_files/pythonrc.py +++ b/python_files/pythonrc.py @@ -1,15 +1,16 @@ def _initialize(): import re import sys - import _pyrepl.utils if sys.platform != "win32": import readline - # Override regex to support OSC codes - _pyrepl.utils.ANSI_ESCAPE_SEQUENCE = re.compile( - r"\x1b(?:\[[ -@]*[A-~]|\][^\x1b\x07]*(?:\x07|\x1b\\))" - ) + # Override regex to support OSC codes (if >= 3.13) + if sys.version_info.major >= 3 and sys.version_info.minor >= 3.13: + import _pyrepl + _pyrepl.utils.ANSI_ESCAPE_SEQUENCE = re.compile( + r"\x1b(?:\[[ -@]*[A-~]|\][^\x1b\x07]*(?:\x07|\x1b\\))" + ) original_ps1 = getattr(sys, "ps1", ">>> ") # PYTHONSTARTUP executes this file's code inside the user's __main__ From 390dcb59e40713faef4798c453cb73c2c182f6f8 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 29 Sep 2026 16:23:09 -0700 Subject: [PATCH 08/16] Fix version comparison --- python_files/pythonrc.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/python_files/pythonrc.py b/python_files/pythonrc.py index b0c7a8d31695..e1099726055a 100644 --- a/python_files/pythonrc.py +++ b/python_files/pythonrc.py @@ -1,13 +1,14 @@ def _initialize(): - import re import sys if sys.platform != "win32": import readline - # Override regex to support OSC codes (if >= 3.13) - if sys.version_info.major >= 3 and sys.version_info.minor >= 3.13: - import _pyrepl + # Override regex to support OSC codes + if sys.version_info >= (3, 13): + import re + import _pyrepl.utils + _pyrepl.utils.ANSI_ESCAPE_SEQUENCE = re.compile( r"\x1b(?:\[[ -@]*[A-~]|\][^\x1b\x07]*(?:\x07|\x1b\\))" ) From 2380c7163b3658e24a97b6a66ec31a2c309b757c Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 29 Sep 2026 16:27:30 -0700 Subject: [PATCH 09/16] Fix tests --- python_files/pythonrc.py | 2 +- python_files/tests/test_shell_integration.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/python_files/pythonrc.py b/python_files/pythonrc.py index e1099726055a..ab5ffb76733d 100644 --- a/python_files/pythonrc.py +++ b/python_files/pythonrc.py @@ -13,7 +13,7 @@ def _initialize(): r"\x1b(?:\[[ -@]*[A-~]|\][^\x1b\x07]*(?:\x07|\x1b\\))" ) - original_ps1 = getattr(sys, "ps1", ">>> ") + original_ps1 = ">>> " # PYTHONSTARTUP executes this file's code inside the user's __main__ # namespace, so PS1.__str__'s globals are the user's globals. If the # user later shadows a name we rely on at prompt-render time (e.g. diff --git a/python_files/tests/test_shell_integration.py b/python_files/tests/test_shell_integration.py index ac7fb3d2118d..4ad8404778cd 100644 --- a/python_files/tests/test_shell_integration.py +++ b/python_files/tests/test_shell_integration.py @@ -13,7 +13,7 @@ class _Hooks(Protocol): - failure_flag: bool + last_failure_flag: bool class _PS1(Protocol): @@ -24,7 +24,7 @@ def test_decoration_success(): importlib.reload(pythonrc) if sys.platform != "win32" and (not is_wsl): ps1 = cast("_PS1", sys.ps1) - ps1.hooks.failure_flag = False + ps1.hooks.last_failure_flag = False result = str(ps1) assert ( result @@ -36,7 +36,7 @@ def test_decoration_failure(): importlib.reload(pythonrc) if sys.platform != "win32" and (not is_wsl): ps1 = cast("_PS1", sys.ps1) - ps1.hooks.failure_flag = True + ps1.hooks.last_failure_flag = True result = str(ps1) assert ( result From 7245990d96cc614b267b8fae9584f90d2a0d64fa Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 29 Sep 2026 16:30:17 -0700 Subject: [PATCH 10/16] Isort organize imports --- python_files/pythonrc.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python_files/pythonrc.py b/python_files/pythonrc.py index ab5ffb76733d..ebea9011f274 100644 --- a/python_files/pythonrc.py +++ b/python_files/pythonrc.py @@ -7,6 +7,7 @@ def _initialize(): # Override regex to support OSC codes if sys.version_info >= (3, 13): import re + import _pyrepl.utils _pyrepl.utils.ANSI_ESCAPE_SEQUENCE = re.compile( From 95bacdd495996e88da9120582648f4761231d7d3 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 29 Sep 2026 16:35:50 -0700 Subject: [PATCH 11/16] Add _str back --- python_files/pythonrc.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python_files/pythonrc.py b/python_files/pythonrc.py index ebea9011f274..ec8496df0a0f 100644 --- a/python_files/pythonrc.py +++ b/python_files/pythonrc.py @@ -27,6 +27,7 @@ def _initialize(): # user code to reassign and break in the first place. _int = int _bool = bool + _str = str # https://code.visualstudio.com/docs/terminal/shell-integration#_supported-escape-sequences class ShellIntegrationSequence: From d35f54935f294bb7612cb6d039bcb6e4e784af05 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 29 Sep 2026 16:59:08 -0700 Subject: [PATCH 12/16] Update condition --- python_files/pythonrc.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/python_files/pythonrc.py b/python_files/pythonrc.py index ec8496df0a0f..e30b17d95072 100644 --- a/python_files/pythonrc.py +++ b/python_files/pythonrc.py @@ -1,3 +1,7 @@ +from sys import platform +import sys + + def _initialize(): import sys @@ -123,7 +127,9 @@ def __str__(self): def __repr__(self): return "" - sys.ps1 = PS1() + is_wsl = "microsoft-standard-WSL" in platform.release() + if not is_wsl and (sys.platform != "win32" or sys.version_info >= (3, 13)): + sys.ps1 = PS1() ctrl_key = "Cmd" if sys.platform == "darwin" else "Ctrl" From 37fda622c25d951650fed3fa6aab97a5298018ba Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 29 Sep 2026 17:03:57 -0700 Subject: [PATCH 13/16] Improve compatibility check --- python_files/pythonrc.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/python_files/pythonrc.py b/python_files/pythonrc.py index e30b17d95072..1962c92a5d41 100644 --- a/python_files/pythonrc.py +++ b/python_files/pythonrc.py @@ -1,8 +1,5 @@ -from sys import platform -import sys - - def _initialize(): + import platform import sys if sys.platform != "win32": From c16c5dce89e80b6e75ba8dab34506ca4303a517b Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 29 Sep 2026 17:27:17 -0700 Subject: [PATCH 14/16] Update tests --- python_files/tests/test_shell_integration.py | 83 ++++++++++++++------ 1 file changed, 59 insertions(+), 24 deletions(-) diff --git a/python_files/tests/test_shell_integration.py b/python_files/tests/test_shell_integration.py index 4ad8404778cd..985bdc9c2c72 100644 --- a/python_files/tests/test_shell_integration.py +++ b/python_files/tests/test_shell_integration.py @@ -5,9 +5,14 @@ from typing import Any, Protocol, cast from unittest.mock import Mock +import pytest + import pythonrc is_wsl = "microsoft-standard-WSL" in platform.release() +prompt_is_installed = not is_wsl and ( + sys.platform != "win32" or sys.version_info >= (3, 13) +) PYTHONRC_PATH = Path(pythonrc.__file__) @@ -20,28 +25,34 @@ class _PS1(Protocol): hooks: _Hooks +def _expected_prompt(exit_code: int) -> str: + if sys.platform == "win32": + return ( + f"\x1b]633;D;{exit_code}\x07\x1b]633;A\x07>>> " + "\x1b]633;B\x07\x1b]633;C\x07" + ) + return ( + "\x01\x1b]633;C\x07\x1b]633;E;None\x07" + f"\x1b]633;D;{exit_code}\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02" + ) + + +@pytest.mark.skipif(not prompt_is_installed, reason="Shell integration prompt is not installed") def test_decoration_success(): importlib.reload(pythonrc) - if sys.platform != "win32" and (not is_wsl): - ps1 = cast("_PS1", sys.ps1) - ps1.hooks.last_failure_flag = False - result = str(ps1) - assert ( - result - == "\x01\x1b]633;C\x07\x1b]633;E;None\x07\x1b]633;D;0\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02" - ) + ps1 = cast("_PS1", sys.ps1) + ps1.hooks.last_failure_flag = False + assert str(ps1) == _expected_prompt(0) + +@pytest.mark.skipif(not prompt_is_installed, reason="Shell integration prompt is not installed") def test_decoration_failure(): importlib.reload(pythonrc) - if sys.platform != "win32" and (not is_wsl): - ps1 = cast("_PS1", sys.ps1) - ps1.hooks.last_failure_flag = True - result = str(ps1) - assert ( - result - == "\x01\x1b]633;C\x07\x1b]633;E;None\x07\x1b]633;D;1\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02" - ) + ps1 = cast("_PS1", sys.ps1) + ps1.hooks.last_failure_flag = True + + assert str(ps1) == _expected_prompt(1) def test_displayhook_call(): @@ -73,6 +84,37 @@ def test_does_not_pollute_namespace(): assert not [name for name in vars(pythonrc) if not name.startswith("__")] +@pytest.mark.skipif(sys.version_info < (3, 13), reason="_pyrepl requires Python 3.13+") +def test_replacement_regex_removes_bel_terminated_osc(): + pyrepl_utils = importlib.import_module("_pyrepl.utils") + importlib.reload(pythonrc) + + assert pyrepl_utils.ANSI_ESCAPE_SEQUENCE.sub("", "before\x1b]633;A\x07after") == ( + "beforeafter" + ) + + +@pytest.mark.skipif(sys.version_info < (3, 13), reason="_pyrepl requires Python 3.13+") +def test_replacement_regex_removes_st_terminated_osc(): + pyrepl_utils = importlib.import_module("_pyrepl.utils") + importlib.reload(pythonrc) + + assert pyrepl_utils.ANSI_ESCAPE_SEQUENCE.sub("", "before\x1b]633;A\x1b\\after") == ( + "beforeafter" + ) + + +@pytest.mark.skipif(sys.version_info < (3, 13), reason="_pyrepl requires Python 3.13+") +def test_replacement_regex_preserves_csi_handling(): + pyrepl_utils = importlib.import_module("_pyrepl.utils") + importlib.reload(pythonrc) + + assert pyrepl_utils.ANSI_ESCAPE_SEQUENCE.sub("", "before\x1b[31mred\x1b[0mafter") == ( + "beforeredafter" + ) + + +@pytest.mark.skipif(not prompt_is_installed, reason="Shell integration prompt is not installed") def test_prompt_survives_shadowed_builtins_under_pythonstartup(): # PYTHONSTARTUP executes pythonrc's source directly inside the real # REPL's __main__ namespace, not as an imported module. The tests @@ -81,9 +123,6 @@ def test_prompt_survives_shadowed_builtins_under_pythonstartup(): # the real PYTHONSTARTUP path by exec-ing the source into a synthetic # __main__-like namespace, then shadow the names PS1 relies on at # prompt-render time and confirm rendering the prompt still works. - if sys.platform == "win32" or is_wsl: - return - source = PYTHONRC_PATH.read_text(encoding="utf-8") namespace: dict[str, Any] = {"__name__": "__main__"} exec(compile(source, str(PYTHONRC_PATH), "exec"), namespace) @@ -100,11 +139,7 @@ def test_prompt_survives_shadowed_builtins_under_pythonstartup(): ) ps1 = cast("_PS1", sys.ps1) - result = str(ps1) - assert ( - result - == "\x01\x1b]633;C\x07\x1b]633;E;None\x07\x1b]633;D;0\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02" - ) + assert str(ps1) == _expected_prompt(0) if sys.platform == "darwin": From f4342645689e6b4ec03731e51f37f46e63b2c484 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 29 Sep 2026 17:27:59 -0700 Subject: [PATCH 15/16] Update tests --- python_files/tests/test_shell_integration.py | 26 ++++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/python_files/tests/test_shell_integration.py b/python_files/tests/test_shell_integration.py index 985bdc9c2c72..f5b5fc5bfeeb 100644 --- a/python_files/tests/test_shell_integration.py +++ b/python_files/tests/test_shell_integration.py @@ -5,8 +5,6 @@ from typing import Any, Protocol, cast from unittest.mock import Mock -import pytest - import pythonrc is_wsl = "microsoft-standard-WSL" in platform.release() @@ -37,18 +35,22 @@ def _expected_prompt(exit_code: int) -> str: ) -@pytest.mark.skipif(not prompt_is_installed, reason="Shell integration prompt is not installed") def test_decoration_success(): importlib.reload(pythonrc) + if not prompt_is_installed: + return + ps1 = cast("_PS1", sys.ps1) ps1.hooks.last_failure_flag = False assert str(ps1) == _expected_prompt(0) -@pytest.mark.skipif(not prompt_is_installed, reason="Shell integration prompt is not installed") def test_decoration_failure(): importlib.reload(pythonrc) + if not prompt_is_installed: + return + ps1 = cast("_PS1", sys.ps1) ps1.hooks.last_failure_flag = True @@ -84,8 +86,10 @@ def test_does_not_pollute_namespace(): assert not [name for name in vars(pythonrc) if not name.startswith("__")] -@pytest.mark.skipif(sys.version_info < (3, 13), reason="_pyrepl requires Python 3.13+") def test_replacement_regex_removes_bel_terminated_osc(): + if sys.version_info < (3, 13): + return + pyrepl_utils = importlib.import_module("_pyrepl.utils") importlib.reload(pythonrc) @@ -94,8 +98,10 @@ def test_replacement_regex_removes_bel_terminated_osc(): ) -@pytest.mark.skipif(sys.version_info < (3, 13), reason="_pyrepl requires Python 3.13+") def test_replacement_regex_removes_st_terminated_osc(): + if sys.version_info < (3, 13): + return + pyrepl_utils = importlib.import_module("_pyrepl.utils") importlib.reload(pythonrc) @@ -104,8 +110,10 @@ def test_replacement_regex_removes_st_terminated_osc(): ) -@pytest.mark.skipif(sys.version_info < (3, 13), reason="_pyrepl requires Python 3.13+") def test_replacement_regex_preserves_csi_handling(): + if sys.version_info < (3, 13): + return + pyrepl_utils = importlib.import_module("_pyrepl.utils") importlib.reload(pythonrc) @@ -114,7 +122,6 @@ def test_replacement_regex_preserves_csi_handling(): ) -@pytest.mark.skipif(not prompt_is_installed, reason="Shell integration prompt is not installed") def test_prompt_survives_shadowed_builtins_under_pythonstartup(): # PYTHONSTARTUP executes pythonrc's source directly inside the real # REPL's __main__ namespace, not as an imported module. The tests @@ -123,6 +130,9 @@ def test_prompt_survives_shadowed_builtins_under_pythonstartup(): # the real PYTHONSTARTUP path by exec-ing the source into a synthetic # __main__-like namespace, then shadow the names PS1 relies on at # prompt-render time and confirm rendering the prompt still works. + if not prompt_is_installed: + return + source = PYTHONRC_PATH.read_text(encoding="utf-8") namespace: dict[str, Any] = {"__name__": "__main__"} exec(compile(source, str(PYTHONRC_PATH), "exec"), namespace) From a84fd31d378dd70387b1849105c52bece14cbd87 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 29 Sep 2026 17:29:09 -0700 Subject: [PATCH 16/16] Update tests --- python_files/tests/test_shell_integration.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/python_files/tests/test_shell_integration.py b/python_files/tests/test_shell_integration.py index f5b5fc5bfeeb..a009380d24b8 100644 --- a/python_files/tests/test_shell_integration.py +++ b/python_files/tests/test_shell_integration.py @@ -8,9 +8,7 @@ import pythonrc is_wsl = "microsoft-standard-WSL" in platform.release() -prompt_is_installed = not is_wsl and ( - sys.platform != "win32" or sys.version_info >= (3, 13) -) +prompt_is_installed = not is_wsl and (sys.platform != "win32" or sys.version_info >= (3, 13)) PYTHONRC_PATH = Path(pythonrc.__file__) @@ -25,10 +23,7 @@ class _PS1(Protocol): def _expected_prompt(exit_code: int) -> str: if sys.platform == "win32": - return ( - f"\x1b]633;D;{exit_code}\x07\x1b]633;A\x07>>> " - "\x1b]633;B\x07\x1b]633;C\x07" - ) + return f"\x1b]633;D;{exit_code}\x07\x1b]633;A\x07>>> \x1b]633;B\x07\x1b]633;C\x07" return ( "\x01\x1b]633;C\x07\x1b]633;E;None\x07" f"\x1b]633;D;{exit_code}\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02" @@ -93,9 +88,7 @@ def test_replacement_regex_removes_bel_terminated_osc(): pyrepl_utils = importlib.import_module("_pyrepl.utils") importlib.reload(pythonrc) - assert pyrepl_utils.ANSI_ESCAPE_SEQUENCE.sub("", "before\x1b]633;A\x07after") == ( - "beforeafter" - ) + assert pyrepl_utils.ANSI_ESCAPE_SEQUENCE.sub("", "before\x1b]633;A\x07after") == ("beforeafter") def test_replacement_regex_removes_st_terminated_osc():