Repository navigation
Truncate junitxml failure and error message attributes - #15147
Cherith1222 wants to merge 2 commits into
Conversation
Truncate the escaped message attribute of <failure> and <error> elements to 1000 characters plus '...', keeping the full report in the element body. Fixes pytest-dev#12223. Drafted with AI assistance (Cursor); not yet reviewed by the account owner.
|
🤖 Written by Claude Opus 5.5 via Claude Code for the pytest maintainers; I prompted it, it did the work, I read it. Thanks for picking this up. The goal is right: a short Why the current approach falls short
What common failures look like on main. I measured
Suggestion: keep whole lines up to a budget. If anything was dropped, end with a pointer line: _MESSAGE_BUDGET = 300 # or ~500
def _shorten_message(msg: str) -> str:
lines = msg.splitlines() or [""]
kept: list[str] = []
size = 0
for line in lines:
if kept and size + len(line) + 1 > _MESSAGE_BUDGET:
break
kept.append(line)
size += len(line) + 1
out = "\n".join(kept)
cut = len(out) > _MESSAGE_BUDGET
if cut:
out = out[:_MESSAGE_BUDGET] + "..."
rest = len(lines) - len(kept)
if not cut and not rest:
return out
note = f"+{rest} more lines" if rest else "truncated"
return f"{out}\n[{note}; full report in element text]"It would be applied as With a budget of 300, all 16 cases stay byte-identical at On tests: it would be good to cover the line-boundary cut, the hard cut of a single overlong first line, and an unchanged short multiline message (e.g. the Generated by Claude Code |
Keep whole lines of the raw failure and error text up to 500 characters, then escape. When text is dropped, note that the full report is in the element text. AI-assisted (Cursor). Not yet reviewed by a human.
|
The raw message is shortened before I used 500 rather than 300 so a small This revision was drafted with Cursor. A human has not line-reviewed the new diff. |
|
🤖 Written by Claude Opus 5.5 via Claude Code for the pytest maintainers; I prompted it, it did the work, I read it. Closing in favor of #15150. That PR is a clean reimplementation of the line-budget approach for #12223, and its CI is green. Generated by Claude Code |
Summary
--junitxmlwrote the full assertion message into themessageattribute of<failure>and<error>. With-vv, that attribute can be tens of thousands of characters. The attribute is now shortened from the original text, before XML escaping: whole lines are kept up to a 500-character budget. A single line longer than the budget is cut at 500 characters and then escaped, so an escape such as#x1Bis not split. When anything is dropped, the attribute ends with a note that the full report is in the element text. The element body still contains the full longrepr.Fixes #12223.
The commit already includes
changelog/12223.bugfix.rst.AUTHORSwas not changed.Tests
On Windows, Python 3.13.3, in this checkout, via the project virtualenv:
python -m pytest testing/test_junitxml.py -k message_is_truncated -p no:cacheproviderwas 3 passed, 140 deselected, and-k failure_verbose_messagewas 2 passed, 141 deselected.-k TestShortenFailureMessagewas 4 passed;-k message_is_truncatedwas 3 passed;-k failure_message_cuts_on_line_boundarywas 1 passed;-k raises_match_message_is_not_shortenedwas 1 passed;-k failure_verbose_messagewas 2 passed.ruff0.16.9formatandcheckpassed onsrc/_pytest/junitxml.pyandtesting/test_junitxml.py.Not run: the rest of the pytest suite, mypy, and Python 3.11.
AI assistance
Drafted with Cursor. The account owner authorized opening this pull request. A human has not reviewed the diff. There is no
Co-authored-by,Reviewed-by, orSigned-off-bytrailer.Checklist
Fixes #12223to the PR description. The commit message already says the same.changelog/12223.bugfix.rst.AUTHORSwas not updated.Co-authored-bytrailer was not added.