pytest-dev / pytest-dev/pytest
`--tb` affects `longrepr` construction, so plugins cannot suppress traceback display without losing traceback data
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 14.5k
- Forks
- 3.4k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 35
Description
A reporting plugin that wants to render its own compact traceback has to stop pytest printing the standard one. The obvious way is --tb=no. But --tb is consulted when the representation is built, not only when it is displayed, so this also removes the data the plugin wanted to read.
Reproduced on 9.1.1 and 8.4.2.
# test_repro.py
def inner(): raise ValueError("boom")
def middle(): inner()
def test_a(): middle()
# conftest.py
def pytest_runtest_logreport(report):
if report.failed:
rt = getattr(report.longrepr, "reprtraceback", None)
entries = getattr(rt, "reprentries", []) if rt else []
located = [e for e in entries if getattr(e, "reprfileloc", None) is not None]
print(f"entries={len(entries)} located={len(located)} "
f"len(str(longrepr))={len(str(report.longrepr))}")
--tb=long entries=3 located=3 len(str(longrepr))=441
--tb=short entries=3 located=3 len(str(longrepr))=290
--tb=line entries=3 located=0 len(str(longrepr))=20
--tb=no entries=3 located=0 len(str(longrepr))=20
The entry count survives, but reprfileloc is None under line and no, so the file and line of every frame are gone. A plugin reading reprtraceback to build its own summary sees three anonymous entries.
The result is that a plugin must choose between pytest printing a traceback it does not want, and having no traceback data to work with.
We hit this in a reporting plugin and shipped a version that silently lost all frame information: setting --tb=no in pytest_configure looked like a clean way to suppress output, and the summaries kept rendering, just without any of the frames they were supposed to summarise. The workaround is to leave --tb alone and suppress the rendering through some other mechanism, which works, but which mechanism is available is not obvious.
This may well be intentional — not building what will not be shown is a reasonable optimisation. If so, it would be worth documenting, since the flag reads as purely presentational. If not, separating "what representation to build" from "what to display" would let plugins summarise tracebacks without either fighting the terminal reporter or losing the data.
Happy to work on a patch if there is a direction the team would prefer.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the test_repro.py and conftest.py reproduction with each --tb value, focusing on pytest_runtest_logreport and report.longrepr. Trace where reprtraceback and reprentries are built and how the terminal output is rendered. Done should preserve usable frame locations for plugins while retaining the intended traceback display behavior, or document the deliberate limitation and supported workaround.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli, testing
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100