A run that dies during collection¶
pytest 7.1.0 - 7.3.1 - What pytest does when a hook implementation raises.
These 9 releases produced an identical flow, so they share one page. Identical as far as this scenario can measure - a scenario exercising more hooks may tell them apart.
The conftest.py here raises from pytest_collection_modifyitems. Nothing
catches it, so pytest abandons the session and reports an internal error.
No test ever runs, so the whole run-test phase is missing from this diagram - which is the point. It shows how little of a session happens when a hook implementation fails early, and which hooks still get their chance to clean up.
How this was produced¶
- Source:
scenarios/internal-error/- the project this diagram was traced from - Invocation:
pytest -p hook_atlas_pytest . -q - Traced against: pytest 7.3.1, pluggy 1.6.0, Python 3.9.25
- Covers: 9 releases - pytest 7.1.0 - 7.3.1, which produced an identical flow
- Observed: 118 hook calls, 22 distinct hooks
The project is conftest.py, test_never_runs.py. Browse it in the repository rather than inline here - scenarios grow directory trees, and GitHub renders them better than a collapsed block can.
The whole run¶
Phases left to right, steps top to bottom. Colour says which phase a hook belongs to; how dark a step is says how often it was called. Click a column heading to jump to that phase in full detail, or any hook to open its pytest documentation. Why it looks like this
Startup and configuration¶
Everything before collection begins: initial conftests are loaded, plugins register, and the session is configured.
Collection¶
Finding tests. Note that pytest_make_collect_report recurses - directories contain directories contain files.
Session finish¶
Summary reporting and teardown of the session.
Every hook observed¶
| Hook | Calls | Semantics | Implemented by, in call order |
|---|---|---|---|
pytest_cmdline_main |
1 | firstresult | _pytest.setupplan [tryfirst]_pytest.setuponly [tryfirst]_pytest.mark [tryfirst]_pytest.python_pytest.helpconfig_pytest.main |
pytest_cmdline_preparse |
1 | - | |
pytest_collect_file |
5 | _pytest.doctest_pytest.python |
|
pytest_collection |
1 | firstresult | _pytest.logging.LoggingPlugin (logging-plugin) [hookwrapper, tryfirst]_pytest.warnings [hookwrapper, tryfirst]_pytest.config.Config (pytestconfig) [hookwrapper]_pytest.terminal.TerminalReporter_pytest.assertion_pytest.main |
pytest_collection_finish |
1 | _pytest.terminal.TerminalReporter |
|
pytest_collection_modifyitems |
1 | _pytest.fixtures.FixtureManager (funcmanage)conftest.py_pytest.main_pytest.mark |
|
pytest_collectreport |
2 | _pytest.main.Session.pytest_runtest_logreport (session) [tryfirst]_pytest.terminal.TerminalReporter |
|
pytest_collectstart |
2 | _pytest.main.Session [tryfirst] |
|
pytest_configure |
1 | historic | _pytest.faulthandler_pytest.warnings_pytest.junitxml_pytest.tmpdir_pytest.legacypath_pytest.skipping_pytest.debugging_pytest.terminal_pytest.python_pytest.mark_pytest.config.PytestPluginManager (<anonymous>)_pytest.pastebin [trylast]_pytest.logging [trylast] |
pytest_generate_tests |
1 | _pytest.fixtures.FixtureManager (funcmanage)_pytest.python |
|
pytest_ignore_collect |
5 | firstresult | _pytest.main |
pytest_internalerror |
1 | _pytest.capture.CaptureManager [tryfirst]_pytest.terminal.TerminalReporter |
|
pytest_itemcollected |
1 | - | |
pytest_load_initial_conftests |
1 | _pytest.warnings [hookwrapper]_pytest.capture [hookwrapper]_pytest.python_path [tryfirst]_pytest.legacypath [tryfirst]_pytest.config.Config (pytestconfig) [trylast] |
|
pytest_make_collect_report |
2 | firstresult | _pytest.capture.CaptureManager [hookwrapper]_pytest.runner |
pytest_plugin_registered |
84 | historic | _pytest.legacypath_pytest.terminal.TerminalReporter_pytest.fixtures.FixtureManager (funcmanage) |
pytest_pycollect_makeitem |
3 | firstresult | _pytest.unittest_pytest.python [trylast] |
pytest_pycollect_makemodule |
1 | firstresult | _pytest.python |
pytest_report_collectionfinish |
1 | - | |
pytest_sessionfinish |
1 | _pytest.logging.LoggingPlugin (logging-plugin) [hookwrapper, tryfirst]_pytest.terminal.TerminalReporter [hookwrapper]_pytest.warnings [hookwrapper]_pytest.assertion_pytest.tmpdir_pytest.runner1 |
|
pytest_sessionstart |
1 | _pytest.logging.LoggingPlugin (logging-plugin) [hookwrapper, tryfirst]_pytest.fixtures_pytest.runner_pytest.terminal.TerminalReporter [trylast] |
|
pytest_unconfigure |
1 | _pytest.logging.LoggingPlugin (logging-plugin)_pytest.terminal.TerminalReporter_pytest.faulthandler_pytest.doctest_pytest.junitxml_pytest.pastebin_pytest.mark_pytest.python_path [trylast] |
1 of these changed implementer somewhere in pytest 7.1.0 - 7.3.1 without changing the flow - pytest moves implementations between its own plugins. The table shows the newest; what changed along the way is below.
-
7.3.0 gained
_pytest.tmpdir↩