pypi / pytest
pytest
What changed in pytest 9, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-18.
10 breaking1 security11 deprecations17 new APIs and options1 performance8 behavior and defaults31 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli initpytest 979 changes
Breaking changes 10
Autouse fixtures with module, package, or session scope defined inline in Python test modules may execute twice when doctest modules are enabled.
Fixture overrides are resolved first by visibility in the collection tree, so a more specific node takes precedence over a more general node regardless of registration order.
Unraisable exceptions from finalizers are collected during
pytest_unconfigurebefore session warning filters are torn down, so matching error filters promote them to failures regardless of plugin cleanup order.It is no longer considered an interactive exception, so
pytest_exception_interactis no longer called for it.Disallows blocking a
conftest.pyfile and raises a clearUsageErrorexplaining that conftest files are not plugins and cannot be disabled via-p.CI mode is activated only when
CIorBUILD_NUMBERis defined and has a non-empty value.A file argument with parametrization syntax is now reported as a usage error instead of silently being treated as the file path.
Warnings of this type now raise errors by default; affected features are slated for removal in pytest 9.1.
pytest no longer supports Python 3.9.
A single
--versionno longer loads the plugin infrastructure; passing it twice retains the behavior of showing pytest and plugin information. It only works when passed directly on the command line.
Security 1
Fixes the use of an insecure temporary directory.
Deprecations 11
Class-scoped fixtures defined as instance methods without
@classmethodnow emit a deprecation warning; use@classmethodinstead.The private
config.inicfgattribute is deprecated; useconfig.getini()to access configuration values.Passing
nodeidstrings to fixture registration APIs is deprecated; use thenodeparameter for fixture scoping.Passing
baseidtoFixtureDefis deprecated; use thenodeparameter for fixture scoping.The private
FixtureDef.has_locationattribute is deprecated and will be removed in pytest 10.Configuring hooks using markers, deprecated since pytest 7.2, is now scheduled for removal in pytest 10.
The option is deprecated; the same functionality is available in the external
pytest-pastebinplugin.This function is deprecated and will be removed in pytest 10; use
pytest.maininstead.Type checkers now recognize
yield_fixtureas deprecated through thedeprecateddecorator.The attribute will be deprecated in pytest 9.1 and removed in pytest 10.
Prints a warning when configuration is spread over more than one file, clarifying that only one is used.
New APIs and options 17
Adds a setting to render string equality failures as separate
Left:andRight:blocks instead ofndiffoutput.Adds a command-line threshold that fails the test run when the number of warnings exceeds the given value.
Adds a configuration threshold that fails the test run when the number of warnings exceeds the given value.
Supports comparisons with
datetimeandtimedelta; datetime comparisons require an explicit absolute or relative tolerance as atimedelta, and relative tolerance is unsupported.The callable overload uses
ParamSpecinstead ofAnyfor type hints, andfunccan now be passed as a keyword argument.Adds an imperative interface for registering fixtures, intended for plugins where declarative registration is cumbersome or unviable.
The callable overload uses
ParamSpecinstead ofAnyfor type hints, andfunccan now be passed as a keyword argument.Adds
pytest.tomlas a separate native TOML configuration file.Adds
.pytest.tomlas a separate native TOML configuration file.Adds a configuration option that enables
strict_config,strict_markers,strict_parametrization_ids, andstrict_xfail; individual options can override it.Adds
strict_configas a configuration option alias for the--strict-configflag.Adds
strict_markersas a configuration option alias for the--strict-markersflag.When enabled, emits an error for non-unique parameter set IDs instead of automatically making them unique.
Adds
strict_xfailas an alias toxfail_strict.Adds subtests as an alternative to parametrization when values are not all known at collection time; failures are reported individually. The feature is experimental.
Adds native TOML configuration in the
[tool.pytest]table ofpyproject.toml; it cannot be used alongside[tool.pytest.ini_options].pytest now supports unittest subTest.
Performance 1
Quadratic-time behavior when handling unittest subtests in Python 3.10 was fixed.
Behavior and default changes 8
Help and error messages identify
pytest,python -m pytest, orpytest.main()according to how pytest was invoked.Output excludes internal-implementation fixtures generated by
@pytest.mark.parametrizeand similar.When warnings were emitted but the match pattern did not match, the message now says “Regex pattern did not match” instead of “DID NOT WARN”.
A
PytestCollectionWarningis emitted when module-level__getattr__returnsNoneforpytestmark; collection then continues normally.Output now prints a space after the test name and any listed fixtures to separate them from the test result.
The default number of
gc.collect()passes is reduced from five to one on CPython; PyPy retains five passes.Terminal progress is disabled by default except on Windows; enable it with -p terminalprogress.
The previously-deprecated flag now enables strict mode.
Fixes and other changes 31
Restored loading files under
<invocation dir>/test*as initial conftests when pytest is invoked without arguments, so hooks in those files can run.Fixed mypy list-item typing errors for the argvalues parameter.
Fixed incorrect match messages that could pair an exception with the wrong error.
Logging capture now works for non-propagating loggers, not only logs that reach the root logger.
Fixes doubled output when
capteesysis used with--capture=no(-s).Fixes duplicated
-Woption values inConfig.known_args_namespace.Fixture values are released more promptly when a test is interrupted by
KeyboardInterruptor early exit.High Unicode supplementary-plane characters, such as emoji, are no longer incorrectly escaped in test failure messages.
An exception from this hook no longer prevents fixtures from being torn down, avoiding additional errors in following tests.
Recognizes types with
__array_interface__as numpy-like arrays.A trailing-comma single argument name such as
"arg,"now unpacks single-element tuple values like("arg",).The callable overload uses
ParamSpecinstead ofAnyfor type hints, andfunccan now be passed as a keyword argument.Assertion verbosity is propagated so the
-vhint in match-diff output works.Adds official support for Python 3.15.
Fixes a regression where
--strict-configspecified throughaddoptswas silently ignored.Fixes a regression where
--strict-markersspecified throughaddoptswas silently ignored.Autouse fixtures defined inside a skipped or
skipIf-decorated test case no longer run.The short form of
--versionnow displays the current version correctly.Correctly takes mapping key order into account when comparing mappings.
Fixes a crash when a test raises an exception group with
__tracebackhide__ = True.Non-string messages passed to
subTest()are now printed.The private attribute is restored to working order with a compatibility shim after a breaking change in pytest 9.0.0.
When TERM is dumb, pytest no longer emits escape codes, even if the terminal progress plugin is enabled.
Fixes a UserWarning on some earlier Python 3.12 and 3.13 point versions.
The plugin is automatically disabled when iTerm2 is detected because it generated desktop notifications instead of the desired functionality.
Raising unittest.SkipTest once again skips tests.
Fixes teardown handling for an
ExceptionGroupcontaining only skipped exceptions, which previously appeared as an error.Improves assertion and error messages when comparing mappings with differing lengths or keys.
Hidden
.pytest.inifiles are now selected as the configuration file even when empty.Type annotations for
pytest.skipand related functions are more spec-compliant to work across more type checkers.A filter referencing a class that cannot be imported now produces a message instead of failing.