Skip to content

fix: don't color logged exceptions on non-TTY streams; add IPython support (Closes #87, #10) - #165

Open
18680368135 wants to merge 1 commit into
Qix-:masterfrom
18680368135:fix/logging-color-and-ipython-support
Open

fix: don't color logged exceptions on non-TTY streams; add IPython support (Closes #87, #10)#165
18680368135 wants to merge 1 commit into
Qix-:masterfrom
18680368135:fix/logging-color-and-ipython-support

Conversation

@18680368135

@18680368135 18680368135 commented Jul 29, 2026

Copy link
Copy Markdown

Summary

This PR addresses two issues:

Fix #87: Logged exceptions shouldn't contain colour

Problem: When the terminal supports colors (or FORCE_COLOR=1 is set), exceptions logged through the logging module to non-TTY streams (e.g. files, pipes) would contain ANSI escape codes, making them hard to read in editors and log viewers.

Solution: Introduced _stream_supports_color(stream) which checks both the global SUPPORTS_COLOR flag and whether the specific output stream is a TTY. FORCE_COLOR=1 still acts as an explicit override that enables color on all streams (for users who explicitly want colored logs).

Changes to better_exceptions/log.py:

  • Added _stream_supports_color(stream) function that checks FORCE_COLOR, SUPPORTS_COLOR, and the stream's TTY status
  • Modified _make_logging_format_exception() to accept a stream parameter and use _stream_supports_color() at call time
  • Updated patch() to pass the handler's stream to _make_logging_format_exception()

Fix #10: ipython support

Problem: better_exceptions had no integration with IPython/Jupyter notebooks.

Solution: Added better_exceptions.integrations.ipython.install() which hooks into IPython's set_custom_exc API to replace the default traceback formatter with better_exceptions' formatter.

Features:

  • Registers a custom exception handler for all BaseException subclasses
  • SyntaxError is delegated to IPython's built-in handler (IPython has special formatting for syntax errors)
  • Raises clear errors when IPython is not installed or no active shell is found

Usage:

from better_exceptions.integrations.ipython import install
install()

Changes

  • better_exceptions/log.py: Added _stream_supports_color() and modified _make_logging_format_exception() to accept stream parameter
  • better_exceptions/integrations/ipython.py: New file implementing IPython integration via set_custom_exc
  • test/test_logging_color.py: New test file with 5 test cases for issue Logged exceptions shouldn't contain colour #87
  • test/test_ipython_integration.py: New test file with 5 test cases for issue ipython support #10
  • test_all.sh: Added both new test files to the test suite
  • test/output/*.out: Regenerated expected output files for all 12 test configurations
  • README.md: Added IPython/Jupyter usage section

Testing

All tests pass locally across all 12 configurations (xterm/vt100/dumb × ascii/UTF-8 × color/nocolor):

$ ./test_all.sh
# All 12 test configurations pass with no diffs

New test files:

  • test/test_logging_color.py: Tests non-TTY stream color handling, FORCE_COLOR override, file handler output
  • test/test_ipython_integration.py: Tests import, no active shell, mock shell registration, handler formatting, SyntaxError delegation

Checklist

  • Relevant modules affected by these changes build locally
  • Tests pass locally (./test_all.sh passes all 12 configurations)
  • Documentation has been updated (README.md updated with IPython usage section)
  • No generated build artifacts are committed
  • Changes are scoped to the PR purpose and avoid unrelated cleanup
  • Security, privacy, and error-handling implications have been considered

Closes #87, #10

Previously, the logging integration used the global SUPPORTS_COLOR flag
to decide whether to add ANSI color codes. This meant that if the terminal
supported colors (or FORCE_COLOR=1 was set), exceptions logged to files
or other non-TTY streams would contain escape sequences.

This change introduces _stream_supports_color(stream) which checks both
the global color support flag AND whether the specific output stream is a
TTY. FORCE_COLOR=1 still acts as an explicit override that enables color
on all streams.

Fix Qix-#10: Add IPython/Jupyter support

Add better_exceptions.integrations.ipython.install() which hooks into
IPython's set_custom_exc API to replace the default traceback formatter
with better_exceptions' formatter. SyntaxErrors are delegated to
IPython's built-in handler since IPython has special formatting for them.

Usage:
    from better_exceptions.integrations.ipython import install
    install()

Tests:
- test/test_logging_color.py: Tests for issue Qix-#87
- test/test_ipython_integration.py: Tests for issue Qix-#10
- Updated test_all.sh and regenerated expected output files
@18680368135 18680368135 changed the title Fix #87: Don't color logged exceptions on non-TTY streams + Fix #10: Add IPython support fix: don't color logged exceptions on non-TTY streams; add IPython support (Closes #87, #10) Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Logged exceptions shouldn't contain colour ipython support

1 participant