Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IDLE displays ANSI sequences in tracebacks when sys.excepthook is customized #127060

Open
vstinner opened this issue Nov 20, 2024 · 3 comments
Open
Labels
3.13 bugs and security fixes 3.14 new features, bugs and security fixes stdlib Python modules in the Lib dir topic-IDLE type-bug An unexpected behavior, bug, or error

Comments

@vstinner
Copy link
Member

vstinner commented Nov 20, 2024

Error on Python 3.13 and newer.

Reproducer

  • Run IDLE
  • Set a custom sys.excepthook:
import sys
def hook(*args): return sys.__excepthook__(*args)
sys.excepthook=hook
  • 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.

Linked PRs

@vstinner vstinner added topic-IDLE 3.13 bugs and security fixes 3.14 new features, bugs and security fixes labels Nov 20, 2024
vstinner added a commit to vstinner/cpython that referenced this issue Nov 20, 2024
IDLE StdOutputFile.isatty() now returns False instead of True.
@terryjreedy terryjreedy 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 Nov 20, 2024
@terryjreedy
Copy link
Member

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 runcode
    exec(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: . 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.

@picnixz picnixz added type-bug An unexpected behavior, bug, or error stdlib Python modules in the Lib dir labels Nov 21, 2024
@vstinner
Copy link
Member Author

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.

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
Copy link
Member Author

vstinner commented Nov 21, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.13 bugs and security fixes 3.14 new features, bugs and security fixes stdlib Python modules in the Lib dir topic-IDLE type-bug An unexpected behavior, bug, or error
Projects
Status: No status
Development

No branches or pull requests

3 participants