Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 78 additions & 80 deletions python_files/pythonrc.py
Original file line number Diff line number Diff line change
@@ -1,85 +1,83 @@
import platform
import sys
def setup():
import platform
import sys

if sys.platform != "win32":
import readline

original_ps1 = ">>> "
is_wsl = "microsoft-standard-WSL" in platform.release()


class REPLHooks:
def __init__(self):
self.global_exit = None
self.failure_flag = False
self.original_excepthook = sys.excepthook
self.original_displayhook = sys.displayhook
sys.excepthook = self.my_excepthook
sys.displayhook = self.my_displayhook

def my_displayhook(self, value):
if value is None:
self.failure_flag = False

self.original_displayhook(value)

def my_excepthook(self, type_, value, traceback):
self.global_exit = value
self.failure_flag = True

self.original_excepthook(type_, value, traceback)


def get_last_command():
# Get the last history item
last_command = ""
if sys.platform != "win32":
last_command = readline.get_history_item(readline.get_current_history_length())

return last_command

import readline

class PS1:
hooks = REPLHooks()
sys.excepthook = hooks.my_excepthook
sys.displayhook = hooks.my_displayhook
original_ps1 = ">>> "
is_wsl = "microsoft-standard-WSL" in platform.release()

# 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
# Guide following official VS Code doc for shell integration sequence:
result = ""
# For non-windows allow recent_command history.
class REPLHooks:
def __init__(self):
self.global_exit = None
self.failure_flag = False
self.original_excepthook = sys.excepthook
self.original_displayhook = sys.displayhook
sys.excepthook = self.my_excepthook
sys.displayhook = self.my_displayhook

def my_displayhook(self, value):
if value is None:
self.failure_flag = False
self.original_displayhook(value)

def my_excepthook(self, type_, value, traceback):
self.global_exit = value
self.failure_flag = True
self.original_excepthook(type_, value, traceback)

def get_last_command():
# Get the last history item
last_command = ""
if sys.platform != "win32":
result = "{soh}{command_executed}{command_line}{command_finished}{prompt_started}{stx}{prompt}{soh}{command_start}{stx}".format(
soh="\001",
stx="\002",
command_executed="\x1b]633;C\x07",
command_line="\x1b]633;E;" + str(get_last_command()) + "\x07",
command_finished="\x1b]633;D;" + str(exit_code) + "\x07",
prompt_started="\x1b]633;A\x07",
prompt=original_ps1,
command_start="\x1b]633;B\x07",
)
else:
result = "{command_finished}{prompt_started}{prompt}{command_start}{command_executed}".format(
command_finished="\x1b]633;D;" + str(exit_code) + "\x07",
prompt_started="\x1b]633;A\x07",
prompt=original_ps1,
command_start="\x1b]633;B\x07",
command_executed="\x1b]633;C\x07",
)

# result = f"{chr(27)}]633;D;{exit_code}{chr(7)}{chr(27)}]633;A{chr(7)}{original_ps1}{chr(27)}]633;B{chr(7)}{chr(27)}]633;C{chr(7)}"

return result


if sys.platform != "win32" and (not is_wsl):
sys.ps1 = PS1()

if sys.platform == "darwin":
print("Cmd click to launch VS Code Native REPL")
else:
print("Ctrl click to launch VS Code Native REPL")
last_command = readline.get_history_item(readline.get_current_history_length())
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

The readline module is conditionally imported inside setup() on line 6, but it's used by get_last_command() on line 34. When PS1.str() calls get_last_command() after setup() completes, readline will not be in scope, resulting in a NameError. The import needs to be accessible to the persistent get_last_command() function.

Copilot uses AI. Check for mistakes.
return last_command
Comment on lines +30 to +35
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

The get_last_command() function is defined as a nested function inside setup() and will not be accessible when called by PS1.str() on line 54 after setup() completes. Since PS1 instances persist beyond the setup() call, this will result in a NameError when the PS1 prompt tries to format the command line. The function needs to be defined at a scope that remains accessible to the PS1 instance.

Copilot uses AI. Check for mistakes.

class PS1:
hooks = REPLHooks()
sys.excepthook = hooks.my_excepthook
sys.displayhook = hooks.my_displayhook

# 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
# Guide following official VS Code doc for shell integration sequence:
result = ""
# For non-windows allow recent_command history.
if sys.platform != "win32":
result = "{soh}{command_executed}{command_line}{command_finished}{prompt_started}{stx}{prompt}{soh}{command_start}{stx}".format(
soh="\001",
stx="\002",
command_executed="\x1b]633;C\x07",
command_line="\x1b]633;E;" + str(get_last_command()) + "\x07",
command_finished="\x1b]633;D;" + str(exit_code) + "\x07",
prompt_started="\x1b]633;A\x07",
prompt=original_ps1,
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

The variable original_ps1 is used by the PS1.str() method on lines 57 and 64, but it's defined as a local variable in setup() on line 8. After setup() completes, this will cause a NameError when PS1 tries to format the prompt. The variable needs to be accessible to PS1 instances that persist beyond the setup() call.

Copilot uses AI. Check for mistakes.
command_start="\x1b]633;B\x07",
)
else:
result = "{command_finished}{prompt_started}{prompt}{command_start}{command_executed}".format(
command_finished="\x1b]633;D;" + str(exit_code) + "\x07",
prompt_started="\x1b]633;A\x07",
prompt=original_ps1,
command_start="\x1b]633;B\x07",
command_executed="\x1b]633;C\x07",
)

# result = f"{chr(27)}]633;D;{exit_code}{chr(7)}{chr(27)}]633;A{chr(7)}{original_ps1}{chr(27)}]633;B{chr(7)}{chr(27)}]633;C{chr(7)}"

return result

if sys.platform != "win32" and (not is_wsl):
sys.ps1 = PS1()

if sys.platform == "darwin":
print("Cmd click to launch VS Code Native REPL")
else:
print("Ctrl click to launch VS Code Native REPL")


setup()
del setup
Comment on lines +1 to +83
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

After wrapping all code in the setup() function and deleting it, the classes PS1 and REPLHooks will no longer be accessible as module-level attributes. This breaks the existing test suite which references pythonrc.PS1() and pythonrc.REPLHooks() in test_shell_integration.py. These classes need to remain accessible at module level for the tests to work.

Copilot uses AI. Check for mistakes.