pytest-dev / pytest-dev/pytest
KeyboardInterrupt full-trace should have option to ignore pytest frames
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 14.5k
- Forks
- 3.4k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 35
Description
What's the problem this feature will solve?
Currently, pytest is difficult to use when testing bugs that cause your program to hang. By default, interrupting will mark the test as successful and no traceback is shown (related: #7640). So if it hangs you'll need to re-run your tests with the --full-trace flag (which can be annoying if the tests take a while or the problem is not consistently reproducible).
But when you use --full-trace it includes a bunch of frames from internal pytest and related libraries. i.e.:
anaconda3/envs/s/lib/python3.7/site-packages/pluggy/hooks.py
anaconda3/envs/s/lib/python3.7/site-packages/pluggy/manager.py
anaconda3/envs/s/lib/python3.7/site-packages/_pytest/python.py
anaconda3/envs/s/lib/python3.7/site-packages/_pytest/runner.py
... etc.
and makes the output SUUUUUPER LONG (like obscenely).
But 90% of the time, I don't care about all of those frames and it just makes the problem really hard and tedious to parse. I just want the frames related to my application.
I understand that those might be useful for debugging pytest, but I have personally used ctrl-c countless times to debug hanging programs and nearly every time I want to see the trace for my application and nothing else.
(I have also tried --full-trace --tb=native and --full-trace --tb=short with no change in behaviour).
Describe the solution you'd like
I would like a way to tell pytest to enable stack traces for keyboard interrupt, only including the frames that are relevant to my application.
The clearest solution that I can think of would be to add a --ctrlc-trace CLI flag
Basically, I'm suggesting decoupling --full-trace with showing the ctrl-c output because --full-trace has the additional connotation of "show me every possible frame including everything in pytest" which is something I have never wanted.
Alternatives
- Setting a global variable in your
test_something.pyfile (__keyboardinterrupt_trace__ = True) - Setting an attribute in pytest (e.g.
pytest.__keyboardinterrupt_trace__ = True) in yourtest_something.py - Have a list of paths to filter from tracebacks (e.g.
pytest.ignore_stack_trace_matching.append('ignored1', 'ignored2')
Path to a solution
Doing a quick look thru the source, the logic already partially exists
https://github.com/pytest-dev/pytest/blob/483f239d01aad3328360e242ed86b081eecb7608/src/_pytest/_code/code.py#L1246
And maybe it just involves adding another option and checking it here
https://github.com/pytest-dev/pytest/blob/483f239d01aad3328360e242ed86b081eecb7608/src/_pytest/terminal.py#L857
i.e.
if self.config.option.fulltrace or self.config.option.ctrlctrace:
...
since it looks like the full unfiltered trace is being enforced here, so by adding the second option, the kb interrupt output can be shown without being forced to use style == 'long'
(I am not familiar with the pytest source and I didn't do a deep dive so I'm sure I'm missing a thing or two)
Additional context
pytest 6.2.5
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 with src/_pytest/_code/code.py at filter_traceback, then inspect the KeyboardInterrupt handling in src/_pytest/terminal.py and option definitions in src/_pytest/config/init.py. Trace how --full-trace currently affects interrupt output. Done means a separate option can show application-relevant KeyboardInterrupt frames without forcing the full unfiltered pytest trace, with tests covering the new behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli, testing
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100