# pytest: what changed from 8 to 9 - Product: pytest (https://whatsnew.fyi/product/pytest) - Vendor: pytest - Range: changelog entries numbered after 8.4.2 up to and including 9.1.1, stable releases only - Entries below: 6 releases (newest first) - Resolved: 8 is 8.4.2 and 9 is 9.1.1, the newest stable release of each major we track - Carrying security changes: 1 · CVEs mentioned: 1 · Mentioning breaking changes: 2 · Removing or deprecating something: 1 - Page: https://whatsnew.fyi/product/pytest/compare/8...9 What's New is an index, not a publisher: every entry below links to the vendor's own release notes, which are the authoritative source. Entries are labelled where they are hand-curated sample data, pre-releases, or drawn from a secondary source such as a developer blog. Reuse: the summaries, labels and curation here are © What's New. Quote freely with attribution and a link back; wholesale republication of the corpus is not permitted — terms: https://whatsnew.fyi/terms. The vendors' own release notes remain their publishers'. ## What changed (44 changes, grouped by kind) ### Added #### 9.1.0 (2026-06-13) - Added pytest.register_fixture() to register fixtures using an imperative interface - Added --report-chars long CLI option - Added --max-warnings command-line option and max_warnings configuration option to fail the test run when the number of warnings exceeds a given threshold - Added the assertion_text_diff_style configuration option for rendering string equality failures as separate Left: and Right: blocks instead of ndiff output - Added support for datetime and timedelta comparisons with pytest.approx #### 9.0.0 (2025-11-08) - Support for subtests has been added as an alternative to parametrization, useful when parametrization values are not all known at collection time - Added support for native TOML configuration files in pyproject.toml under the [tool.pytest] table, as well as pytest.toml or .pytest.toml files - Added a strict mode enabled by the strict configuration option that enables strict_config, strict_markers, strict_parametrization_ids, and strict_xfail - Added the strict_parametrization_ids configuration option to emit an error if non-unique parameter set IDs are detected - Added support for displaying test session progress in the terminal tab using the OSC 9;4; ANSI sequence - Support PEP420 implicit namespace packages as --pyargs target when consider_namespace_packages is true in the config - Added a new faulthandler_exit_on_timeout configuration option set to false by default to let faulthandler interrupt the pytest process after a timeout in case of deadlock - Added support for configuration option aliases via the aliases parameter in Parser.addini() ### Changed #### 9.1.0 (2026-06-13) - pytest.warns now shows "Regex pattern did not match" instead of "DID NOT WARN" when warnings were emitted but the match pattern did not match - Improved output of --fixtures-per-test by excluding internal-implementation fixtures generated by @pytest.mark.parametrize and similar #### 9.0.0 (2025-11-08) - The previously-deprecated --strict command-line flag now enables strict mode - unittest.TestCase.subTest is now also supported ### Fixed #### 9.1.1 (2026-06-19) - Fixed a logic bug in pytest.RaisesGroup which would cause it to display incorrect error pairing messages - Fixed a regression in pytest 9.1.0 which caused overriding a parametrized fixture with an indirect @pytest.mark.parametrize to fail with duplicate parametrization error - Fixed list-item typing errors from mypy in @pytest.mark.parametrize argvalues parameter - Fixed a regression in pytest 9.1.0 where conftest.py files located in /test* were no longer loaded as initial conftests when invoked without arguments #### 9.0.3 (2026-04-07) - Fixed pytest.approx to correctly take into account Mapping keys order when comparing them - Blocking a conftest.py file using the -p no: option is now explicitly disallowed and raises a clear UsageError instead of causing an internal assertion failure - Fixed crash when a test raises an exceptiongroup with __tracebackhide__ = True - Fixed an issue where non-string messages passed to unittest.TestCase.subTest() were not printed #### 9.0.2 (2025-12-06) - Disable the terminal progress feature by default except on Windows due to compatibility issues with some terminal emulators, and do not emit escape codes when the TERM environment variable is dumb - Fix the TOML type of the tmp_path_retention_count setting in the API reference from number to string - Restore the private config.inicfg attribute to working order using a compatibility shim after breaking changes in pytest 9.0.0 - Fix quadratic-time behavior when handling unittest subtests in Python 3.10 #### 9.0.1 (2025-11-12) - Restore support for skipping tests via raise unittest.SkipTest - The terminal progress plugin is now automatically disabled when iTerm2 is detected to prevent generating desktop notifications instead of the desired functionality - Fixed the TOML type of the verbosity settings in the API reference from number to string - Fixed UserWarning: Do not expect file_or_dir on some earlier Python 3.12 and 3.13 point versions ### Removed #### 9.1.0 (2026-06-13) - When using --doctest-modules, autouse fixtures with module, package or session scope that are defined inline in Python test modules will now possibly execute twice ### Deprecated #### 9.1.0 (2026-06-13) - Class-scoped fixtures defined as instance methods without @classmethod decorator are now deprecated - Calling request.getfixturevalue() during teardown to request a fixture that was not already requested is now deprecated - Using non-Collection iterables such as generators, iterators, or custom iterable objects for the argvalues parameter in @pytest.mark.parametrize and metafunc.parametrize is now deprecated - The private config.inicfg attribute is now deprecated, use config.getini() instead - Passing baseid to FixtureDef or nodeid strings to fixture registration APIs is now deprecated, use the node parameter instead - The method of configuring hooks using markers is now scheduled to be removed in pytest 10 - The --pastebin option is now deprecated - The private FixtureDef.has_location attribute is now deprecated - pytest.console_main is now deprecated, use pytest.main instead ### Security #### 9.0.3 (2026-04-07) - Fixed use of insecure temporary directory (CVE-2025-71176) ## Release notes ### 9.1.1 - Date: 2026-06-19 - Version: 9.1.1 - Original notes: https://github.com/pytest-dev/pytest/releases/tag/9.1.1 - Permalink: https://whatsnew.fyi/product/pytest/releases/9.1.1 - **fixed** — Fixed a logic bug in pytest.RaisesGroup which would cause it to display incorrect error pairing messages - **fixed** — Fixed a regression in pytest 9.1.0 which caused overriding a parametrized fixture with an indirect @pytest.mark.parametrize to fail with duplicate parametrization error - **fixed** — Fixed list-item typing errors from mypy in @pytest.mark.parametrize argvalues parameter - **fixed** — Fixed a regression in pytest 9.1.0 where conftest.py files located in /test* were no longer loaded as initial conftests when invoked without arguments #### pytest 9.1.1 (2026-06-19) ##### Bug fixes - [\#14220](https://github.com/pytest-dev/pytest/issues/14220): Fixed a logic bug in `pytest.RaisesGroup` which would might cause it to display incorrect "It matches FooError() which was paired with BarError" messages. - [\#14591](https://github.com/pytest-dev/pytest/issues/14591): Fixed a regression in pytest 9.1.0 which caused overriding a parametrized fixture with an indirect @pytest.mark.parametrize to fail with "duplicate parametrization of '\'". - [\#14606](https://github.com/pytest-dev/pytest/issues/14606): Fixed `list-item` typing errors from mypy in `@pytest.mark.parametrize ` `argvalues` parameter. - [\#14608](https://github.com/pytest-dev/pytest/issues/14608): Fixed a regression in pytest 9.1.0 where `conftest.py` files located in `/test*` were no longer loaded as initial conftests when invoked without arguments. This could cause certain hooks (like `pytest_addoption`) in these files to not fire. ### 9.1.0 - Date: 2026-06-13 - Version: 9.1.0 - Original notes: https://github.com/pytest-dev/pytest/releases/tag/9.1.0 - Permalink: https://whatsnew.fyi/product/pytest/releases/9.1.0 - **removed** — When using --doctest-modules, autouse fixtures with module, package or session scope that are defined inline in Python test modules will now possibly execute twice - **deprecated** — Class-scoped fixtures defined as instance methods without @classmethod decorator are now deprecated - **deprecated** — Calling request.getfixturevalue() during teardown to request a fixture that was not already requested is now deprecated - **deprecated** — Using non-Collection iterables such as generators, iterators, or custom iterable objects for the argvalues parameter in @pytest.mark.parametrize and metafunc.parametrize is now deprecated - **deprecated** — The private config.inicfg attribute is now deprecated, use config.getini() instead - **deprecated** — Passing baseid to FixtureDef or nodeid strings to fixture registration APIs is now deprecated, use the node parameter instead - **deprecated** — The method of configuring hooks using markers is now scheduled to be removed in pytest 10 - **deprecated** — The --pastebin option is now deprecated - **deprecated** — The private FixtureDef.has_location attribute is now deprecated - **deprecated** — pytest.console_main is now deprecated, use pytest.main instead - **added** — Added pytest.register_fixture() to register fixtures using an imperative interface - **added** — Added --report-chars long CLI option - **added** — Added --max-warnings command-line option and max_warnings configuration option to fail the test run when the number of warnings exceeds a given threshold - **added** — Added the assertion_text_diff_style configuration option for rendering string equality failures as separate Left: and Right: blocks instead of ndiff output - **added** — Added support for datetime and timedelta comparisons with pytest.approx - **changed** — pytest.warns now shows "Regex pattern did not match" instead of "DID NOT WARN" when warnings were emitted but the match pattern did not match - **changed** — Improved output of --fixtures-per-test by excluding internal-implementation fixtures generated by @pytest.mark.parametrize and similar #### pytest 9.1.0 (2026-06-13) ##### Removals and backward incompatible breaking changes - [\#14533](https://github.com/pytest-dev/pytest/issues/14533): When using `--doctest-modules`, autouse fixtures with `module`, `package` or `session` scope that are defined inline in Python test modules (not plugins or conftests) will now possibly execute twice. If this is undesirable, move the fixture definition to a `conftest.py` file if possible. Technical explanation for those interested: When using --doctest-modules, pytest possibly collects Python modules twice, once as `pytest.Module` and once as a `DoctestModule` (depending on the configuration). Due to improvements in pytest's fixture implementation, if e.g. the `DoctestModule` collects a fixture, it is now visible to it only, and not to the `Module`. This means that both need to register the fixtures independently. ##### Deprecations (removal in next major release) - [\#10819](https://github.com/pytest-dev/pytest/issues/10819): Added a deprecation warning for class-scoped fixtures defined as instance methods (without `@classmethod`). Such fixtures set attributes on a different instance than the test methods use, leading to unexpected behavior. Use `@classmethod` decorator instead -- by `yastcher`. See `10819` and `14011`. - [\#12882](https://github.com/pytest-dev/pytest/issues/12882): Calling `request.getfixturevalue() ` during teardown to request a fixture that was not already requested is now deprecated and will become an error in pytest 10. See `dynamic-fixture-request-during-teardown` for details. - [\#13409](https://github.com/pytest-dev/pytest/issues/13409): Using non-`~collections.abc.Collection` iterables (such as generators, iterators, or custom iterable objects) for the `argvalues` parameter in `@pytest.mark.parametrize ` and `metafunc.parametrize ` is now deprecated. These iterables get exhausted after the first iteration, leading to tests getting unexpectedly skipped in cases such as running `pytest.main()` multiple times, using class-level parametrize decorators, or collecting tests multiple times. See `parametrize-iterators` for details and suggestions. - [\#13946](https://github.com/pytest-dev/pytest/issues/13946): The private `config.inicfg` attribute is now deprecated. Use `config.getini() ` to access configuration values instead. See `config-inicfg` for more details. - [\#14004](https://github.com/pytest-dev/pytest/issues/14004): Passing `baseid` to `~pytest.FixtureDef` or `nodeid` strings to fixture registration APIs is now deprecated. These are internal pytest APIs that are used by some plugins. Use the `node` parameter instead for fixture scoping. This enables more robust node-based matching instead of string prefix matching. If you've used `nodeid=None`, pass `node=session` instead. This will be removed in pytest 10. - [\#14335](https://github.com/pytest-dev/pytest/issues/14335): The method of configuring hooks using markers, deprecated since pytest 7.2, is now scheduled to be removed in pytest 10. See `hook-markers` for more details. - [\#14434](https://github.com/pytest-dev/pytest/issues/14434): The `--pastebin` option is now deprecated. The same functionality is now available in an external plugin, `pytest-pastebin`. See `pastebin-deprecated` for more details. - [\#14513](https://github.com/pytest-dev/pytest/issues/14513): The private `FixtureDef.has_location` attribute is now deprecated and will be removed in pytest 10. See `fixturedef-has-location-deprecated` for details. - [\#1764](https://github.com/pytest-dev/pytest/issues/1764): `pytest.console_main` is now deprecated and will be removed in pytest 10. It was never intended for programmatic use; use `pytest.main` instead. ##### New features - [\#12376](https://github.com/pytest-dev/py _[Truncated at 4000 characters — full notes: https://github.com/pytest-dev/pytest/releases/tag/9.1.0]_ ### 9.0.3 - Date: 2026-04-07 - Version: 9.0.3 - Original notes: https://github.com/pytest-dev/pytest/releases/tag/9.0.3 - Permalink: https://whatsnew.fyi/product/pytest/releases/9.0.3 - **fixed** — Fixed pytest.approx to correctly take into account Mapping keys order when comparing them - **fixed** — Blocking a conftest.py file using the -p no: option is now explicitly disallowed and raises a clear UsageError instead of causing an internal assertion failure - **fixed** — Fixed crash when a test raises an exceptiongroup with __tracebackhide__ = True - **fixed** — Fixed an issue where non-string messages passed to unittest.TestCase.subTest() were not printed - **security** — Fixed use of insecure temporary directory (CVE-2025-71176) #### pytest 9.0.3 (2026-04-07) ##### Bug fixes - [\#12444](https://github.com/pytest-dev/pytest/issues/12444): Fixed `pytest.approx` which now correctly takes into account `~collections.abc.Mapping` keys order to compare them. - [\#13634](https://github.com/pytest-dev/pytest/issues/13634): Blocking a `conftest.py` file using the `-p no:` option is now explicitly disallowed. Previously this resulted in an internal assertion failure during plugin loading. Pytest now raises a clear `UsageError` explaining that conftest files are not plugins and cannot be disabled via `-p`. - [\#13734](https://github.com/pytest-dev/pytest/issues/13734): Fixed crash when a test raises an exceptiongroup with `__tracebackhide__ = True`. - [\#14195](https://github.com/pytest-dev/pytest/issues/14195): Fixed an issue where non-string messages passed to unittest.TestCase.subTest() were not printed. - [\#14343](https://github.com/pytest-dev/pytest/issues/14343): Fixed use of insecure temporary directory (CVE-2025-71176). ##### Improved documentation - [\#13388](https://github.com/pytest-dev/pytest/issues/13388): Clarified documentation for `-p` vs `PYTEST_PLUGINS` plugin loading and fixed an incorrect `-p` example. - [\#13731](https://github.com/pytest-dev/pytest/issues/13731): Clarified that capture fixtures (e.g. `capsys` and `capfd`) take precedence over the `-s` / `--capture=no` command-line options in `Accessing captured output from a test function `. - [\#14088](https://github.com/pytest-dev/pytest/issues/14088): Clarified that the default `pytest_collection` hook sets `session.items` before it calls `pytest_collection_finish`, not after. - [\#14255](https://github.com/pytest-dev/pytest/issues/14255): TOML integer log levels must be quoted: Updating reference documentation. ##### Contributor-facing changes - [\#12689](https://github.com/pytest-dev/pytest/issues/12689): The test reports are now published to Codecov from GitHub Actions. The test statistics is visible [on the web interface](https://app.codecov.io/gh/pytest-dev/pytest/tests). -- by `aleguy02` ### 9.0.2 - Date: 2025-12-06 - Version: 9.0.2 - Original notes: https://github.com/pytest-dev/pytest/releases/tag/9.0.2 - Permalink: https://whatsnew.fyi/product/pytest/releases/9.0.2 - **fixed** — Disable the terminal progress feature by default except on Windows due to compatibility issues with some terminal emulators, and do not emit escape codes when the TERM environment variable is dumb - **fixed** — Fix the TOML type of the tmp_path_retention_count setting in the API reference from number to string - **fixed** — Restore the private config.inicfg attribute to working order using a compatibility shim after breaking changes in pytest 9.0.0 - **fixed** — Fix quadratic-time behavior when handling unittest subtests in Python 3.10 #### pytest 9.0.2 (2025-12-06) ##### Bug fixes - [\#13896](https://github.com/pytest-dev/pytest/issues/13896): The terminal progress feature added in pytest 9.0.0 has been disabled by default, except on Windows, due to compatibility issues with some terminal emulators. You may enable it again by passing `-p terminalprogress`. We may enable it by default again once compatibility improves in the future. Additionally, when the environment variable `TERM` is `dumb`, the escape codes are no longer emitted, even if the plugin is enabled. - [\#13904](https://github.com/pytest-dev/pytest/issues/13904): Fixed the TOML type of the `tmp_path_retention_count` settings in the API reference from number to string. - [\#13946](https://github.com/pytest-dev/pytest/issues/13946): The private `config.inicfg` attribute was changed in a breaking manner in pytest 9.0.0. Due to its usage in the ecosystem, it is now restored to working order using a compatibility shim. It will be deprecated in pytest 9.1 and removed in pytest 10. - [\#13965](https://github.com/pytest-dev/pytest/issues/13965): Fixed quadratic-time behavior when handling `unittest` subtests in Python 3.10. ##### Improved documentation - [\#4492](https://github.com/pytest-dev/pytest/issues/4492): The API Reference now contains cross-reference-able documentation of `pytest's command-line flags `. ### 9.0.1 - Date: 2025-11-12 - Version: 9.0.1 - Original notes: https://github.com/pytest-dev/pytest/releases/tag/9.0.1 - Permalink: https://whatsnew.fyi/product/pytest/releases/9.0.1 - **fixed** — Restore support for skipping tests via raise unittest.SkipTest - **fixed** — The terminal progress plugin is now automatically disabled when iTerm2 is detected to prevent generating desktop notifications instead of the desired functionality - **fixed** — Fixed the TOML type of the verbosity settings in the API reference from number to string - **fixed** — Fixed UserWarning: Do not expect file_or_dir on some earlier Python 3.12 and 3.13 point versions #### pytest 9.0.1 (2025-11-12) ##### Bug fixes - [\#13895](https://github.com/pytest-dev/pytest/issues/13895): Restore support for skipping tests via `raise unittest.SkipTest`. - [\#13896](https://github.com/pytest-dev/pytest/issues/13896): The terminal progress plugin added in pytest 9.0 is now automatically disabled when iTerm2 is detected, it generated desktop notifications instead of the desired functionality. - [\#13904](https://github.com/pytest-dev/pytest/issues/13904): Fixed the TOML type of the verbosity settings in the API reference from number to string. - [\#13910](https://github.com/pytest-dev/pytest/issues/13910): Fixed UserWarning: Do not expect file_or_dir on some earlier Python 3.12 and 3.13 point versions. ##### Packaging updates and notes for downstreams - [\#13933](https://github.com/pytest-dev/pytest/issues/13933): The tox configuration has been adjusted to make sure the desired version string can be passed into its `package_env` through the `SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST` environment variable as a part of the release process -- by `webknjaz`. ##### Contributor-facing changes - [\#13891](https://github.com/pytest-dev/pytest/issues/13891), [\#13942](https://github.com/pytest-dev/pytest/issues/13942): The CI/CD part of the release automation is now capable of creating GitHub Releases without having a Git checkout on disk -- by `bluetech` and `webknjaz`. - [\#13933](https://github.com/pytest-dev/pytest/issues/13933): The tox configuration has been adjusted to make sure the desired version string can be passed into its `package_env` through the `SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST` environment variable as a part of the release process -- by `webknjaz`. ### 9.0.0 - Date: 2025-11-08 - Version: 9.0.0 - Original notes: https://github.com/pytest-dev/pytest/releases/tag/9.0.0 - Permalink: https://whatsnew.fyi/product/pytest/releases/9.0.0 - **added** — Support for subtests has been added as an alternative to parametrization, useful when parametrization values are not all known at collection time - **added** — Added support for native TOML configuration files in pyproject.toml under the [tool.pytest] table, as well as pytest.toml or .pytest.toml files - **added** — Added a strict mode enabled by the strict configuration option that enables strict_config, strict_markers, strict_parametrization_ids, and strict_xfail - **added** — Added the strict_parametrization_ids configuration option to emit an error if non-unique parameter set IDs are detected - **added** — Added support for displaying test session progress in the terminal tab using the OSC 9;4; ANSI sequence - **added** — Support PEP420 implicit namespace packages as --pyargs target when consider_namespace_packages is true in the config - **added** — Added a new faulthandler_exit_on_timeout configuration option set to false by default to let faulthandler interrupt the pytest process after a timeout in case of deadlock - **added** — Added support for configuration option aliases via the aliases parameter in Parser.addini() - **changed** — The previously-deprecated --strict command-line flag now enables strict mode - **changed** — unittest.TestCase.subTest is now also supported #### pytest 9.0.0 (2025-11-05) ##### New features - [\#1367](https://github.com/pytest-dev/pytest/issues/1367): **Support for subtests** has been added. `subtests ` are an alternative to parametrization, useful in situations where the parametrization values are not all known at collection time. Example: ``` python def contains_docstring(p: Path) -> bool: """Return True if the given Python file contains a top-level docstring.""" ... def test_py_files_contain_docstring(subtests: pytest.Subtests) -> None: for path in Path.cwd().glob("*.py"): with subtests.test(path=str(path)): assert contains_docstring(path) ``` Each assert failure or error is caught by the context manager and reported individually, giving a clear picture of all files that are missing a docstring. In addition, `unittest.TestCase.subTest` is now also supported. This feature was originally implemented as a separate plugin in [pytest-subtests](https://github.com/pytest-dev/pytest-subtests), but since then has been merged into the core. > [!NOTE] > This feature is experimental and will likely evolve in future releases. By that we mean that we might change how subtests are reported on failure, but the functionality and how to use it are stable. - [\#13743](https://github.com/pytest-dev/pytest/issues/13743): Added support for **native TOML configuration files**. While pytest, since version 6, supports configuration in `pyproject.toml` files under `[tool.pytest.ini_options]`, it does so in an "INI compatibility mode", where all configuration values are treated as strings or list of strings. Now, pytest supports the native TOML data model. In `pyproject.toml`, the native TOML configuration is under the `[tool.pytest]` table. ``` toml # pyproject.toml [tool.pytest] minversion = "9.0" addopts = ["-ra", "-q"] testpaths = [ "tests", "integration", ] ``` The `[tool.pytest.ini_options]` table remains supported, but both tables cannot be used at the same time. If you prefer to use a separate configuration file, or don't use `pyproject.toml`, you can use `pytest.toml` or `.pytest.toml`: ``` toml # pytest.toml or .pytest.toml [pytest] minversion = "9.0" addopts = ["-ra", "-q"] testpaths = [ "tests", "integration", ] ``` The documentation now (sometimes) shows configuration snippets in both TOML and INI formats, in a tabbed interface. See `config file formats` for full details. - [\#13823](https://github.com/pytest-dev/pytest/issues/13823): Added a **"strict mode"** enabled by the `strict` configuration option. When set to `true`, the `strict` option currently enables - `strict_config` - `strict_markers` - `strict_parametrization_ids` - `strict_xfail` The individual strictness options can be explicitly set to override the global `strict` setting. The previously-deprecated `--strict` command-line flag now enables strict mode. If pytest adds new strictness options in the future, they will also be enabled in strict mode. Therefore, you should only enable strict mode if you use a pinned/locked version of pytest, or if you want to proactively adopt new strictness options as they are added. See `strict mode` for more details. - [\#13737](https://github.com/pytest-dev/pytest/issues/13737): Added the `strict_parametrization_ids` configuration option. When set, pytest emits an error if it detects non-unique parameter set IDs, rather than automatically making the IDs unique by adding 0, 1, ... to them. This can be particularly useful for catching unintended duplicates. - [\#13072](https://github.com/pytest-dev/pytest/issues/13072): Added support for displaying test session **progress in the terminal tab** using the [OSC 9;4;](https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC) ANSI sequence. When pytest runs i _[Truncated at 4000 characters — full notes: https://github.com/pytest-dev/pytest/releases/tag/9.0.0]_