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
IDLE displays ANSI sequences in tracebacks when sys.excepthook is customized #127060
Trigger an error which display a traceback, such as accessing a variable which doesn't exist.
Output
>>> os
Traceback (most recent call last):
File �[35m"/home/vstinner/python/3.13/Lib/idlelib/run.py"�[0m, line �[35m590�[0m, in �[35mruncode�[0m
�[31mexec�[0m�[1;31m(code, self.locals)�[0m
�[31m~~~~�[0m�[1;31m^^^^^^^^^^^^^^^^^^^�[0m
File �[35m"<pyshell#12>"�[0m, line �[35m1�[0m, in �[35m<module>�[0m
�[1;35mNameError�[0m: �[35mname 'os' is not defined. Did you forget to import 'os'?�[0m
ANSI sequences to colorize the output are unexpected and makes the output hard to read.
Expected output
>>> os
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
os
NameError: name 'os' is not defined. Did you forget to import 'os'?
Explanation
In the normal case:
IDLE replaces sys.stderr with io.StringIO() to call the "excepthook".
_colorize.can_colorize() returns False.
It works as expected.
If sys.excepthook is overridden:
IDLE replaces sys.stderr with a idlelib.run.StdOutputFile object at startup.
_colorize.can_colorize() returns True because StdOutputFile.isatty() always return True.
changed the title [-][IDLE] IDLE displays ANSI sequences in tracebacks when sys.excepthook is customized[/-][+]IDLE displays ANSI sequences in tracebacks when sys.excepthook is customized[/+]on Nov 20, 2024
On Windows, 3.14.0a1 install or fresh build, I do not see this when running from editor.
Traceback (most recent call last):
File "f:\dev\3x\Lib\idlelib\run.py", line 590, in runcodeexec(code, self.locals)
~~~~^^^^^^^^^^^^^^^^^^^
File "F:\dev\tem\tem.py", line 4, in <module>
os
NameError: name 'os' is not defined. Did you forget to import 'os'?
After entering at prompt, the only differences are that the file is <pyshell#3> and os is missing. In CommandPrompt, the escape code highlighting (and the OS line) is present.
I do see the code on macOS, so I presume you are using mac or linux.
IDLE normally calls print_exception, which call a function to rid tracebacks of IDLE artifacts. When sys.excepthook is changed from sys.__excepthook__, the custom hook has to do this if desired. hook does not, hence the extra lines.
The absence of interactive code lines, such as os was part of the default sys.__excepthook__ before 3.13. Python does not cache them. IDLE normally adds them and the new REPL does also.
I have thought about converting ~/^ to highlights. Since those lines might eventually go away when duplicated by inline markup, I have recently also thought of using the latter instead. It would be disappointing if that were not available on Windows.
IDLE always replaces the run process stderr with StdOutputfile. Normally, print_exception is called. After printing the traceback created by python while stderr is bound to an StdOutput file, it calls get_message_line to get SomeException: <message line>. For Attribute and Name errors, it temporarily replaces stderr to get the 'Did you mean' hints. (When hints are added for other exception classes, they should be added to the list.) This temporary replacement cannot affect the presence of color codes in the traceback itself.
The sys.stdxxx bindings are visible to user code. Changing an attribute might break the intended behavior of existing code.
I do see the code on macOS, so I presume you are using mac or linux.
Right, I'm on Linux. I expected the behavior to be the same on Windows.
On Fedora, the ABRT service installs a custom sys.excepthook using a PTH file (.pth) to catch Python unhandled exceptions and report them to Bugzilla bug tracker.
I expected the behavior to be the same on Windows.
Oh, I forgot that on Windows Python doesn't use ANSI sequences, but control directly the console using the Windows API. So right, Windows is not affected by this issue.
I will try to test on my Mac tomorrow. And maybe get setup to do so on Ubuntu. (I have it on a partition on Windows, which my daughter used, but have not yet done anything with it myself.) I need to be able to create and download/run PRs on both other systems.
I am a bit worried that changing isatty could break something. I can grep idlelib to check locally, but 3rd party code might be accessing sys.stdxxx.isatty. As I said above, this seems like a public interface.
Besides this, I would like to revise IDLE to recognize the code and add highlights. This would require switching back. Now that Hugh made it (supposedly, not yet tested) possible to request color codes on Windows, I will be more motivated to do so.
A different temporary fix would by to filter out color codes. If I can get them on Windows, I can work on that immediately on my Windows machine. (This would be the first step in using them anyway.) Besides familiarily, my main Windows machine is by far the best ergonomically.
Return True if the stream is interactive (i.e., connected to a terminal/tty device).
To me, this means that one can use s = input("Prompt: ") and expect someone to read the prompt and respond. This is true when connected to IDLE's shell, so I consider the current code to be correct, and hence prefer a different solution.
Since Hugo has started adding color codes to other output (unittest and something else so far), perhaps all stderr output should be filtered, not just Tracebacks. I would not want to filter stdout, as users might want to test sending ansi codes. It might be better to change the environment setting on startup, as long as this only affects IDLE and its subprocesses.
Why not simply set the TERM environment variable to "idle" or whatever? Not all terminals support ANSI sequences, IDLE is the one that does not support.
Later we can implement support of ANSI sequences in IDLE.
Activity
pythongh-127060: IDLE StdOutputFile is no longer a TTY
[-][IDLE] IDLE displays ANSI sequences in tracebacks when sys.excepthook is customized[/-][+]IDLE displays ANSI sequences in tracebacks when sys.excepthook is customized[/+]terryjreedy commentedon Nov 20, 2024
On Windows, 3.14.0a1 install or fresh build, I do not see this when running from editor.
After entering at prompt, the only differences are that the file is
<pyshell#3>andosis missing. In CommandPrompt, the escape code highlighting (and the OS line) is present.I do see the code on macOS, so I presume you are using mac or linux.
IDLE normally calls print_exception, which call a function to rid tracebacks of IDLE artifacts. When
sys.excepthookis changed fromsys.__excepthook__, the custom hook has to do this if desired.hookdoes not, hence the extra lines.The absence of interactive code lines, such as
oswas part of the defaultsys.__excepthook__before 3.13. Python does not cache them. IDLE normally adds them and the new REPL does also.I have thought about converting
~/^to highlights. Since those lines might eventually go away when duplicated by inline markup, I have recently also thought of using the latter instead. It would be disappointing if that were not available on Windows.IDLE always replaces the run process stderr with StdOutputfile. Normally, print_exception is called. After printing the traceback created by python while stderr is bound to an StdOutput file, it calls get_message_line to get
SomeException: <message line>. For Attribute and Name errors, it temporarily replaces stderr to get the 'Did you mean' hints. (When hints are added for other exception classes, they should be added to the list.) This temporary replacement cannot affect the presence of color codes in the traceback itself.The sys.stdxxx bindings are visible to user code. Changing an attribute might break the intended behavior of existing code.
vstinner commentedon Nov 21, 2024
Right, I'm on Linux. I expected the behavior to be the same on Windows.
On Fedora, the ABRT service installs a custom
sys.excepthookusing a PTH file (.pth) to catch Python unhandled exceptions and report them to Bugzilla bug tracker.So this IDLE bug is always reproduced on Fedora without having to install a custom excepthook manually, see: https://bugzilla.redhat.com/show_bug.cgi?id=2325502
vstinner commentedon Nov 21, 2024
Oh, I forgot that on Windows Python doesn't use ANSI sequences, but control directly the console using the Windows API. So right, Windows is not affected by this issue.
vstinner commentedon Nov 25, 2024
What's the purpose of pretending that
sys.stdoutandsys.stderrare TTY, whereas they are not?vstinner commentedon Nov 27, 2024
cc @serhiy-storchaka
vstinner commentedon Dec 16, 2024
@terryjreedy: So you don't like my simple #127061 approach? It does fix the issue for me. Do you have access to Linux or macOS to reproduce the issue?
terryjreedy commentedon Dec 17, 2024
I will try to test on my Mac tomorrow. And maybe get setup to do so on Ubuntu. (I have it on a partition on Windows, which my daughter used, but have not yet done anything with it myself.) I need to be able to create and download/run PRs on both other systems.
terryjreedy commentedon Dec 17, 2024
I am a bit worried that changing isatty could break something. I can grep idlelib to check locally, but 3rd party code might be accessing sys.stdxxx.isatty. As I said above, this seems like a public interface.
Besides this, I would like to revise IDLE to recognize the code and add highlights. This would require switching back. Now that Hugh made it (supposedly, not yet tested) possible to request color codes on Windows, I will be more motivated to do so.
A different temporary fix would by to filter out color codes. If I can get them on Windows, I can work on that immediately on my Windows machine. (This would be the first step in using them anyway.) Besides familiarily, my main Windows machine is by far the best ergonomically.
terryjreedy commentedon Dec 17, 2024
isatty()
To me, this means that one can use
s = input("Prompt: ")and expect someone to read the prompt and respond. This is true when connected to IDLE's shell, so I consider the current code to be correct, and hence prefer a different solution.terryjreedy commentedon Dec 17, 2024
Since Hugo has started adding color codes to other output (unittest and something else so far), perhaps all stderr output should be filtered, not just Tracebacks. I would not want to filter stdout, as users might want to test sending ansi codes. It might be better to change the environment setting on startup, as long as this only affects IDLE and its subprocesses.
serhiy-storchaka commentedon Dec 17, 2024
Why not simply set the TERM environment variable to "idle" or whatever? Not all terminals support ANSI sequences, IDLE is the one that does not support.
Later we can implement support of ANSI sequences in IDLE.
pythongh-127060: Disable traceback colors in IDLE
pythongh-127060: Disable traceback colors in IDLE
vstinner commentedon Dec 17, 2024
Good idea: I wrote PR gh-128028 to fix this issue.
terryjreedy commentedon Dec 18, 2024
TERM is set in pyshell line 427. Should move to init when do other cleanups. Can easily change if needed.
gh-127060: Disable traceback colors in IDLE (#128028)
pythongh-127060: Disable traceback colors in IDLE (pythonGH-128028)
[3.13] gh-127060: Disable traceback colors in IDLE (GH-128028) (#128052)
pythongh-127060: Disable traceback colors in IDLE (python#128028)