Skip to content

Strip ANSI sequences before writing junitxml text - #15084

Open
00200200 wants to merge 3 commits into
pytest-dev:mainfrom
00200200:fix/junitxml-strip-ansi
Open

00200200 wants to merge 3 commits into
pytest-dev:mainfrom
00200200:fix/junitxml-strip-ansi

Conversation

@00200200

@00200200 00200200 commented Sep 22, 2026

Copy link
Copy Markdown

Problem

Closes #12365. With Pygments installed and color enabled, assertion diffs under -v/-vv embed ANSI SGR sequences into longrepr. Those leak into --junitxml as #x1B[...] fragments and break CI XML consumers.

Fix

Strip SGR escape sequences at the junitxml write boundary (failure/error message and details) before bin_xml_escape. This keeps TerminalRepr untouched for cases where user data intentionally contains escapes (which saferepr already renders as literal \x1b text).

How tested

testing/test_junitxml.py::test_junitxml_strips_ansi_from_failure_details (with pygments, PY_COLORS=1, -vv).

Pygments-highlighted assertion diffs bake SGR codes into the longrepr.
Strip them at the junitxml boundary so CI XML stays parseable without
touching TerminalRepr (which must preserve user data containing escapes).
@00200200
00200200 force-pushed the fix/junitxml-strip-ansi branch from 443cb6c to c636f62 Compare September 22, 2026 21:05
@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided (automation) changelog entry is part of PR label Sep 22, 2026

@ege-arhan ege-arhan left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

_write_content (src/_pytest/junitxml.py:206-208 on head 6229b1e) still writes captured output via bin_xml_escape(content) without strip_ansi_escapes. Repro on pytest 9.1.1: a test printing "\x1b[31mred\x1b[0m" with --junitxml out.xml -o junit_logging=all leaves #x1B[31m...#x1B[0m inside <system-out> (verified by parsing the XML). The new test only covers failure details. Suggestion: apply strip_ansi_escapes(content) in _write_content too, or narrow the changelog if captured output is intentionally left verbatim.

_write_content still wrote captured stdout/stderr verbatim, so colored
output left escape sequences in <system-out>/<system-err>. Also updates
test_escaped_setup_teardown_error, which asserted the old escaped form.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@00200200

Copy link
Copy Markdown
Author

Thanks @ege-arhan, you're right. _write_content now applies strip_ansi_escapes as well, so captured output in <system-out>/<system-err> is cleaned too, and the changelog says so. Added test_ansi_escapes_stripped_from_captured_output (fails without the change, passes with it). The macOS failures came from test_escaped_setup_teardown_error still asserting the old escaped form; it now asserts the stripped text. testing/test_junitxml.py passes locally (143) and pre-commit is clean.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided (automation) changelog entry is part of PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ASCII color chars leaking into xml report file when using verbose flag

2 participants