NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #24 most downloaded on PyPI
pytest: simple powerful testing with Python
Last release 3 months ago
19 Jun 2026
Ships fairly regularly
a new release about every 2 months
Nearly every release is documented
notes for 60 of the last 60 stable releases
1 version withdrawn
withdrawn after publishing
16 years old
192 releases · first in 2010
pytest 9.1.1 (2026-06-19) Bug fixes #14220 : Fixed a logic bug in pytest.RaisesGroup which would might cause it to display incorrect "It matches FooEr
pytest.RaisesGroup which would might cause it to display incorrect "It matches FooError() which was paired with BarError" messages.list-item typing errors from mypy in @pytest.mark.parametrize <pytest.mark.parametrize ref> argvalues parameter.conftest.py files located in <invocation dir>/test* were no longer loaded as initial conftests when invoked without arguments.pytest_addoption) in these files to not fire.One column per quarter.
Removals and backward incompatible breaking changes
#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.
#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: Calling request.getfixturevalue() <pytest.FixtureRequest.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: Using non-~collections.abc.Collection iterables (such as generators, iterators, or custom iterable objects) for the argvalues parameter in @pytest.mark.parametrize <pytest.mark.parametrize ref> and metafunc.parametrize <pytest.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: The private config.inicfg attribute is now deprecated.
Use config.getini() <pytest.Config.getini> to access configuration values instead.
See config-inicfg for more details.
#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: 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: 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: The private FixtureDef.has_location attribute is now deprecated and will be removed in pytest 10.
See fixturedef-has-location-deprecated for details.
#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.
#12376: Added pytest.register_fixture() to register fixtures using an imperative interface.
This is an advanced function intended for use by plugins.
Normally, fixtures should be registered declaratively using the @pytest.fixture <pytest.fixture> decorator.
Pytest looks for these fixture definitions during the collection phase and registers them automatically.
For some plugin usecases the declarative interface can be cumbersome or unviable, in which case this imperative interface can be used.
#14023: Added --report-chars long CLI option.
#14371: 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 -- by miketheman.
#6757: Added the assertion_text_diff_style configuration option, allowing
string equality failures to be rendered as separate Left: and Right:
blocks instead of ndiff output.
#8395: Added support for ~datetime.datetime and ~datetime.timedelta comparisons with pytest.approx. An explicit abs or rel tolerance as a ~datetime.timedelta is required and relative tolerance is not supported for datetime comparisons -- by hamza-mobeen.
#11225: 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.
#11295: Improved output of --fixtures-per-test by excluding internal-implementation fixtures generated by @pytest.mark.parametrize and similar.
#13241: pytest.raises, pytest.warns and pytest.deprecated_call now uses ParamSpec for the type hint to the (old and not recommended) callable overload, instead of Any. This allows type checkers to raise errors when passing incorrect function parameters.
func can now also be passed as a kwarg, which the type hint previously showed as possible but didn't accept.
#13862: Improved the readability of "DID NOT RAISE" error messages by using the exception type's name instead of its repr.
#14026: Added test coverage for compiled regex patterns in pytest.raises match parameter.
#14137: pytest.ScopeName is now public to allow using it in function signatures.
#14342: Marked yield_fixture as deprecated to type checkers using the deprecated decorator. Note it
has originally been deprecated <yield-fixture-deprecated> in pytest 6.2 already.
#14373: Added type annotations for pytest.approx.
#14430: When using --setup-show, a space is now printed after the test name (and possibly used fixtures), to separate it from the test result.
#14441: Reduced the default number of gc.collect() passes in the unraisableexception plugin from 5 to 1 on CPython, where reference counting makes a single pass sufficient. PyPy retains 5 passes due to object resurrection via __del__. This can noticeably speed up test suites that trigger many pytester runs.
#14461: Improved assertion failure explanations for equality comparisons between mapping objects that are not dict instances.
#14513: The order in which fixture definitions overriding each other are resolved is now determined first by their visibility in the collection tree rather than by the order in which they are registered.
A fixture defined for a more specific node (e.g. a module or an item) now always takes precedence over one with the same name defined for a more general node (e.g. the session), even when the more general one was registered later.
Fixtures with non-comparable visibility or the same visibility keep the existing behavior of "last registered wins".
This change is supposed to only affect plugins which register multiple fixtures programmatically with the same name.
#14524: Add official Python 3.15 support.
#1764: Improved argparse program name to show pytest, python -m pytest, or pytest.main() based on how pytest was invoked, making help and error messages clearer.
#8265: Emit a PytestCollectionWarning when a module-level __getattr__ returns None for pytestmark instead of raising AttributeError.
Previously this caused a cryptic TypeError: got None instead of Mark error.
Now pytest issues a helpful warning and continues collecting the module normally.
#13192: Fixed | (pipe) not being treated as a regex meta-character that needs escaping in pytest.raises(match=...) <pytest.raises>.
#13484: Fixed -W option values being duplicated in Config.known_args_namespace.
#13626: Fixed function-scoped fixture values being kept alive after a test was interrupted by KeyboardInterrupt or early exit,
allowing them to potentially be released more promptly.
#13784: Fixed capteesys producing doubled output when used with --capture=no (-s).
#13817: Fixed a secondary AttributeError masking the original error when an option argument fails to initialize.
#13884: Fixed rare internal IndexError caused by builtins.compile being overridden in client code.
#13885: Fixed autouse fixtures defined inside a unittest.TestCase class running even when the class is decorated with unittest.skip or unittest.skipIf -- regression since pytest 8.1.0.
#13917: unittest.SkipTest is no longer considered an interactive exception, i.e. pytest_exception_interact is no longer called for it.
#13963: Fixed subtests running with pytest-xdist when their contexts contain objects that are not JSON-serializable.
Fixes pytest-dev/pytest-xdist#1273.
#14004: Fixed conftest.py fixture scoping when testpaths points outside of the rootdir <rootdir>.
Previously, fixtures from nested conftest.py files would incorrectly leak to sibling directories
when using a relative testpaths like ../tests/sdk.
Conftest fixtures are now parsed during Directory <pytest.Directory> collection, using the Directory node for proper scoping.
#14050: Display dictionary differences in assertion failures using the original key insertion order instead of sorted order.
#14080: fix missing type annotations on Pytester.makepyfile and Pytester.maketxtfile methods.
#14114: An exception from pytest_fixture_post_finalizer no longer prevents fixtures from being torn down, causing additional errors in the following tests.
#14161: Fixed monkeypatch.setattr() <pytest.MonkeyPatch.setattr> leaving a stale entry on the undo stack when the underlying setattr() call fails (e.g. on immutable targets), causing an AttributeError crash during teardown.
#14214: Fixed -v hint in pytest.raises match diff not working because assertion verbosity was not propagated.
#14234: Allow pytest.HIDDEN_PARAM <hidden-param> in @pytest.mark.parametrize(ids=...) <pytest.mark.parametrize ref> typing.
#14248: Fixed direct parametrization causing the static fixture closure (as reflected in request.fixturenames <pytest.FixtureRequest.fixturenames>) to omit fixtures that are requested transitively from overridden fixtures.
#14263: Unraisable exceptions from finalizers are now collected during pytest_unconfigure, before pytest tears down the warning filters installed for the session. Previously the collection ran from a cleanup callback whose order relative to other plugins' cleanups was not guaranteed, so an active error filter could be removed before the exception surfaced and a late resource leak would pass silently. A -W error filter, or any filter matching pytest.PytestUnraisableExceptionWarning, now promotes these exceptions to failures regardless of plugin cleanup order.
#14377: Fixed crash in Config.get_terminal_writer when an assertion fails with the terminalreporter plugin disabled.
#14381: Fixed -V (short form of --version) to properly display the current version.
#14389: Improved pytest.raises(..., match=...) <pytest.raises> failures to suppress the mismatched exception as a cause of the resulting AssertionError.
#14392: Fixed a bug in pytest.raises(match=...) <pytest.raises> "fully escaped" detection, causing the regex diff display to be shown in some instances when the raw string diff display should be shown instead.
#14442: Fixed a regression in pytest 9.0 where --strict-markers and --strict-config specified through addopts were silently ignored.
Note that when targeting pytest >= 9.0, it's nicer to use strict_markers and strict_config, or strict mode <strict mode>.
#14456: Fixed pytest.approx not recognizing types with __array_interface__ as numpy-like arrays.
#14474: Fixed a regression where -k and -m expressions containing both backslash characters in identifiers and string literal arguments would incorrectly raise a SyntaxError about escaping.
#14483: Fixed JUnit XML report incorrectly escaping high Unicode codepoints (supplementary plane characters like emoji) in test failure messages. -- by EternalRights
#14492: Fixed Code.getargs() incorrectly including local variable names in the returned argument tuple for functions with *args and/or **kwargs. The method was using co_flags bitmask values (4 and 8) directly as counts instead of converting them to 1 via bool(), and was not accounting for co_kwonlyargcount when var=True.
#3697: Logging capture now works for non-propagating loggers.
Previously only logs which reached the root logger were captured.
This includes caplog and the "Captured log calls" test reporting.
#3850: Fixed JUnit XML report: the tests attribute of the <testsuite> element now always matches the number of <testcase> elements in the file. In some cases (test passes but fails during teardown) the tests attribute would report an incorrect number of testcases in the XML file.
#5848: pytest_fixture_post_finalizer is no longer called extra times for the same fixture teardown in some cases.
#719: Fixed @pytest.mark.parametrize <pytest.mark.parametrize ref> not unpacking single-element tuple values when using a string argnames with a trailing comma (e.g., "arg,").
The trailing comma form now correctly behaves like the tuple form ("arg",), treating argvalues as a list of tuples to unpack.
@pytest.hookimpl(specname=...) only works for function names starting with pytest_.request fixture provides indirect parametrization values via request.param.conftest.py files are not available to other plugins during their pytest_addoption() execution, as conftest files are discovered and loaded after builtin and third-party plugins have been initialized. However, initial conftest files themselves can implement pytest_addoption() to add their own command-line options.ini options ref section of the API Reference now specified the type and default value of every configuration option.pytestconfig.cache access pattern when thecacheprovider plugin is disabled.newhooks.py file in pytest-xdist at tag v3.8.0 instead of an unrelated 2017-era commit under the old layout. Pointing at a tag keeps the example in sync with the version users actually install, while remaining stable when the project's main branch moves on.Previously this resulted in an internal assertion failure during plugin loading.
#12444: Fixed pytest.approx which now correctly takes into account ~collections.abc.Mapping keys order to compare them.
#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: Fixed crash when a test raises an exceptiongroup with __tracebackhide__ = True.
#14195: Fixed an issue where non-string messages passed to unittest.TestCase.subTest() were not printed.
#14343: Fixed use of insecure temporary directory (CVE-2025-71176).
-p vs PYTEST_PLUGINS plugin loading and fixed an incorrect -p example.capsys and capfd) take precedence over the -s / --capture=no command-line options in Accessing captured output from a test function <accessing-captured-output>.pytest_collection hook sets session.items before it calls pytest_collection_finish, not after.#12689: The test reports are now published to Codecov from GitHub Actions.
The test statistics is visible on the web interface.
-- by aleguy02
You may enable it again by passing -p terminalprogress . We may enable it by default again once compatibility improves in the future.
#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: Fixed the TOML type of the tmp_path_retention_count settings in the API reference from number to string.
#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: Fixed quadratic-time behavior when handling unittest subtests in Python 3.10.
pytest's command-line flags <command-line-flags>.Packaging updates and notes for downstreams
raise unittest.SkipTest.package_env throughSETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST environmentwebknjaz.bluetech and webknjaz.package_env throughSETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST environmentwebknjaz.Removals and backward incompatible breaking changes
#1367: Support for subtests has been added.
subtests <subtests> are an alternative to parametrization, useful in situations where the parametrization values are not all known at collection time.
Example:
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, 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: 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.
# 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:
# 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: Added a "strict mode" enabled by the strict configuration option.
When set to true, the strict option currently enables
strict_configstrict_markersstrict_parametrization_idsstrict_xfailThe 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: 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: Added support for displaying test session progress in the terminal tab using the OSC 9;4; ANSI sequence.
When pytest runs in a supported terminal emulator like ConEmu, Gnome Terminal, Ptyxis, Windows Terminal, Kitty or Ghostty,
you'll see the progress in the terminal tab or window,
allowing you to monitor pytest's progress at a glance.
This feature is automatically enabled when running in a TTY. It is implemented as an internal plugin. If needed, it can be disabled as follows:
-p no:terminalprogress on the command line or via an environment variable PYTEST_ADDOPTS='-p no:terminalprogress'.addopts = "-p no:terminalprogress".#478: Support PEP420 (implicit namespace packages) as --pyargs target when consider_namespace_packages is true in the config.
Previously, this option only impacted package imports, now it also impacts tests discovery.
#13678: 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.
Previously, a faulthandler timeout would only dump the traceback of all threads to stderr, but would not interrupt the pytest process.
-- by ogrisel.
#13829: Added support for configuration option aliases via the aliases parameter in Parser.addini() <pytest.Parser.addini>.
Plugins can now register alternative names for configuration options,
allowing for more flexibility in configuration naming and supporting backward compatibility when renaming options.
The canonical name always takes precedence if both the canonical name and an alias are specified in the configuration file.
#13330: Having pytest configuration spread over more than one file (for example having both a pytest.ini file and pyproject.toml with a [tool.pytest.ini_options] table) will now print a warning to make it clearer to the user that only one of them is actually used.
-- by sgaist
#13574: The single argument --version no longer loads the entire plugin infrastructure, making it faster and more reliable when displaying only the pytest version.
Passing --version twice (e.g., pytest --version --version) retains the original behavior, showing both the pytest version and plugin information.
[!NOTE]
Since--versionis now processed early, it only takes effect when passed directly via the command line. It will not work if set through other mechanisms, such asPYTEST_ADDOPTSoraddopts.
#13823: Added strict_xfail as an alias to the xfail_strict option,
strict_config as an alias to the --strict-config flag,
and strict_markers as an alias to the --strict-markers flag.
This makes all strictness options consistently have configuration options with the prefix strict_.
#13700: --junitxml no longer prints the generated xml file summary at the end of the pytest session when --quiet is given.
#13732: Previously, when filtering warnings, pytest would fail if the filter referenced a class that could not be imported. Now, this only outputs a message indicating the problem.
#13859: Clarify the error message for pytest.raises() when a regex match fails.
#13861: Better sentence structure in a test's expected error message. Previously, the error message would be "expected exception must be <expected>, but got <actual>". Now, it is "Expected <expected>, but got <actual>".
#12083: Fixed a bug where an invocation such as pytest a/ a/b would cause only tests from a/b to run, and not other tests under a/.
The fix entails a few breaking changes to how such overlapping arguments and duplicates are handled:
If you rely on these behaviors, consider using --keep-duplicates <duplicate-paths>, which retains its existing behavior (including the bug).
#13719: Support for Python 3.9 is dropped following its end of life.
#13766: Previously, pytest would assume it was running in a CI/CD environment if either of the environment variables $CI or $BUILD_NUMBER was defined;
now, CI mode is only activated if at least one of those variables is defined and set to a non-empty value.
#13779: PytestRemovedIn9Warning deprecation warnings are now errors by default.
Following our plan to remove deprecated features with as little disruption as
possible, all warnings of type PytestRemovedIn9Warning now generate errors
instead of warning messages by default.
The affected features will be effectively removed in pytest 9.1, so please consult the
deprecations section in the docs for directions on how to update existing code.
In the pytest 9.0.X series, it is possible to change the errors back into warnings as a
stopgap measure by adding this to your pytest.ini file:
[pytest]
filterwarnings =
ignore::pytest.PytestRemovedIn9WarningBut this will stop working when pytest 9.1 is released.
If you have concerns about the removal of a specific feature, please add a
comment to 13779.
monkeypatch.syspath_prepend() <pytest.MonkeyPatch.syspath_prepend> now issues a deprecation warning when the prepended path contains legacy namespace packages (those using pkg_resources.declare_namespace()).420).monkeypatch-fixup-namespace-packages for details.#13445: Made the type annotations of pytest.skip and friends more spec-complaint to have them work across more type checkers.
#13537: Fixed a bug in which ExceptionGroup with only Skipped exceptions in teardown was not handled correctly and showed as error.
#13598: Fixed possible collection confusion on Windows when short paths and symlinks are involved.
#13716: Fixed a bug where a nonsensical invocation like pytest x.py[a] (a file cannot be parametrized) was silently treated as pytest x.py. This is now a usage error.
#13722: Fixed a misleading assertion failure message when using pytest.approx on mappings with differing lengths.
#13773: Fixed the static fixture closure calculation to properly consider transitive dependencies requested by overridden fixtures.
#13816: Fixed pytest.approx which now returns a clearer error message when comparing mappings with different keys.
#13849: Hidden .pytest.ini files are now picked up as the config file even if empty.
This was an inconsistency with non-hidden pytest.ini.
#13865: Fixed --show-capture with --tb=line.
#13522: Fixed pytester in subprocess mode ignored all :attr`pytester.plugins <pytest.Pytester.plugins>` except the first.
Fixed pytester in subprocess mode silently ignored non-str pytester.plugins <pytest.Pytester.plugins>.
Now it errors instead.
If you are affected by this, specify the plugin by name, or switch the affected tests to use pytester.runpytest_inprocess <pytest.Pytester.runpytest_inprocess> explicitly instead.
iniconfig and packaging were bumped to 1.0.1 and 22.0.0, respectively.lsof command hanging (e.g. due to unreachable network filesystems), with the affected selftests being skipped after 10 seconds.gh pr new command in scripts/prepare-release-pr.py.gh pr create which is compatible with GitHub CLI v2.0+.ogrisel.tox>=4 is now required when contributing to pytest.pytest_addoption(), pytest_configure(), and cacheshow() functions in cacheprovider.py.-o/--override-ini) are now processed during startup rather than during config.getini() <pytest.Config.getini>.This prevents crashes during module collection when modules do not explicitly use from __future__ import annotations and import types for annotations
#13478: Fixed a crash when using console_output_style{.interpreted-text role="confval"} with times and a module is skipped.
#13530: Fixed a crash when using pytest.approx{.interpreted-text role="func"} and decimal.Decimal{.interpreted-text role="class"} instances with the decimal.FloatOperation{.interpreted-text role="class"} trap set.
#13549: No longer evaluate type annotations in Python 3.14 when inspecting function signatures.
This prevents crashes during module collection when modules do not explicitly use from __future__ import annotations and import types for annotations within a if TYPE_CHECKING: block.
#13559: Added missing [int]{.title-ref} and [float]{.title-ref} variants to the [Literal]{.title-ref} type annotation of the [type]{.title-ref} parameter in pytest.Parser.addini{.interpreted-text role="meth"}.
#13563: pytest.approx{.interpreted-text role="func"} now only imports numpy if NumPy is already in sys.modules. This fixes unconditional import behavior introduced in [8.4.0]{.title-ref}.
pytest_generate_tests is discovered in test modules/classes; other hooks must be in conftest.py or plugins.-Wdefault or a similar override.test_doctest_unexpected_exception in Python 3.14.CI environment variable -- by ogrisel{.interpreted-text role="user"}.#13478 : Fixed a crash when using console_output_style with times and a module is skipped.
#13530 : Fixed a crash when using pytest.approx() and decimal.Decimal instances with the decimal.FloatOperation trap set.
#13549 : No longer evaluate type annotations in Python 3.14 when inspecting function signatures.
This prevents crashes during module collection when modules do not explicitly use from future import annotations and import types for annotations within a if TYPE_CHECKING: block.
#13559 : Added missing int and float variants to the Literal type annotation of the type parameter in pytest.Parser.addini() .
#13563 : pytest.approx() now only imports numpy if NumPy is already in sys.modules . This fixes unconditional import behavior introduced in 8.4.0 .
#13577 : Clarify that pytest_generate_tests is discovered in test modules/classes; other hooks must be in conftest.py or plugins.
#13480 : Self-testing: fixed a few test failures when run with -Wdefault or a similar override.
#13547 : Self-testing: corrected expected message for test_doctest_unexpected_exception in Python 3.14 .
#13684 : Make pytest’s own testsuite insensitive to the presence of the CI environment variable – by @ogrisel .
This warning is raised when a test functions returns a value other than None , which is often a mistake made by beginners.
#13461: Corrected _pytest.terminal.TerminalReporter.isatty to support
being called as a method. Before it was just a boolean which could
break correct code when using -o log_cli=true).
#13477: Reintroduced pytest.PytestReturnNotNoneWarning{.interpreted-text role="class"} which was removed by accident in pytest [8.4]{.title-ref}.
This warning is raised when a test functions returns a value other than None, which is often a mistake made by beginners.
See return-not-none{.interpreted-text role="ref"} for more information.
#13497: Fixed compatibility with Twisted 25+.
faulthandler not working on Windows.#13461 : Corrected _pytest.terminal.TerminalReporter.isatty to support being called as a method. Before it was just a boolean which could break correct code when using -o log_cli=true ).
#13477 : Reintroduced pytest.PytestReturnNotNoneWarning which was removed by accident in pytest 8.4 .
This warning is raised when a test functions returns a value other than None , which is often a mistake made by beginners.
See Returning non-None value in test functions for more information.
#13497 : Fixed compatibility with Twisted 25+ .
#13492 : Fixed outdated warning about faulthandler not working on Windows.
See the docs {.interpreted-text role="ref"} for more information.
#11372: Async tests will now fail, instead of warning+skipping, if you don't have any suitable plugin installed.
#12346: Tests will now fail, instead of raising a warning, if they return any value other than None.
#12874: We dropped support for Python 3.8 following its end of life (2024-10-07).
#12960: Test functions containing a yield now cause an explicit error. They have not been run since pytest 4.0, and were previously marked as an expected failure and deprecation warning.
See the docs <yield tests deprecated>{.interpreted-text role="ref"} for more information.
autouse=True. For guidance on how to work around this warning see sync-test-async-fixture{.interpreted-text role="ref"}.#11538: Added pytest.RaisesGroup{.interpreted-text role="class"} as an equivalent to pytest.raises{.interpreted-text role="func"} for expecting ExceptionGroup{.interpreted-text role="exc"}. Also adds pytest.RaisesExc{.interpreted-text role="class"} which is now the logic behind pytest.raises{.interpreted-text role="func"} and used as parameter to pytest.RaisesGroup{.interpreted-text role="class"}. RaisesGroup includes the ability to specify multiple different expected exceptions, the structure of nested exception groups, and flags for emulating except* <except_star>{.interpreted-text role="ref"}. See assert-matching-exception-groups{.interpreted-text role="ref"} and docstrings for more information.
#12081: Added capteesys{.interpreted-text role="fixture"} to capture AND pass output to next handler set by --capture=.
#12504: pytest.mark.xfail{.interpreted-text role="func"} now accepts pytest.RaisesGroup{.interpreted-text role="class"} for the raises parameter when you expect an exception group. You can also pass a pytest.RaisesExc{.interpreted-text role="class"} if you e.g. want to make use of the check parameter.
#12713: New [--force-short-summary]{.title-ref} option to force condensed summary output regardless of verbosity level.
This lets users still see condensed summary output of failures for quick reference in log files from job outputs, being especially useful if non-condensed output is very verbose.
#12749: pytest traditionally collects classes/functions in the test module namespace even if they are imported from another file.
For example:
# contents of src/domain.py
class Testament: ...
# contents of tests/test_testament.py
from domain import Testament
def test_testament(): ...
In this scenario with the default options, pytest will collect the class [Testament]{.title-ref} from [tests/test_testament.py]{.title-ref} because it starts with [Test]{.title-ref}, even though in this case it is a production class being imported in the test module namespace.
This behavior can now be prevented by setting the new collect_imported_tests{.interpreted-text role="confval"} configuration option to false, which will make pytest collect classes/functions from test files only if they are defined in that file.
-- by FreerGit{.interpreted-text role="user"}
#12765: Thresholds to trigger snippet truncation can now be set with truncation_limit_lines{.interpreted-text role="confval"} and truncation_limit_chars{.interpreted-text role="confval"}.
See truncation-params{.interpreted-text role="ref"} for more information.
#13125: console_output_style{.interpreted-text role="confval"} now supports times to show execution time of each test.
#13192: pytest.raises{.interpreted-text role="func"} will now raise a warning when passing an empty string to match, as this will match against any value. Use match="^$" if you want to check that an exception has no message.
#13192: pytest.raises{.interpreted-text role="func"} will now print a helpful string diff if matching fails and the match parameter has ^ and $ and is otherwise escaped.
#13192: You can now pass with pytest.raises(check=fn): <pytest.raises>{.interpreted-text role="func"}, where fn is a function which takes a raised exception and returns a boolean. The raises fails if no exception was raised (as usual), passes if an exception is raised and fn returns True (as well as match and the type matching, if specified, which are checked before), and propagates the exception if fn returns False (which likely also fails the test).
#13228: hidden-param{.interpreted-text role="ref"} can now be used in id of pytest.param{.interpreted-text role="func"} or in
ids of Metafunc.parametrize <pytest.Metafunc.parametrize>{.interpreted-text role="py:func"}.
It hides the parameter set from the test name.
#13253: New flag: --disable-plugin-autoload <disable_plugin_autoload>{.interpreted-text role="ref"} which works as an alternative to PYTEST_DISABLE_PLUGIN_AUTOLOAD{.interpreted-text role="envvar"} when setting environment variables is inconvenient; and allows setting it in config files with addopts{.interpreted-text role="confval"}.
#10224: pytest's short and long traceback styles (how-to-modifying-python-tb-printing{.interpreted-text role="ref"})
now have partial 657{.interpreted-text role="pep"} support and will show specific code segments in the
traceback.
================================= FAILURES =================================
_______________________ test_gets_correct_tracebacks _______________________
test_tracebacks.py:12: in test_gets_correct_tracebacks
assert manhattan_distance(p1, p2) == 1
^^^^^^^^^^^^^^^^^^^^^^^^^^
test_tracebacks.py:6: in manhattan_distance
return abs(point_1.x - point_2.x) + abs(point_1.y - point_2.y)
^^^^^^^^^
E AttributeError: 'NoneType' object has no attribute 'x'
-- by ammaraskar{.interpreted-text role="user"}
#11118: Now pythonpath{.interpreted-text role="confval"} configures [$PYTHONPATH]{.title-ref} earlier than before during the initialization process, which now also affects plugins loaded via the [-p]{.title-ref} command-line option.
-- by millerdev{.interpreted-text role="user"}
#11381: The type parameter of the parser.addini method now accepts ["int"]{.title-ref} and "float" parameters, facilitating the parsing of configuration values in the configuration file.
Example:
def pytest_addoption(parser):
parser.addini("int_value", type="int", default=2, help="my int value")
parser.addini("float_value", type="float", default=4.2, help="my float value")
The [pytest.ini]{.title-ref} file:
[pytest]
int_value = 3
float_value = 5.4
#11525: Fixtures are now clearly represented in the output as a "fixture object", not as a normal function as before, making it easy for beginners to catch mistakes such as referencing a fixture declared in the same module but not requested in the test function.
-- by the-compiler{.interpreted-text role="user"} and glyphack{.interpreted-text role="user"}
#12426: A warning is now issued when pytest.mark.usefixtures ref{.interpreted-text role="ref"} is used without specifying any fixtures. Previously, empty usefixtures markers were silently ignored.
#12707: Exception chains can be navigated when dropped into Pdb in Python 3.13+.
#12736: Added a new attribute [name]{.title-ref} with the fixed value ["pytest tests"]{.title-ref} to the root tag [testsuites]{.title-ref} of the junit-xml generated by pytest.
This attribute is part of many junit-xml specifications and is even part of the [junit-10.xsd]{.title-ref} specification that pytest's implementation is based on.
#12943: If a test fails with an exceptiongroup with a single exception, the contained exception will now be displayed in the short test summary info.
#12958: A number of unraisable <unraisable>{.interpreted-text role="ref"} enhancements:
tracemalloc{.interpreted-text role="mod"} allocation traceback (if available).StopIteration{.interpreted-text role="class"} in test failures.pytest.PytestUnraisableExceptionWarning{.interpreted-text role="class"} exception if raised.repr of the unraisable object in the unraisable hook so you get the latest information if available, and should help with resurrection of the object.#13010: pytest.approx{.interpreted-text role="func"} now can compare collections that contain numbers and non-numbers mixed.
#13016: A number of threadexception <unraisable>{.interpreted-text role="ref"} enhancements:
tracemalloc{.interpreted-text role="mod"} allocation traceback (if available).StopIteration{.interpreted-text role="class"} in test failures.pytest.PytestUnhandledThreadExceptionWarning{.interpreted-text role="class"} exception if raised.name of the thread object in the excepthook which should help with resurrection of the thread.#13031: An empty parameter set as in pytest.mark.parametrize([], ids=idfunc) will no longer trigger a call to idfunc with internal objects.
#13115: Allows supplying ExceptionGroup[Exception] and BaseExceptionGroup[BaseException] to pytest.raises to keep full typing on ExceptionInfo <pytest.ExceptionInfo>{.interpreted-text role="class"}:
with pytest.raises(ExceptionGroup[Exception]) as exc_info:
some_function()
Parametrizing with other exception types remains an error - we do not check the types of child exceptions and thus do not permit code that might look like we do.
#13122: The --stepwise mode received a number of improvements:
It no longer forgets the last failed test in case pytest is executed later without the flag.
This enables the following workflow:
--stepwise, pytest then stops at the first failing test;--stepwise flag (for example in an IDE), until it is fixed.--stepwise again and pytest will continue from the previously failed test, and if it passes, continue on to the next tests.Previously, at step 3, pytest would start from the beginning, forgetting the previously failed test.
This change however might cause issues if the --stepwise mode is used far apart in time, as the state might get stale, so the internal state will be reset automatically in case the test suite changes (for now only the number of tests are considered for this, we might change/improve this on the future).
New --stepwise-reset/--sw-reset flag, allowing the user to explicitly reset the stepwise state and restart the workflow from the beginning.
#13308: Added official support for Python 3.14.
#13380: Fix ExceptionGroup{.interpreted-text role="class"} traceback filtering to exclude pytest internals.
#13415: The author metadata of the BibTex example is now correctly formatted with last names following first names. An example of BibLaTex has been added. BibTex and BibLaTex examples now clearly indicate that what is cited is software.
-- by willynilly{.interpreted-text role="user"}
#13420: Improved test collection performance by optimizing path resolution used in FSCollector.
#13457: The error message about duplicate parametrization no longer displays an internal stack trace.
#4112: Using pytest.mark.usefixtures <pytest.mark.usefixtures ref>{.interpreted-text role="ref"} on pytest.param{.interpreted-text role="func"} now produces an error instead of silently doing nothing.
#5473: Replace [:]{.title-ref} with [;]{.title-ref} in the assertion rewrite warning message so it can be filtered using standard Python warning filters before calling pytest.main{.interpreted-text role="func"}.
[#6985](https://github.com/pytest-dev/pytest/issues/6985): Improved `pytest.approx`{.interpreted-text role="func"} to enhance the readability of value ranges and tolerances between 0.001 and 1000.
: - The [repr]{.title-ref} method now provides clearer output for values within those ranges, making it easier to interpret the results.
- Previously, the output for those ranges of values and tolerances was displayed in scientific notation (e.g., [42 ± 1.0e+00]{.title-ref}). The updated method now presents the tolerance as a decimal for better readability (e.g., [42 ± 1]{.title-ref}).
Example:
**Previous Output:**
``` console
>>> pytest.approx(42, abs=1)
42 ± 1.0e+00
```
**Current Output:**
``` console
>>> pytest.approx(42, abs=1)
42 ± 1
```
\-- by `fazeelghafoor`{.interpreted-text role="user"}
pygments dependency is now required, causing output always to be source-highlighted (unless disabled via the --code-highlight=no CLI option).#10404: Apply filterwarnings from config/cli as soon as possible, and revert them as late as possible so that warnings as errors are collected throughout the pytest run and before the unraisable and threadexcept hooks are removed.
This allows very late warnings and unraisable/threadexcept exceptions to fail the test suite.
This also changes the warning that the lsof plugin issues from PytestWarning to the new warning PytestFDWarning so it can be more easily filtered.
#11067: The test report is now consistent regardless if the test xfailed via pytest.mark.xfail <pytest.mark.xfail ref>{.interpreted-text role="ref"} or pytest.fail{.interpreted-text role="func"}.
Previously, xfailed tests via the marker would have the string "reason: " prefixed to the message, while those xfailed via the function did not. The prefix has been removed.
#12008: In 11220{.interpreted-text role="pr"}, an unintended change in reordering was introduced by changing the way indices were assigned to direct params. More specifically, before that change, the indices of direct params to metafunc's callspecs were assigned after all parametrizations took place. Now, that change is reverted.
#12863: Fix applying markers, including pytest.mark.parametrize <pytest.mark.parametrize ref>{.interpreted-text role="ref"} when placed above [@staticmethod]{.title-ref} or [@classmethod]{.title-ref}.
#12929: Handle StopIteration from test cases, setup and teardown correctly.
#12938: Fixed --durations-min argument not respected if -vv is used.
#12946: Fixed missing help for pdb{.interpreted-text role="mod"} commands wrapped by pytest -- by adamchainz{.interpreted-text role="user"}.
#12981: Prevent exceptions in pytest.Config.add_cleanup{.interpreted-text role="func"} callbacks preventing further cleanups.
#13047: Restore pytest.approx{.interpreted-text role="func"} handling of equality checks between [bool]{.title-ref} and [numpy.bool_]{.title-ref} types.
Comparing [bool]{.title-ref} and [numpy.bool_]{.title-ref} using pytest.approx{.interpreted-text role="func"} accidentally changed in version [8.3.4]{.title-ref} and [8.3.5]{.title-ref} to no longer match:
>>> import numpy as np
>>> from pytest import approx
>>> [np.True_, np.True_] == pytest.approx([True, True])
False
This has now been fixed:
>>> [np.True_, np.True_] == pytest.approx([True, True])
True
#13119: Improved handling of invalid regex patterns for filter warnings by providing a clear error message.
#13175: The diff is now also highlighted correctly when comparing two strings.
#13248: Fixed an issue where passing a scope in Metafunc.parametrize <pytest.Metafunc.parametrize>{.interpreted-text role="py:func"} with indirect=True
could result in other fixtures being unable to depend on the parametrized fixture.
#13291: Fixed repr of attrs objects in assertion failure messages when using attrs>=25.2.
#13312: Fixed a possible KeyError crash on PyPy during collection of tests involving higher-scoped parameters.
#13345: Fix type hints for pytest.TestReport.when{.interpreted-text role="attr"} and pytest.TestReport.location{.interpreted-text role="attr"}.
#13377: Fixed handling of test methods with positional-only parameter syntax.
Now, methods are supported that formally define self as positional-only
and/or fixture parameters as keyword-only, e.g.:
class TestClass:
def test_method(self, /, *, fixture): ...
Before, this caused an internal error in pytest.
#13384: Fixed an issue where pytest could report negative durations.
#13420: Added lru_cache to nodes._check_initialpaths_for_relpath.
#9037: Honor disable_test_id_escaping_and_forfeit_all_rights_to_community_support{.interpreted-text role="confval"} when escaping ids in parametrized tests.
#12535: [This
example]{.title-ref}<https://docs.pytest.org/en/latest/example/simple.html#making-test-result-information-available-in-fixtures>
showed print statements that do not exactly reflect what the
different branches actually do. The fix makes the example more precise.
#13218: Pointed out in the pytest.approx{.interpreted-text role="func"} documentation that it considers booleans unequal to numeric zero or one.
#13221: Improved grouping of CLI options in the --help output.
#6649: Added ~pytest.TerminalReporter{.interpreted-text role="class"} to the api-reference{.interpreted-text role="ref"} documentation page.
#8612: Add a recipe for handling abstract test classes in the documentation.
A new example has been added to the documentation to demonstrate how to use a mixin class to handle abstract
test classes without manually setting the __test__ attribute for subclasses.
This ensures that subclasses of abstract test classes are automatically collected by pytest.
colorama, iniconfig,
and packaging; and bumped the minimum allowed version
of exceptiongroup for python_version<'3.11' from a release
candidate to a full release.#12017: Mixed internal improvements:
MockTiming into _pytest.timing.-- by RonnyPfannschmidt{.interpreted-text role="user"}
#12647: Fixed running the test suite with the hypothesis pytest plugin.
~pytest.TerminalReporter{.interpreted-text role="class"} to the public pytest API, as it is part of the signature of the pytest_terminal_summary{.interpreted-text role="hook"} hook.See types{.interpreted-text role="ref"} for detailed usage.
-vv verbosity.libedit build of Python, such as on macOS or with uv-managed Python binaries from the python-build-standalone project. This could manifest e.g. by a broken prompt when using Pdb, or seeing empty inputs with manual usage of input() and suspended capturing.AttributeError{.interpreted-text role="class"} crash when using --import-mode=importlib when top-level directory same name as another module of the standard library.--import-mode=importlib, a directory containing py file with the same name would cause an ImportError#12842: Added dedicated page about using types with pytest.
See types{.interpreted-text role="ref"} for detailed usage.
# pytest 8.3.4 (2024-12-01) ## Bug fixes - #12592: Fixed KeyError{.interpreted-text role="class"} crash when using --import-mode=importlib in a direct
#12592: Fixed KeyError{.interpreted-text role="class"} crash when using --import-mode=importlib in a directory layout where a directory contains a child directory with the same name.
#12818: Assertion rewriting now preserves the source ranges of the original instructions, making it play well with tools that deal with the AST, like executing.
#12849: ANSI escape codes for colored output now handled correctly in pytest.fail{.interpreted-text role="func"} with [pytrace=False]{.title-ref}.
#9353: pytest.approx{.interpreted-text role="func"} now uses strict equality when given booleans.
#10558: Fix ambiguous docstring of pytest.Config.getoption{.interpreted-text role="func"}.
#10829: Improve documentation on the current handling of the --basetemp option and its lack of retention functionality (temporary directory location and retention{.interpreted-text role="ref"}).
#12866: Improved cross-references concerning the recwarn{.interpreted-text role="fixture"} fixture.
#12966: Clarify filterwarnings{.interpreted-text role="ref"} docs on filter precedence/order when using multiple @pytest.mark.filterwarnings <pytest.mark.filterwarnings ref>{.interpreted-text role="ref"} marks.
#12592 : Fixed KeyError crash when using --import-mode=importlib in a directory layout where a directory contains a child directory with the same name.
#12818 : Assertion rewriting now preserves the source ranges of the original instructions, making it play well with tools that deal with the AST , like executing .
#12849 : ANSI escape codes for colored output now handled correctly in pytest.fail() with pytrace=False .
#9353 : pytest.approx() now uses strict equality when given booleans.
#10558 : Fix ambiguous docstring of pytest.Config.getoption() .
#10829 : Improve documentation on the current handling of the --basetemp option and its lack of retention functionality ( Temporary directory location and retention ).
#12866 : Improved cross-references concerning the recwarn fixture.
#12966 : Clarify @pytest.mark.filterwarnings docs on filter precedence/order when using multiple @pytest.mark.filterwarnings marks.
#12497 : Fixed two failing pdb-related tests on Python 3.13.
\#12446: Avoid calling @property (and other instance descriptors) during fixture discovery \-- by asottile{.interpreted-text role="user"}
#12446: Avoid calling @property (and other instance descriptors) during fixture discovery -- by asottile{.interpreted-text role="user"}
#12659: Fixed the issue of not displaying assertion failure differences when using the parameter --import-mode=importlib in pytest>=8.1.
#12667: Fixed a regression where type change in [ExceptionInfo.errisinstance]{.title-ref} caused [mypy]{.title-ref} to fail.
#12744: Fixed typing compatibility with Python 3.9 or less -- replaced [typing.Self]{.title-ref} with [typing_extensions.Self]{.title-ref} -- by Avasam{.interpreted-text role="user"}
#12745: Fixed an issue with backslashes being incorrectly converted in nodeid paths on Windows, ensuring consistent path handling across environments.
#6682: Fixed bug where the verbosity levels where not being respected when printing the "msg" part of failed assertion (as in assert condition, msg).
#9422: Fix bug where disabling the terminal plugin via -p no:terminal would cause crashes related to missing the verbose option.
-- by GTowers1{.interpreted-text role="user"}
#12446 : Avoid calling @property (and other instance descriptors) during fixture discovery – by @asottile
#12659 : Fixed the issue of not displaying assertion failure differences when using the parameter --import-mode=importlib in pytest>=8.1.
#12667 : Fixed a regression where type change in ExceptionInfo.errisinstance caused mypy to fail.
#12744 : Fixed typing compatibility with Python 3.9 or less – replaced typing.Self with typing_extensions.Self – by @Avasam
#12745 : Fixed an issue with backslashes being incorrectly converted in nodeid paths on Windows, ensuring consistent path handling across environments.
#6682 : Fixed bug where the verbosity levels where not being respected when printing the “msg” part of failed assertion (as in assert condition, msg ).
#9422 : Fix bug where disabling the terminal plugin via -p no:terminal would cause crashes related to missing the verbose option.
– by @GTowers1
#12663 : Clarify that the pytest_deselected hook should be called from pytest_collection_modifyitems hook implementations when items are deselected.
#12678 : Remove erroneous quotes from tmp_path_retention_policy example in docs.
#12769 : Fix typos discovered by codespell and add codespell to pre-commit hooks.
\#12652: Resolve regression [conda]{.title-ref} environments where no longer being automatically detected.
#12652: Resolve regression [conda]{.title-ref} environments where no longer being automatically detected.
-- by RonnyPfannschmidt{.interpreted-text role="user"}
#12652 : Resolve regression conda environments where no longer being automatically detected.
– by @RonnyPfannschmidt
The 8.3.0 release failed to include the change notes and docs for the release. This patch release remedies this. There are no other changes.
The 8.3.0 release failed to include the change notes and docs for the release. This patch release remedies this. There are no other changes.
If the [\--xfail-tb]{.title-ref} flag is not given, tracebacks for XFAIL results are NOT shown.
#12231: Added [--xfail-tb]{.title-ref} flag, which turns on traceback output for XFAIL results.
Some history:
With pytest 8.0, [-rx]{.title-ref} or [-ra]{.title-ref} would not only turn on summary reports for xfail, but also report the tracebacks for xfail results. This caused issues with some projects that utilize xfail, but don't want to see all of the xfail tracebacks.
This change detaches xfail tracebacks from [-rx]{.title-ref}, and now we turn on xfail tracebacks with [--xfail-tb]{.title-ref}. With this, the default [-rx]{.title-ref}/ [-ra]{.title-ref} behavior is identical to pre-8.0 with respect to xfail tracebacks. While this is a behavior change, it brings default behavior back to pre-8.0.0 behavior, which ultimately was considered the better course of action.
#12281: Added support for keyword matching in marker expressions.
Now tests can be selected by marker keyword arguments.
Supported values are int{.interpreted-text role="class"}, (unescaped) str{.interpreted-text role="class"}, bool{.interpreted-text role="class"} & None{.interpreted-text role="data"}.
See marker examples <marker_keyword_expression_example>{.interpreted-text role="ref"} for more information.
-- by lovetheguitar{.interpreted-text role="user"}
#12567: Added --no-fold-skipped command line option.
If this option is set, then skipped tests in short summary are no longer grouped by reason but all tests are printed individually with their nodeid in the same way as other statuses.
-- by pbrezina{.interpreted-text role="user"}
#12469: The console output now uses the "third-party plugins" terminology,
replacing the previously established but confusing and outdated
reference to setuptools <setuptools:index>{.interpreted-text role="std:doc"}
-- by webknjaz{.interpreted-text role="user"}.
#12544, #12545: Python virtual environment detection was improved by
checking for a pyvenv.cfg{.interpreted-text role="file"} file, ensuring reliable detection on
various platforms -- by zachsnickers{.interpreted-text role="user"}.
#2871: Do not truncate arguments to functions in output when running with [-vvv]{.title-ref}.
#389: The readability of assertion introspection of bound methods has been enhanced
-- by farbodahm{.interpreted-text role="user"}, webknjaz{.interpreted-text role="user"}, obestwalter{.interpreted-text role="user"}, flub{.interpreted-text role="user"}
and glyphack{.interpreted-text role="user"}.
Earlier, it was like:
=================================== FAILURES ===================================
_____________________________________ test _____________________________________
def test():
> assert Help().fun() == 2
E assert 1 == 2
E + where 1 = <bound method Help.fun of <example.Help instance at 0x256a830>>()
E + where <bound method Help.fun of <example.Help instance at 0x256a830>> = <example.Help instance at 0x256a830>.fun
E + where <example.Help instance at 0x256a830> = Help()
example.py:7: AssertionError
=========================== 1 failed in 0.03 seconds ===========================
And now it's like:
=================================== FAILURES ===================================
_____________________________________ test _____________________________________
def test():
> assert Help().fun() == 2
E assert 1 == 2
E + where 1 = fun()
E + where fun = <test_local.Help object at 0x1074be230>.fun
E + where <test_local.Help object at 0x1074be230> = Help()
test_local.py:13: AssertionError
=========================== 1 failed in 0.03 seconds ===========================
#7662: Added timezone information to the testsuite timestamp in the JUnit XML report.
#11706: Fixed reporting of teardown errors in higher-scoped fixtures when using [--maxfail]{.title-ref} or [--stepwise]{.title-ref}.
Originally added in pytest 8.0.0, but reverted in 8.0.2 due to a regression in pytest-xdist. This regression was fixed in pytest-xdist 3.6.1.
#11797: pytest.approx{.interpreted-text role="func"} now correctly handles Sequence <collections.abc.Sequence>{.interpreted-text role="class"}-like objects.
#12204, #12264: Fixed a regression in pytest 8.0 where tracebacks get longer and longer when multiple
tests fail due to a shared higher-scope fixture which raised -- by bluetech{.interpreted-text role="user"}.
Also fixed a similar regression in pytest 5.4 for collectors which raise during setup.
The fix necessitated internal changes which may affect some plugins:
FixtureDef.cached_result[2] is now a tuple (exc, tb)
instead of exc.SetupState.stack failures are now a tuple (exc, tb)
instead of exc.#12275: Fixed collection error upon encountering an abstract <abc>{.interpreted-text role="mod"} class, including abstract [unittest.TestCase]{.title-ref} subclasses.
#12328: Fixed a regression in pytest 8.0.0 where package-scoped parameterized items were not correctly reordered to minimize setups/teardowns in some cases.
#12424: Fixed crash with [assert testcase is not None]{.title-ref} assertion failure when re-running unittest tests using plugins like pytest-rerunfailures. Regressed in 8.2.2.
#12472: Fixed a crash when returning category "error" or "failed" with a custom test status from pytest_report_teststatus{.interpreted-text role="hook"} hook -- pbrezina{.interpreted-text role="user"}.
#12505: Improved handling of invalid regex patterns in pytest.raises(match=r'...') <pytest.raises>{.interpreted-text role="func"} by providing a clear error message.
#12580: Fixed a crash when using the cache class on Windows and the cache directory was created concurrently.
#6962: Parametrization parameters are now compared using [==]{.title-ref} instead of [is]{.title-ref} ([is]{.title-ref} is still used as a fallback if the parameter does not support [==]{.title-ref}). This fixes use of parameters such as lists, which have a different [id]{.title-ref} but compare equal, causing fixtures to be re-computed instead of being cached.
#7166: Fixed progress percentages (the [ 87%] at the edge of the screen) sometimes not aligning correctly when running with pytest-xdist -n.
#12153: Documented using PYTEST_VERSION{.interpreted-text role="envvar"} to detect if code is running from within a pytest run.
#12469: The external plugin mentions in the documentation now avoid mentioning
setuptools entry-points <setuptools:index>{.interpreted-text role="std:doc"} as the concept is
much more generic nowadays. Instead, the terminology of "external",
"installed", or "third-party" plugins (or packages) replaces that.
-- by webknjaz{.interpreted-text role="user"}
#12577: [CI]{.title-ref} and [BUILD_NUMBER]{.title-ref} environment variables role is discribed in
the reference doc. They now also appear when doing [pytest -h]{.title-ref}
-- by MarcBresson{.interpreted-text role="user"}.
#12467: Migrated all internal type-annotations to the python3.10+ style by using the [annotations]{.title-ref} future import.
-- by RonnyPfannschmidt{.interpreted-text role="user"}
#11771, #12557: The PyPy runtime version has been updated to 3.9 from 3.8 that introduced a flaky bug at the garbage collector which was not expected to fix there as the 3.8 is EoL.
-- by x612skm{.interpreted-text role="user"}
#12493: The change log draft preview integration has been refactored to use a
third party extension sphinxcontib-towncrier. The previous in-repo
script was putting the change log preview file at
doc/en/_changelog_towncrier_draft.rst{.interpreted-text role="file"}. Said file is no longer
ignored in Git and might show up among untracked files in the
development environments of the contributors. To address that, the
contributors can run the following command that will clean it up:
$ git clean -x -i -- doc/en/_changelog_towncrier_draft.rst
-- by webknjaz{.interpreted-text role="user"}
#12498: All the undocumented tox environments now have descriptions.
They can be listed in one's development environment by invoking
tox -av in a terminal.
-- by webknjaz{.interpreted-text role="user"}
#12501: The changelog configuration has been updated to introduce more accurate
audience-tailored categories. Previously, there was a trivial
change log fragment type with an unclear and broad meaning. It was
removed and we now have contrib, misc and packaging in
place of it.
The new change note types target the readers who are downstream packagers and project contributors. Additionally, the miscellaneous section is kept for unspecified updates that do not fit anywhere else.
-- by webknjaz{.interpreted-text role="user"}
#12502: The UX of the GitHub automation making pull requests to update the plugin list has been updated. Previously, the maintainers had to close the automatically created pull requests and re-open them to trigger the CI runs. From now on, they only need to click the [Ready for review]{.title-ref} button instead.
-- by webknjaz{.interpreted-text role="user"}
#12522: The :pull: RST role has been replaced with a shorter
:pr: due to starting to use the implementation from
the third-party sphinx-issues{.interpreted-text role="pypi"} Sphinx extension
-- by webknjaz{.interpreted-text role="user"}.
#12531: The coverage reporting configuration has been updated to exclude pytest's own tests marked as expected to fail from the coverage report. This has an effect of reducing the influence of flaky tests on the resulting number.
-- by webknjaz{.interpreted-text role="user"}
#12533: The extlinks Sphinx extension is no longer enabled. The :bpo:
role it used to declare has been removed with that. BPO itself has
migrated to GitHub some years ago and it is possible to link the
respective issues by using their GitHub issue numbers and the
:issue: role that the sphinx-issues extension implements.
-- by webknjaz{.interpreted-text role="user"}
#12562: Possible typos in using the :user: RST role is now being linted
through the pre-commit tool integration -- by webknjaz{.interpreted-text role="user"}.
#12231 : Added --xfail-tb flag, which turns on traceback output for XFAIL results.
If the --xfail-tb flag is not given, tracebacks for XFAIL results are NOT shown.
The style of traceback for XFAIL is set with --tb , and can be auto|long|short|line|native|no .
Note: Even if you have --xfail-tb set, you won’t see them if --tb=no .
Some history:
With pytest 8.0, -rx or -ra would not only turn on summary reports for xfail, but also report the tracebacks for xfail results. This caused issues with some projects that utilize xfail, but don’t want to see all of the xfail tracebacks.
This change detaches xfail tracebacks from -rx , and now we turn on xfail tracebacks with --xfail-tb . With this, the default -rx / -ra behavior is identical to pre-8.0 with respect to xfail tracebacks. While this is a behavior change, it brings default behavior back to pre-8.0.0 behavior, which ultimately was considered the better course of action.
– by @okken
#12281 : Added support for keyword matching in marker expressions.
Now tests can be selected by marker keyword arguments. Supported values are int , (unescaped) str , bool & None .
See marker examples for more information.
– by @lovetheguitar
#12567 : Added --no-fold-skipped command line option.
If this option is set, then skipped tests in short summary are no longer grouped by reason but all tests are printed individually with their nodeid in the same way as other statuses.
– by @pbrezina
#12469 : The console output now uses the “third-party plugins” terminology, replacing the previously established but confusing and outdated reference to setuptools – by @webknjaz .
#12544 , #12545 : Python virtual environment detection was improved by checking for a pyvenv.cfg file, ensuring reliable detection on various platforms – by @zachsnickers .
#2871 : Do not truncate arguments to functions in output when running with -vvv .
#389 : The readability of assertion introspection of bound methods has been enhanced – by @farbodahm , @webknjaz , @obestwalter , @flub and @glyphack .
Earlier, it was like:
=================================== FAILURES =================================== _____________________________________ test _____________________________________ def test(): > assert Help().fun() == 2 E assert 1 == 2 E + where 1 = <bound method Help.fun of <example.Help instance at 0x256a830>>() E + where <bound method Help.fun of <example.Help instance at 0x256a830>> = <example.Help instance at 0x256a830>.fun E + where <example.Help instance at 0x256a830> = Help() example.py:7: AssertionError =========================== 1 failed in 0.03 seconds ===========================
And now it’s like:
=================================== FAILURES =================================== _____________________________________ test _____________________________________ def test(): > assert Help().fun() == 2 E assert 1 == 2 E + where 1 = fun() E + where fun = <test_local.Help object at 0x1074be230>.fun E + where <test_local.Help object at 0x1074be230> = Help() test_local.py:13: AssertionError =========================== 1 failed in 0.03 seconds ===========================
#7662 : Added timezone information to the testsuite timestamp in the JUnit XML report.
#11706 : Fixed reporting of teardown errors in higher-scoped fixtures when using --maxfail or --stepwise .
Originally added in pytest 8.0.0, but reverted in 8.0.2 due to a regression in pytest-xdist. This regression was fixed in pytest-xdist 3.6.1.
#11797 : pytest.approx() now correctly handles Sequence -like objects.
#12204 , #12264 : Fixed a regression in pytest 8.0 where tracebacks get longer and longer when multiple tests fail due to a shared higher-scope fixture which raised – by @bluetech .
Also fixed a similar regression in pytest 5.4 for collectors which raise during setup.
The fix necessitated internal changes which may affect some plugins:
FixtureDef.cached_result[2] is now a tuple (exc, tb) instead of exc .
SetupState.stack failures are now a tuple (exc, tb) instead of exc .
#12275 : Fixed collection error upon encountering an abstract class, including abstract unittest.TestCase subclasses.
#12328 : Fixed a regression in pytest 8.0.0 where package-scoped parameterized items were not correctly reordered to minimize setups/teardowns in some cases.
#12424 : Fixed crash with assert testcase is not None assertion failure when re-running unittest tests using plugins like pytest-rerunfailures. Regressed in 8.2.2.
#12472 : Fixed a crash when returning category "error" or "failed" with a custom test status from pytest_report_teststatus hook – @pbrezina .
#12505 : Improved handling of invalid regex patterns in pytest.raises(match=r'...') by providing a clear error message.
#12580 : Fixed a crash when using the cache class on Windows and the cache directory was created concurrently.
#6962 : Parametrization parameters are now compared using == instead of is ( is is still used as a fallback if the parameter does not support == ). This fixes use of parameters such as lists, which have a different id but compare equal, causing fixtures to be re-computed instead of being cached.
#7166 : Fixed progress percentages (the [ 87%] at the edge of the screen) sometimes not aligning correctly when running with pytest-xdist -n .
#12153 : Documented using PYTEST_VERSION to detect if code is running from within a pytest run.
#12469 : The external plugin mentions in the documentation now avoid mentioning setuptools entry-points as the concept is much more generic nowadays. Instead, the terminology of “external”, “installed”, or “third-party” plugins (or packages) replaces that.
– by @webknjaz
#12577 : CI and BUILD_NUMBER environment variables role is described in the reference doc. They now also appear when doing pytest -h – by @MarcBresson .
#12467 : Migrated all internal type-annotations to the python3.10+ style by using the annotations future import.
– by @RonnyPfannschmidt
#11771 , #12557 : The PyPy runtime version has been updated to 3.9 from 3.8 that introduced a flaky bug at the garbage collector which was not expected to fix there as the 3.8 is EoL.
– by @x612skm
#12493 : The change log draft preview integration has been refactored to use a third party extension sphinxcontib-towncrier . The previous in-repo script was putting the change log preview file at doc/en/_changelog_towncrier_draft.rst . Said file is no longer ignored in Git and might show up among untracked files in the development environments of the contributors. To address that, the contributors can run the following command that will clean it up:
$ git clean -x -i -- doc/en/_changelog_towncrier_draft.rst
– by @webknjaz
#12498 : All the undocumented tox environments now have descriptions. They can be listed in one’s development environment by invoking tox -av in a terminal.
– by @webknjaz
#12501 : The changelog configuration has been updated to introduce more accurate audience-tailored categories. Previously, there was a trivial change log fragment type with an unclear and broad meaning. It was removed and we now have contrib , misc and packaging in place of it.
The new change note types target the readers who are downstream packagers and project contributors. Additionally, the miscellaneous section is kept for unspecified updates that do not fit anywhere else.
– by @webknjaz
#12502 : The UX of the GitHub automation making pull requests to update the plugin list has been updated. Previously, the maintainers had to close the automatically created pull requests and re-open them to trigger the CI runs. From now on, they only need to click the Ready for review button instead.
– by @webknjaz
#12522 : The :pull: RST role has been replaced with a shorter :pr: due to starting to use the implementation from the third-party sphinx-issues Sphinx extension – by @webknjaz .
#12531 : The coverage reporting configuration has been updated to exclude pytest’s own tests marked as expected to fail from the coverage report. This has an effect of reducing the influence of flaky tests on the resulting number.
– by @webknjaz
#12533 : The extlinks Sphinx extension is no longer enabled. The :bpo: role it used to declare has been removed with that. BPO itself has migrated to GitHub some years ago and it is possible to link the respective issues by using their GitHub issue numbers and the :issue: role that the sphinx-issues extension implements.
– by @webknjaz
#12562 : Possible typos in using the :user: RST role is now being linted through the pre-commit tool integration – by @webknjaz .
\#12355: Fix possible catastrophic performance slowdown on a certain parametrization pattern involving many higher-scoped parameters.
.pytest_cache) creation. Regressed in pytest 8.2.0.\#12334: Support for Python 3.13 (beta1 at the time of writing).
.pytest_cache directories became rwx------ instead of the expected rwxr-xr-x.\#12069: A deprecation warning is now raised when implementations of one of the following hooks request a deprecated py.path.local parameter instead o…
#12069: A deprecation warning is now raised when implementations of one of the following hooks request a deprecated py.path.local parameter instead of the pathlib.Path parameter which replaced it:
pytest_ignore_collect{.interpreted-text role="hook"} - the path parameter - use collection_path instead.pytest_collect_file{.interpreted-text role="hook"} - the path parameter - use file_path instead.pytest_pycollect_makemodule{.interpreted-text role="hook"} - the path parameter - use module_path instead.pytest_report_header{.interpreted-text role="hook"} - the startdir parameter - use start_path instead.pytest_report_collectionfinish{.interpreted-text role="hook"} - the startdir parameter - use start_path instead.The replacement parameters are available since pytest 7.0.0. The old parameters will be removed in pytest 9.0.0.
See legacy-path-hooks-deprecated{.interpreted-text role="ref"} for more details.
#11871: Added support for reading command line arguments from a file using the prefix character @, like e.g.: pytest @tests.txt. The file must have one argument per line.
See Read arguments from file <args-from-file>{.interpreted-text role="ref"} for details.
#11523: pytest.importorskip{.interpreted-text role="func"} will now issue a warning if the module could be found, but raised ImportError{.interpreted-text role="class"} instead of ModuleNotFoundError{.interpreted-text role="class"}.
The warning can be suppressed by passing exc_type=ImportError to pytest.importorskip{.interpreted-text role="func"}.
See import-or-skip-import-error{.interpreted-text role="ref"} for details.
#11728: For unittest-based tests, exceptions during class cleanup (as raised by functions registered with TestCase.addClassCleanup <unittest.TestCase.addClassCleanup>{.interpreted-text role="meth"}) are now reported instead of silently failing.
#11777: Text is no longer truncated in the short test summary info section when -vv is given.
#12112: Improved namespace packages detection when consider_namespace_packages{.interpreted-text role="confval"} is enabled, covering more situations (like editable installs).
#9502: Added PYTEST_VERSION{.interpreted-text role="envvar"} environment variable which is defined at the start of the pytest session and undefined afterwards. It contains the value of pytest.__version__, and among other things can be used to easily check if code is running from within a pytest run.
#12065: Fixed a regression in pytest 8.0.0 where test classes containing setup_method and tests using @staticmethod or @classmethod would crash with AttributeError: 'NoneType' object has no attribute 'setup_method'.
Now the request.instance <pytest.FixtureRequest.instance>{.interpreted-text role="attr"} attribute of tests using @staticmethod and @classmethod is no longer None, but a fresh instance of the class, like in non-static methods.
Previously it was None, and all fixtures of such tests would share a single self.
#12135: Fixed issue where fixtures adding their finalizer multiple times to fixtures they request would cause unreliable and non-intuitive teardown ordering in some instances.
#12194: Fixed a bug with --importmode=importlib and --doctest-modules where child modules did not appear as attributes in parent modules.
#1489: Fixed some instances where teardown of higher-scoped fixtures was not happening in the reverse order they were initialized in.
#12089 : pytest now requires that unittest.TestCase subclasses can be instantiated freely using MyTestCase('runTest') .
If the class doesn’t allow this, you may see an error during collection such as AttributeError: 'MyTestCase' object has no attribute 'runTest' .
Classes which do not override init , or do not access the test method in init using getattr or similar, are unaffected.
Classes which do should take care to not crash when "runTest" is given, as is shown in unittest.TestCases’s implementation . Alternatively, consider using setUp instead of init .
If you run into this issue using tornado.AsyncTestCase , please see issue 12263 .
If you run into this issue using an abstract TestCase subclass, please see issue 12275 .
Historical note: the effect of this change on custom TestCase implementations was not properly considered initially, this is why it was done in a minor release. We apologize for the inconvenience.
#12069 : A deprecation warning is now raised when implementations of one of the following hooks request a deprecated py.path.local parameter instead of the pathlib.Path parameter which replaced it:
pytest_ignore_collect - the path parameter - use collection_path instead.
pytest_collect_file - the path parameter - use file_path instead.
pytest_pycollect_makemodule - the path parameter - use module_path instead.
pytest_report_header - the startdir parameter - use start_path instead.
pytest_report_collectionfinish - the startdir parameter - use start_path instead.
The replacement parameters are available since pytest 7.0.0. The old parameters will be removed in pytest 9.0.0.
See py.path.local arguments for hooks replaced with pathlib.Path for more details.
#11871 : Added support for reading command line arguments from a file using the prefix character @ , like e.g.: pytest @tests.txt . The file must have one argument per line.
See Read arguments from file for details.
#11523 : pytest.importorskip() will now issue a warning if the module could be found, but raised ImportError instead of ModuleNotFoundError .
The warning can be suppressed by passing exc_type=ImportError to pytest.importorskip() .
See pytest.importorskip default behavior regarding ImportError for details.
#11728 : For unittest -based tests, exceptions during class cleanup (as raised by functions registered with TestCase.addClassCleanup ) are now reported instead of silently failing.
#11777 : Text is no longer truncated in the short test summary info section when -vv is given.
#12112 : Improved namespace packages detection when consider_namespace_packages is enabled, covering more situations (like editable installs).
#9502 : Added PYTEST_VERSION environment variable which is defined at the start of the pytest session and undefined afterwards. It contains the value of pytest.version , and among other things can be used to easily check if code is running from within a pytest run.
#12065 : Fixed a regression in pytest 8.0.0 where test classes containing setup_method and tests using @staticmethod or @classmethod would crash with AttributeError: 'NoneType' object has no attribute 'setup_method' .
Now the request.instance attribute of tests using @staticmethod and @classmethod is no longer None , but a fresh instance of the class, like in non-static methods. Previously it was None , and all fixtures of such tests would share a single self .
#12135 : Fixed issue where fixtures adding their finalizer multiple times to fixtures they request would cause unreliable and non-intuitive teardown ordering in some instances.
#12194 : Fixed a bug with --importmode=importlib and --doctest-modules where child modules did not appear as attributes in parent modules.
#1489 : Fixed some instances where teardown of higher-scoped fixtures was not happening in the reverse order they were initialized in.
#12069 : pluggy>=1.5.0 is now required.
#12167 : cache : create supporting files ( CACHEDIR.TAG , .gitignore , etc.) in a temporary directory to provide atomic semantics.
\#12114: Fixed error in pytest.approx{.interpreted-text role="func"} when used with [numpy]{.title-ref} arrays and comparing with other types.
pytest.approx{.interpreted-text role="func"} when used with [numpy]{.title-ref} arrays and comparing with other types.#12114 : Fixed error in pytest.approx() when used with numpy arrays and comparing with other types.
\#12069: Delayed the deprecation of the following features to 9.0.0:
::: {.note} ::: {.title} Note :::
This release is not a usual bug fix release -- it contains features and improvements, being a follow up
to 8.1.0, which has been yanked from PyPI.
:::
#11475: Added the new consider_namespace_packages{.interpreted-text role="confval"} configuration option, defaulting to False.
If set to True, pytest will attempt to identify modules that are part of namespace packages when importing modules.
#11653: Added the new verbosity_test_cases{.interpreted-text role="confval"} configuration option for fine-grained control of test execution verbosity.
See Fine-grained verbosity <pytest.fine_grained_verbosity>{.interpreted-text role="ref"} for more details.
#10865: pytest.warns{.interpreted-text role="func"} now validates that warnings.warn{.interpreted-text role="func"} was called with a [str]{.title-ref} or a [Warning]{.title-ref}.
Currently in Python it is possible to use other types, however this causes an exception when warnings.filterwarnings{.interpreted-text role="func"} is used to filter those warnings (see CPython #103577 for a discussion).
While this can be considered a bug in CPython, we decided to put guards in pytest as the error message produced without this check in place is confusing.
#11311: When using --override-ini for paths in invocations without a configuration file defined, the current working directory is used
as the relative directory.
Previoulsy this would raise an AssertionError{.interpreted-text role="class"}.
#11475: --import-mode=importlib <import-mode-importlib>{.interpreted-text role="ref"} now tries to import modules using the standard import mechanism (but still without changing :pysys.path{.interpreted-text role="data"}), falling back to importing modules directly only if that fails.
This means that installed packages will be imported under their canonical name if possible first, for example app.core.models, instead of having the module name always be derived from their path (for example .env310.lib.site_packages.app.core.models).
#11801: Added the iter_parents() <_pytest.nodes.Node.iter_parents>{.interpreted-text role="func"} helper method on nodes.
It is similar to listchain <_pytest.nodes.Node.listchain>{.interpreted-text role="func"}, but goes from bottom to top, and returns an iterator, not a list.
#11850: Added support for sys.last_exc{.interpreted-text role="data"} for post-mortem debugging on Python>=3.12.
#11962: In case no other suitable candidates for configuration file are found, a pyproject.toml (even without a [tool.pytest.ini_options] table) will be considered as the configuration file and define the rootdir.
#11978: Add --log-file-mode option to the logging plugin, enabling appending to log-files. This option accepts either "w" or "a" and defaults to "w".
Previously, the mode was hard-coded to be "w" which truncates the file before logging.
#12047: When multiple finalizers of a fixture raise an exception, now all exceptions are reported as an exception group. Previously, only the first exception was reported.
#11475: Fixed regression where --importmode=importlib would import non-test modules more than once.
#11904: Fixed a regression in pytest 8.0.0 that would cause test collection to fail due to permission errors when using --pyargs.
This change improves the collection tree for tests specified using --pyargs, see 12043{.interpreted-text role="pull"} for a comparison with pytest 8.0 and <8.
#12011: Fixed a regression in 8.0.1 whereby setup_module xunit-style fixtures are not executed when --doctest-modules is passed.
#12014: Fix the stacklevel used when warning about marks used on fixtures.
#12039: Fixed a regression in 8.0.2 where tests created using tmp_path{.interpreted-text role="fixture"} have been collected multiple times in CI under Windows.
tmp_path fixture in more detail.#11785: Some changes were made to private functions which may affect plugins which access them:
FixtureManager._getautousenames() now takes a Node itself instead of the nodeid.FixtureManager.getfixturedefs() now takes the Node itself instead of the nodeid._pytest.nodes.iterparentnodeids() function is removed without replacement.
Prefer to traverse the node hierarchy itself instead.
If you really need to, copy the function from the previous pytest release.#12069: Delayed the deprecation of the following features to 9.0.0:
node-ctor-fspath-deprecation{.interpreted-text role="ref"}.legacy-path-hooks-deprecated{.interpreted-text role="ref"}.It was discovered after 8.1.0 was released that the warnings about the impeding removal were not being displayed, so the team decided to revert the removal.
This is the reason for 8.1.0 being yanked.
::: {.note} ::: {.title} Note :::
This release has been yanked: it broke some plugins without the proper warning period, due to some warnings not showing up as expected.
See #12069. :::
> This release has been yanked: it broke some plugins without the proper warning period, due to some warnings not showing up as expected. See #12069.
[!IMPORTANT]
This release has been yanked: it broke some plugins without the proper warning period, due to some warnings not showing up as expected. See #12069.
#11475: Added the new consider_namespace_packages{.interpreted-text role="confval"} configuration option, defaulting to False.
If set to True, pytest will attempt to identify modules that are part of namespace packages when importing modules.
#11653: Added the new verbosity_test_cases{.interpreted-text role="confval"} configuration option for fine-grained control of test execution verbosity.
See Fine-grained verbosity <pytest.fine_grained_verbosity>{.interpreted-text role="ref"} for more details.
#10865: pytest.warns{.interpreted-text role="func"} now validates that warnings.warn{.interpreted-text role="func"} was called with a [str]{.title-ref} or a [Warning]{.title-ref}.
Currently in Python it is possible to use other types, however this causes an exception when warnings.filterwarnings{.interpreted-text role="func"} is used to filter those warnings (see CPython #103577 for a discussion).
While this can be considered a bug in CPython, we decided to put guards in pytest as the error message produced without this check in place is confusing.
#11311: When using --override-ini for paths in invocations without a configuration file defined, the current working directory is used
as the relative directory.
Previoulsy this would raise an AssertionError{.interpreted-text role="class"}.
#11475: --import-mode=importlib <import-mode-importlib>{.interpreted-text role="ref"} now tries to import modules using the standard import mechanism (but still without changing :pysys.path{.interpreted-text role="data"}), falling back to importing modules directly only if that fails.
This means that installed packages will be imported under their canonical name if possible first, for example app.core.models, instead of having the module name always be derived from their path (for example .env310.lib.site_packages.app.core.models).
#11801: Added the iter_parents() <_pytest.nodes.Node.iter_parents>{.interpreted-text role="func"} helper method on nodes.
It is similar to listchain <_pytest.nodes.Node.listchain>{.interpreted-text role="func"}, but goes from bottom to top, and returns an iterator, not a list.
#11850: Added support for sys.last_exc{.interpreted-text role="data"} for post-mortem debugging on Python>=3.12.
#11962: In case no other suitable candidates for configuration file are found, a pyproject.toml (even without a [tool.pytest.ini_options] table) will be considered as the configuration file and define the rootdir.
#11978: Add --log-file-mode option to the logging plugin, enabling appending to log-files. This option accepts either "w" or "a" and defaults to "w".
Previously, the mode was hard-coded to be "w" which truncates the file before logging.
#12047: When multiple finalizers of a fixture raise an exception, now all exceptions are reported as an exception group. Previously, only the first exception was reported.
#11904: Fixed a regression in pytest 8.0.0 that would cause test collection to fail due to permission errors when using --pyargs.
This change improves the collection tree for tests specified using --pyargs, see 12043{.interpreted-text role="pull"} for a comparison with pytest 8.0 and <8.
#12011: Fixed a regression in 8.0.1 whereby setup_module xunit-style fixtures are not executed when --doctest-modules is passed.
#12014: Fix the stacklevel used when warning about marks used on fixtures.
#12039: Fixed a regression in 8.0.2 where tests created using tmp_path{.interpreted-text role="fixture"} have been collected multiple times in CI under Windows.
tmp_path fixture in more detail.FixtureManager._getautousenames() now takes a Node itself instead of the nodeid.FixtureManager.getfixturedefs() now takes the Node itself instead of the nodeid._pytest.nodes.iterparentnodeids() function is removed without replacement.
Prefer to traverse the node hierarchy itself instead.
If you really need to, copy the function from the previous pytest release.\#11895: Fix collection on Windows where initial paths contain the short version of a path (for example c:\PROGRA~1\tests).
c:\PROGRA~1\tests).IndexError crash raising from getstatementrange_ast.\#11875: Correctly handle errors from getpass.getuser{.interpreted-text role="func"} in Python 3.13.
getpass.getuser{.interpreted-text role="func"} in Python 3.13.ExceptionInfo._stringify_exception could crash pytest.raises{.interpreted-text role="func"}.pytest.warns{.interpreted-text role="func"} using custom warning subclasses which have more than one parameter in their [__init__]{.title-ref}.pytest.skip{.interpreted-text role="func"} and similar control-flow exceptions within a pytest.warns(){.interpreted-text role="func"} block would get suppressed instead of propagating.#11875 : Correctly handle errors from getpass.getuser() in Python 3.13.
#11879 : Fix an edge case where ExceptionInfo._stringify_exception could crash pytest.raises() .
#11906 : Fix regression with pytest.warns() using custom warning subclasses which have more than one parameter in their init .
#11907 : Fix a regression in pytest 8.0.0 whereby calling pytest.skip() and similar control-flow exceptions within a pytest.warns() block would get suppressed instead of propagating.
#11929 : Fix a regression in pytest 8.0.0 whereby autouse fixtures defined in a module get ignored by the doctests in the module.
#11937 : Fix a regression in pytest 8.0.0 whereby items would be collected in reverse order in some circumstances.
See 8.0.0rc1 and 8.0.0rc2 for the full changes since pytest 7.4!
\#11233: Improvements to -r for xfailures and xpasses:
-r for xfailures and xpasses:
-rx is set.-rX is set.- in summary between test name and reason, to match how xfail is displayed.pytest_plugin_registered{.interpreted-text role="hook"} hook has a new plugin_name parameter containing the name by which plugin is registered.#11706: Fix reporting of teardown errors in higher-scoped fixtures when using [--maxfail]{.title-ref} or [--stepwise]{.title-ref}.
#11758: Fixed IndexError: string index out of range crash in if highlighted[-1] == "\n" and source[-1] != "\n".
This bug was introduced in pytest 8.0.0rc1.
#9765, #11816: Fixed a frustrating bug that afflicted some users with the only error being assert mod not in mods. The issue was caused by the fact that str(Path(mod)) and mod.__file__ don't necessarily produce the same string, and was being erroneously used interchangably in some places in the code.
This fix also broke the internal API of PytestPluginManager.consider_conftest by introducing a new parameter -- we mention this in case it is being used by external code, even if marked as private.
#11233 : Improvements to -r for xfailures and xpasses:
Report tracebacks for xfailures when -rx is set.
Report captured output for xpasses when -rX is set.
For xpasses, add - in summary between test name and reason, to match how xfail is displayed.
#11825 : The pytest_plugin_registered hook has a new plugin_name parameter containing the name by which plugin is registered.
#11706 : Fix reporting of teardown errors in higher-scoped fixtures when using --maxfail or --stepwise .
NOTE: This change was reverted in pytest 8.0.2 to fix a regression it caused in pytest-xdist.
#11758 : Fixed IndexError: string index out of range crash in if highlighted[-1] == "\n" and source[-1] != "\n" . This bug was introduced in pytest 8.0.0rc1.
#9765 , #11816 : Fixed a frustrating bug that afflicted some users with the only error being assert mod not in mods . The issue was caused by the fact that str(Path(mod)) and mod.file don’t necessarily produce the same string, and was being erroneously used interchangeably in some places in the code.
This fix also broke the internal API of PytestPluginManager.consider_conftest by introducing a new parameter – we mention this in case it is being used by external code, even if marked as private .
In this version we\'ve made several breaking changes to pytest\'s collection phase, particularly around how filesystem directories and Python packages…
See https://docs.pytest.org/en/latest/changelog.html#pytest-8-0-0rc1-2023-12-30 for the rendered changelog.
#7363: PytestRemovedIn8Warning deprecation warnings are now errors by default.
Following our plan to remove deprecated features with as little disruption as possible, all warnings of type PytestRemovedIn8Warning now generate errors instead of warning messages by default.
The affected features will be effectively removed in pytest 8.1, so please consult the deprecations{.interpreted-text role="ref"} section in the docs for directions on how to update existing code.
In the pytest 8.0.X series, it is possible to change the errors back into warnings as a stopgap measure by adding this to your pytest.ini file:
[pytest]
filterwarnings =
ignore::pytest.PytestRemovedIn8Warning
But this will stop working when pytest 8.1 is released.
If you have concerns about the removal of a specific feature, please add a comment to 7363{.interpreted-text role="issue"}.
pluggy>=1.3.0 is now required.In this version we've made several breaking changes to pytest's collection phase, particularly around how filesystem directories and Python packages are collected, fixing deficiencies and allowing for cleanups and improvements to pytest's internals. A deprecation period for these changes was not possible.
#7777: Files and directories are now collected in alphabetical order jointly, unless changed by a plugin. Previously, files were collected before directories. See below for an example.
#8976: Running [pytest pkg/__init__.py]{.title-ref} now collects the [pkg/__init__.py]{.title-ref} file (module) only.
Previously, it collected the entire [pkg]{.title-ref} package, including other test files in the directory, but excluding tests in the [__init__.py]{.title-ref} file itself
(unless python_files{.interpreted-text role="confval"} was changed to allow [__init__.py]{.title-ref} file).
To collect the entire package, specify just the directory: [pytest pkg]{.title-ref}.
#11137: pytest.Package{.interpreted-text role="class"} is no longer a pytest.Module{.interpreted-text role="class"} or pytest.File{.interpreted-text role="class"}.
The Package collector node designates a Python package, that is, a directory with an [__init__.py]{.title-ref} file.
Previously Package was a subtype of pytest.Module (which represents a single Python module), the module being the [__init__.py]{.title-ref} file.
This has been deemed a design mistake (see 11137{.interpreted-text role="issue"} and 7777{.interpreted-text role="issue"} for details).
The path property of Package nodes now points to the package directory instead of the __init__.py file.
Note that a Module node for __init__.py (which is not a Package) may still exist, if it is picked up during collection (e.g. if you configured python_files{.interpreted-text role="confval"} to include __init__.py files).
#7777: Added a new pytest.Directory{.interpreted-text role="class"} base collection node, which all collector nodes for filesystem directories are expected to subclass.
This is analogous to the existing pytest.File{.interpreted-text role="class"} for file nodes.
Changed pytest.Package{.interpreted-text role="class"} to be a subclass of pytest.Directory{.interpreted-text role="class"}.
A Package represents a filesystem directory which is a Python package,
i.e. contains an __init__.py file.
pytest.Package{.interpreted-text role="class"} now only collects files in its own directory; previously it collected recursively.
Sub-directories are collected as their own collector nodes, which then collect themselves, thus creating a collection tree which mirrors the filesystem hierarchy.
Added a new pytest.Dir{.interpreted-text role="class"} concrete collection node, a subclass of pytest.Directory{.interpreted-text role="class"}.
This node represents a filesystem directory, which is not a pytest.Package{.interpreted-text role="class"}, that is, does not contain an __init__.py file. Similarly to Package, it only collects the files in its own directory.
pytest.Session{.interpreted-text role="class"} now only collects the initial arguments, without recursing into directories.
This work is now done by the recursive expansion process <pytest.Collector.collect>{.interpreted-text role="func"} of directory collector nodes.
session.name <pytest.Session.name>{.interpreted-text role="attr"} is now ""; previously it was the rootdir directory name.
This matches session.nodeid <_pytest.nodes.Node.nodeid>{.interpreted-text role="attr"} which has always been [""]{.title-ref}.
The collection tree now contains directories/packages up to the rootdir <rootdir>{.interpreted-text role="ref"}, for initial arguments that are found within the rootdir.
For files outside the rootdir, only the immediate directory/package is collected --note however that collecting from outside the rootdir is discouraged.
As an example, given the following filesystem tree:
myroot/
pytest.ini
top/
├── aaa
│ └── test_aaa.py
├── test_a.py
├── test_b
│ ├── __init__.py
│ └── test_b.py
├── test_c.py
└── zzz
├── __init__.py
└── test_zzz.py
the collection tree, as shown by [pytest --collect-only top/]{.title-ref} but with the otherwise-hidden ~pytest.Session{.interpreted-text role="class"} node added for clarity, is now the following:
<Session>
<Dir myroot>
<Dir top>
<Dir aaa>
<Module test_aaa.py>
<Function test_it>
<Module test_a.py>
<Function test_it>
<Package test_b>
<Module test_b.py>
<Function test_it>
<Module test_c.py>
<Function test_it>
<Package zzz>
<Module test_zzz.py>
<Function test_it>
Previously, it was:
<Session>
<Module top/test_a.py>
<Function test_it>
<Module top/test_c.py>
<Function test_it>
<Module top/aaa/test_aaa.py>
<Function test_it>
<Package test_b>
<Module test_b.py>
<Function test_it>
<Package zzz>
<Module test_zzz.py>
<Function test_it>
Code/plugins which rely on a specific shape of the collection tree might need to update.
#11676: The classes ~_pytest.nodes.Node{.interpreted-text role="class"}, ~pytest.Collector{.interpreted-text role="class"}, ~pytest.Item{.interpreted-text role="class"}, ~pytest.File{.interpreted-text role="class"}, ~_pytest.nodes.FSCollector{.interpreted-text role="class"} are now marked abstract (see abc{.interpreted-text role="mod"}).
We do not expect this change to affect users and plugin authors, it will only cause errors when the code is already wrong or problematic.
These are breaking changes where deprecation was not possible.
#11282: Sanitized the handling of the default parameter when defining configuration options.
Previously if default was not supplied for parser.addini <pytest.Parser.addini>{.interpreted-text role="meth"} and the configuration option value was not defined in a test session, then calls to config.getini <pytest.Config.getini>{.interpreted-text role="func"} returned an empty list or an empty string depending on whether type was supplied or not respectively, which is clearly incorrect. Also, None was not honored even if default=None was used explicitly while defining the option.
Now the behavior of parser.addini <pytest.Parser.addini>{.interpreted-text role="meth"} is as follows:
default is NOT passed but type is provided, then a type-specific default will be returned. For example type=bool will return False, type=str will return "", etc.default=None is passed and the option is not defined in a test session, then None will be returned, regardless of the type.default nor type are provided, assume type=str and return "" as default (this is as per previous behavior).The team decided to not introduce a deprecation period for this change, as doing so would be complicated both in terms of communicating this to the community as well as implementing it, and also because the team believes this change should not break existing plugins except in rare cases.
#11667: pytest's setup.py file is removed.
If you relied on this file, e.g. to install pytest using setup.py install, please see Why you shouldn't invoke setup.py directly for alternatives.
#9288: ~pytest.warns{.interpreted-text role="func"} now re-emits unmatched warnings when the context closes -- previously it would consume all warnings, hiding those that were not matched by the function.
While this is a new feature, we announce it as a breaking change because many test suites are configured to error-out on warnings, and will therefore fail on the newly-re-emitted warnings.
#10465: Test functions returning a value other than None will now issue a pytest.PytestWarning{.interpreted-text role="class"} instead of pytest.PytestRemovedIn8Warning{.interpreted-text role="class"}, meaning this will stay a warning instead of becoming an error in the future.
#3664: Applying a mark to a fixture function now issues a warning: marks in fixtures never had any effect, but it is a common user error to apply a mark to a fixture (for example usefixtures) and expect it to work.
This will become an error in pytest 9.0.
These changes improve the diffs that pytest prints when an assertion fails.
Note that syntax highlighting requires the pygments package.
#11520: The very verbose (-vv) diff output is now colored as a diff instead of a big chunk of red.
Python code in error reports is now syntax-highlighted as Python.
The sections in the error reports are now better separated.
#1531: The very verbose diff (-vv) for every standard library container type is improved. The indentation is now consistent and the markers are on their own separate lines, which should reduce the diffs shown to users.
Previously, the standard Python pretty printer was used to generate the output, which puts opening and closing markers on the same line as the first/last entry, in addition to not having consistent indentation.
#10617: Added more comprehensive set assertion rewrites for comparisons other than equality ==, with the following operations now providing better failure messages: !=, <=, >=, <, and >.
#11387: Added the new verbosity_assertions{.interpreted-text role="confval"} configuration option for fine-grained control of failed assertions verbosity.
If you've ever wished that pytest always show you full diffs, but without making everything else verbose, this is for you.
See Fine-grained verbosity <pytest.fine_grained_verbosity>{.interpreted-text role="ref"} for more details.
For plugin authors, config.get_verbosity <pytest.Config.get_verbosity>{.interpreted-text role="attr"} can be used to retrieve the verbosity level for a specific verbosity type.
__notes__These changes improve pytest's support for exception groups.
#10441: Added ExceptionInfo.group_contains() <pytest.ExceptionInfo.group_contains>{.interpreted-text role="func"}, an assertion helper that tests if an ExceptionGroup{.interpreted-text role="class"} contains a matching exception.
See assert-matching-exception-groups{.interpreted-text role="ref"} for an example.
#11227: Allow pytest.raises{.interpreted-text role="func"} match argument to match against [PEP-678 <https://peps.python.org/pep-0678/>]{.title-ref} __notes__.
pytest_collect_directory{.interpreted-text role="hook"},
which is called by filesystem-traversing collector nodes, such as pytest.Session{.interpreted-text role="class"}, pytest.Dir{.interpreted-text role="class"} and pytest.Package{.interpreted-text role="class"}, to create a collector node for a sub-directory.
It is expected to return a subclass of pytest.Directory{.interpreted-text role="class"}.
This hook allows plugins to customize the collection of directories <custom directory collectors>{.interpreted-text role="ref"}.#11122: pytest now uses "new-style" hook wrappers internally, available since pluggy 1.2.0.
See pluggy's 1.2.0 changelog and the updated docs <hookwrapper>{.interpreted-text role="ref"} for details.
Plugins which want to use new-style wrappers can do so if they require pytest>=8.
xunit setup fixture <classic xunit>{.interpreted-text role="ref"}, the test summary now shows the test location instead of the fixture location.--log-file option will use --log-level, --log-format and --log-date-format as fallback
if --log-file-level, --log-file-format and --log-file-date-format are not provided respectively.LogCaptureFixture.filtering() <pytest.LogCaptureFixture.filtering>{.interpreted-text role="func"} context manager which
adds a given logging.Filter{.interpreted-text role="class"} object to the caplog{.interpreted-text role="fixture"} fixture.pytest.deprecated_call{.interpreted-text role="func"} now also considers warnings of type FutureWarning{.interpreted-text role="class"}.pytest.mark.xfail <pytest.mark.xfail>{.interpreted-text role="func"}'s condition param to use False as the default value.~pytest.FixtureDef{.interpreted-text role="class"} is now exported as pytest.FixtureDef for typing purposes.~pytest.PytestPluginManager{.interpreted-text role="class"}.pytest.WarningsRecorder.pop{.interpreted-text role="meth"} will return the most-closely-matched warning in the list,
rather than the first warning which is an instance of the requested type.a, a, a0 now results in a1, a2, a0 instead of the previous (buggy) a0, a1, a0.
This necessarily means changing nodeids where these were previously colliding, and for
readability adds an underscore when non-unique ids end in a number.NO_COLOR and FORCE_COLOR to ignore an empty value.pytest.warns and similar functions now capture warnings when an exception is raised inside a with block.caplog.pytestconfig instead of request.config in cache example to be consistent with the API documentation.#11208: The (internal) FixtureDef.cached_result type has changed.
Now the third item cached_result[2], when set, is an exception instance instead of an exception triplet.
#11218: (This entry is meant to assist plugins which access private pytest internals to instantiate FixtureRequest objects.)
~pytest.FixtureRequest{.interpreted-text role="class"} is now an abstract class which can't be instantiated directly.
A new concrete TopRequest subclass of FixtureRequest has been added for the request fixture in test functions, as counterpart to the existing SubRequest subclass for the request fixture in fixture functions.
#11315: The pytester{.interpreted-text role="fixture"} fixture now uses the monkeypatch{.interpreted-text role="fixture"} fixture to manage the current working directory.
If you use pytester in combination with monkeypatch.undo() <pytest.MonkeyPatch.undo>{.interpreted-text role="func"}, the CWD might get restored.
Use monkeypatch.context() <pytest.MonkeyPatch.context>{.interpreted-text role="func"} instead.
#11333: Corrected the spelling of Config.ArgsSource.INVOCATION_DIR.
The previous spelling INCOVATION_DIR remains as an alias.
#11638: Fixed the selftests to pass correctly if FORCE_COLOR, NO_COLOR or PY_COLORS is set in the calling environment.
## Bug Fixes - #11140: Fix non-string constants at the top of file being detected as docstrings on Python\>=3.8. - #11572: Handle an edge case where s
sys.stderr{.interpreted-text role="data"} and sys.__stderr__{.interpreted-text role="data"} might already be closed when faulthandler{.interpreted-text role="ref"} is tearing down.__iter__ methods. Now they are treated un-iterable instead.--junitxml with --junit-xml and --collectonly with --collect-only.Bug Fixes --------- - #10447: Markers are now considered in the reverse mro order to ensure base class markers are considered first -- this resolves a
[#10447](https://github.com/pytest-dev/pytest/issues/10447): Markers are now considered in the reverse mro order to ensure base class markers are considered first -- this resolves a regression.
[#11239](https://github.com/pytest-dev/pytest/issues/11239): Fixed := in asserts impacting unrelated test cases.
[#11439](https://github.com/pytest-dev/pytest/issues/11439): Handled an edge case where sys.stderr might already be closed when faulthandler is tearing down.
# Bug Fixes - #11237: Fix doctest collection of functools.cached_property objects. - #11306: Fixed bug using --importmode=importlib which would cause
#11237: Fix doctest collection of functools.cached_property objects.
#11306: Fixed bug using --importmode=importlib which would cause package __init__.py files to be imported more than once in some cases.
#11367: Fixed bug where user_properties where not being saved in the JUnit XML file if a fixture failed during teardown.
#11394: Fixed crash when parsing long command line arguments that might be interpreted as files.
Bug Fixes --------- - #10337: Fixed bug where fake intermediate modules generated by --import-mode=importlib would not include the child modules as at
#10337: Fixed bug where fake intermediate modules generated by --import-mode=importlib would not include the
child modules as attributes of the parent modules.
#10702: Fixed error assertion handling in pytest.approx when None is an expected or received value when comparing dictionaries.
#10811: Fixed issue when using --import-mode=importlib together with --doctest-modules that caused modules
to be imported more than once, causing problems with modules that have import side effects.
\#10901: Added ExceptionInfo.from_exception() {.interpreted-text role="func"}, a simpler way to create an ~pytest.ExceptionInfo{.interpreted-text role
ExceptionInfo.from_exception() <pytest.ExceptionInfo.from_exception>{.interpreted-text role="func"}, a simpler way to create an ~pytest.ExceptionInfo{.interpreted-text role="class"} from an exception.
This can replace ExceptionInfo.from_exc_info() <pytest.ExceptionInfo.from_exc_info()>{.interpreted-text role="func"} for most uses.#10872: Update test log report annotation to named tuple and fixed inconsistency in docs for pytest_report_teststatus{.interpreted-text role="hook"} hook.
#10907: When an exception traceback to be displayed is completely filtered out (by mechanisms such as __tracebackhide__, internal frames, and similar), now only the exception string and the following message are shown:
"All traceback entries are hidden. Pass [--full-trace]{.title-ref} to see hidden and internal frames.".
Previously, the last frame of the traceback was shown, even though it was hidden.
#10940: Improved verbose output (-vv) of skip and xfail reasons by performing text wrapping while leaving a clear margin for progress output.
Added TerminalReporter.wrap_write() as a helper for that.
#10991: Added handling of %f directive to print microseconds in log format options, such as log-date-format.
#11005: Added the underlying exception to the cache provider's path creation and write warning messages.
#11013: Added warning when testpaths{.interpreted-text role="confval"} is set, but paths are not found by glob. In this case, pytest will fall back to searching from the current directory.
#11043: When [--confcutdir]{.title-ref} is not specified, and there is no config file present, the conftest cutoff directory ([--confcutdir]{.title-ref}) is now set to the rootdir <rootdir>{.interpreted-text role="ref"}.
Previously in such cases, [conftest.py]{.title-ref} files would be probed all the way to the root directory of the filesystem.
If you are badly affected by this change, consider adding an empty config file to your desired cutoff directory, or explicitly set [--confcutdir]{.title-ref}.
#11081: The norecursedirs{.interpreted-text role="confval"} check is now performed in a pytest_ignore_collect{.interpreted-text role="hook"} implementation, so plugins can affect it.
If after updating to this version you see that your [norecursedirs]{.title-ref} setting is not being respected, it means that a conftest or a plugin you use has a bad [pytest_ignore_collect]{.title-ref} implementation. Most likely, your hook returns [False]{.title-ref} for paths it does not want to ignore, which ends the processing and doesn't allow other plugins, including pytest itself, to ignore the path. The fix is to return [None]{.title-ref} instead of [False]{.title-ref} for paths your hook doesn't want to ignore.
#8711: caplog.set_level() <pytest.LogCaptureFixture.set_level>{.interpreted-text role="func"} and caplog.at_level() <pytest.LogCaptureFixture.at_level>{.interpreted-text role="func"}
will temporarily enable the requested level if level was disabled globally via
logging.disable(LEVEL).
--tb=line mode where pytest.fail(pytrace=False) tests report None.--last-failed whole-file skipping functionality ("skipped N files") for non-python test files <non-python tests>{.interpreted-text role="ref"}.testpaths{.interpreted-text role="confval"} to be considered for loading initial conftests,
even when it was not utilized (e.g. when explicit paths were given on the command line).
Now the testpaths are only considered when they are in use.__tracebackhide__ = True still being shown for chained exceptions (parts after "... the above exception ..." message).--debug.caplog.set_level() <pytest.LogCaptureFixture.set_level>{.interpreted-text role="func"}.-c to now include --config-file to make it clear that this flag applies to the usage of a custom config file.\#10169: Fix bug where very long option names could cause pytest to break with OSError: [Errno 36] File name too long on some systems.
OSError: [Errno 36] File name too long on some systems.testpaths{.interpreted-text role="confval"} is now honored to load root conftests.--last-failed's "(skipped N files)" functionality for files inside of packages (directories with [__init__.py]{.title-ref} files).\#10890: Python 3.12 support: fixed shutil.rmtree(onerror=...) deprecation warning when using tmp_path{.interpreted-text role="fixture"}.
RuntimeError: TestResult has no addDuration method when running unittest tests.shutil.rmtree(onerror=...) deprecation warning when using tmp_path{.interpreted-text role="fixture"}.tmp_path{.interpreted-text role="fixture"} and the new tmp_path_retention_policy{.interpreted-text role="confval"} option.INTERNALERROR IndexError: list index out of range which happens when displaying an exception where all entries are hidden.
This reverts the change "Correctly handle __tracebackhide__ for chained exceptions." introduced in version 7.3.0.\#10525: Test methods decorated with @classmethod can now be discovered as tests, following the same rules as normal methods. This fills the gap that
@classmethod can now be discovered as tests, following the same rules as normal methods. This fills the gap that static methods were discoverable as tests but not class methods.console_output_style{.interpreted-text role="confval"} now supports progress-even-when-capture-no to force the use of the progress output even when capture is disabled. This is useful in large test suites where capture may have significant performance impact.--log-disable CLI option added to disable individual loggers.tmp_path_retention_count{.interpreted-text role="confval"} and tmp_path_retention_policy{.interpreted-text role="confval"} configuration options to control how directories created by the tmp_path{.interpreted-text role="fixture"} fixture are kept.ExceptionGroup of them instead of discarding all but the last.-p arguments to include spaces (eg: -p no:logging instead of
-pno:logging). Mostly useful in the addopts section of the configuration
file.start and stop timestamps to TestReport objects.rootdir, config file and testpaths so each has its own line.tmp_path{.interpreted-text role="fixture"} fixture always raising OSError{.interpreted-text role="class"} on emscripten platform due to missing os.getuid{.interpreted-text role="func"}.__tracebackhide__ for chained exceptions.goodpractices{.interpreted-text role="ref"}: pip install -e . requires a version entry in pyproject.toml to run successfully.#10525 : Test methods decorated with @classmethod can now be discovered as tests, following the same rules as normal methods. This fills the gap that static methods were discoverable as tests but not class methods.
#10755 : console_output_style now supports progress-even-when-capture-no to force the use of the progress output even when capture is disabled. This is useful in large test suites where capture may have significant performance impact.
#7431 : --log-disable CLI option added to disable individual loggers.
#8141 : Added tmp_path_retention_count and tmp_path_retention_policy configuration options to control how directories created by the tmp_path fixture are kept.
#10226 : If multiple errors are raised in teardown, we now re-raise an ExceptionGroup of them instead of discarding all but the last.
#10658 : Allow -p arguments to include spaces (eg: -p no:logging instead of -pno:logging ). Mostly useful in the addopts section of the configuration file.
#10710 : Added start and stop timestamps to TestReport objects.
#10727 : Split the report header for rootdir , config file and testpaths so each has its own line.
#10840 : pytest should no longer crash on AST with pathological position attributes, for example testing AST produced by Hylang https://github.com/hylang/hy__ .
#6267 : The full output of a test is no longer truncated if the truncation message would be longer than the hidden text. The line number shown has also been fixed.
#10743 : The assertion rewriting mechanism now works correctly when assertion expressions contain the walrus operator.
#10765 : Fixed tmp_path fixture always raising OSError on emscripten platform due to missing os.getuid() .
#1904 : Correctly handle tracebackhide for chained exceptions. NOTE: This change was reverted in version 7.3.1.
#10782 : Fixed the minimal example in Good Integration Practices : pip install -e . requires a version entry in pyproject.toml to run successfully.
#10669 : pytest no longer directly depends on the attrs package. While we at pytest all love the package dearly and would like to thank the attrs team for many years of cooperation and support, it makes sense for pytest to have as little external dependencies as possible, as this helps downstream projects. With that in mind, we have replaced the pytest’s limited internal usage to use the standard library’s dataclasses instead.
Nice diffs for attrs classes are still supported though.
\#10533: Fixed pytest.approx{.interpreted-text role="func"} handling of dictionaries containing one or more values of [0.0]{.title-ref}.
pytest.approx{.interpreted-text role="func"} handling of dictionaries containing one or more values of [0.0]{.title-ref}.teardown would be called as part of nose teardown stage.--fixtures and --help are passed at the same time.pytest.raises{.interpreted-text role="func"} to return a 'ContextManager' so that type-checkers could narrow
pytest.raises(...) if ... else nullcontext() down to 'ContextManager' rather than 'object'.#10533 : Fixed pytest.approx() handling of dictionaries containing one or more values of 0.0 .
#10592 : Fixed crash if --cache-show and --help are passed at the same time.
#10597 : Fixed bug where a fixture method named teardown would be called as part of nose teardown stage.
#10626 : Fixed crash if --fixtures and --help are passed at the same time.
#10660 : Fixed pytest.raises() to return a ‘ContextManager’ so that type-checkers could narrow pytest.raises(...) if ... else nullcontext() down to ‘ContextManager’ rather than ‘object’.
#10690 : Added CI and BUILD_NUMBER environment variables to the documentation.
#10721 : Fixed entry-points declaration in the documentation example using Hatch.
#10753 : Changed wording of the module level skip to be very explicit about not collecting tests and not executing the rest of the module.
\#10452: Fix \'importlib.abc.TraversableResources\' deprecation warning in Python 3.12.
rootdir <rootdir>{.interpreted-text role="ref"} on Windows.\#10012: Update pytest.PytestUnhandledCoroutineWarning{.interpreted-text role="class"} to a deprecation; it will raise an error in pytest 8.
#10012: Update pytest.PytestUnhandledCoroutineWarning{.interpreted-text role="class"} to a deprecation; it will raise an error in pytest 8.
#10396: pytest no longer depends on the py library. pytest provides a vendored copy of py.error and py.path modules but will use the py library if it is installed. If you need other py.* modules, continue to install the deprecated py library separately, otherwise it can usually be removed as a dependency.
#4562: Deprecate configuring hook specs/impls using attributes/marks.
Instead use :pypytest.hookimpl{.interpreted-text role="func"} and :pypytest.hookspec{.interpreted-text role="func"}.
For more details, see the docs <legacy-path-hooks-deprecated>{.interpreted-text role="ref"}.
#9886: The functionality for running tests written for nose has been officially deprecated.
This includes:
setup and teardown functions and methods: this might catch users by surprise, as setup() and teardown() are not pytest idioms, but part of the nose support.For more details, consult the deprecation docs <nose-deprecation>{.interpreted-text role="ref"}.
testpaths.#10218: @pytest.mark.parametrize() (and similar functions) now accepts any Sequence[str] for the argument names,
instead of just list[str] and tuple[str, ...].
(Note that str, which is itself a Sequence[str], is still treated as a
comma-delimited name list, as before).
#10381: The --no-showlocals flag has been added. This can be passed directly to tests to override --showlocals declared through addopts.
#3426: Assertion failures with strings in NFC and NFD forms that normalize to the same string now have a dedicated error message detailing the issue, and their utf-8 representation is expresed instead.
#7337: A warning is now emitted if a test function returns something other than [None]{.title-ref}. This prevents a common mistake among beginners that expect that returning a [bool]{.title-ref} (for example [return foo(a, b) == result]{.title-ref}) would cause a test to pass or fail, instead of using [assert]{.title-ref}.
#8508: Introduce multiline display for warning matching via :pypytest.warns{.interpreted-text role="func"} and
enhance match comparison for :py_pytest._code.ExceptionInfo.match{.interpreted-text role="func"} as returned by :pypytest.raises{.interpreted-text role="func"}.
#8646: Improve :pypytest.raises{.interpreted-text role="func"}. Previously passing an empty tuple would give a confusing
error. We now raise immediately with a more helpful message.
#9741: On Python 3.11, use the standard library's tomllib{.interpreted-text role="mod"} to parse TOML.
tomli{.interpreted-text role="mod"}` is no longer a dependency on Python 3.11.
#9742: Display assertion message without escaped newline characters with -vv.
#9823: Improved error message that is shown when no collector is found for a given file.
#9873: Some coloring has been added to the short test summary.
#9883: Normalize the help description of all command-line options.
#9920: Display full crash messages in short test summary info, when runng in a CI environment.
#9987: Added support for hidden configuration file by allowing .pytest.ini as an alternative to pytest.ini.
#10150: sys.stdin{.interpreted-text role="data"} now contains all expected methods of a file-like object when capture is enabled.
#10382: Do not break into pdb when raise unittest.SkipTest() appears top-level in a file.
#7792: Marks are now inherited according to the full MRO in test classes. Previously, if a test class inherited from two or more classes, only marks from the first super-class would apply.
When inheriting marks from super-classes, marks from the sub-classes are now ordered before marks from the super-classes, in MRO order. Previously it was the reverse.
When inheriting marks from super-classes, the [pytestmark]{.title-ref} attribute of the sub-class now only contains the marks directly applied to it. Previously, it also contained marks from its super-classes. Please note that this attribute should not normally be accessed directly; use pytest.Node.iter_markers{.interpreted-text role="func"} instead.
#9159: Showing inner exceptions by forcing native display in ExceptionGroups even when using display options other than --tb=native. A temporary step before full implementation of pytest-native display for inner exceptions in ExceptionGroups.
#9877: Ensure caplog.get_records(when) returns current/correct data after invoking caplog.clear().
pyproject.toml instead of setup.py.pytest.warns{.interpreted-text role="func"} affects DeprecationWarning{.interpreted-text role="class"}.~pytest.PytestReturnNotNoneWarning{.interpreted-text role="class"} is now a subclass of ~pytest.PytestRemovedIn8Warning{.interpreted-text role="class"}: the plan is to make returning non-None from tests an error in the future._pytest.doctest.DoctestItem export pytest.DoctestItem for
type check and runtime purposes. Made [_pytest.doctest]{.title-ref} use internal APIs
to avoid circular imports._pytest.compat re-export importlib_metadata in the eyes of type checkers.EncodingWarning) in cacheprovider\#10060: When running with --pdb, TestCase.tearDown is no longer called for tests when the *class* has been skipped via unittest.skip or pytest.mark.s
--pdb, TestCase.tearDown is no longer called for tests when the class has been skipped via unittest.skip or pytest.mark.skip..py files created by pyproject.toml-based editable builds introduced in pip 21.3.--import-mode flag.FixtureRequest.param as Any as a stop gap measure until 8073{.interpreted-text role="issue"} is fixed.rewrite.py that seems to work fine, but was incorrect and fails in some systems.pytest.approx{.interpreted-text role="func"} when used to compare tuples.tmpdir{.interpreted-text role="fixture"} fixture is discouraged in favour of tmp_path{.interpreted-text role="fixture"}.\#9869: Increase stacklevel for the NODE_CTOR_FSPATH_ARG deprecation to point to the user\'s code, not pytest.
numpy import inside pytest.approx{.interpreted-text role="func"} was removed.dataclasses with InitVar.stacklevel for the NODE_CTOR_FSPATH_ARG deprecation to point to the
user's code, not pytest.\#9767: Fixed a regression in pytest 7.1.0 where some conftest.py files outside of the source tree (e.g. in the [site-packages]{.title-ref} directory)
\#8838: As per our policy, the following features have been deprecated in the 6.X series and are now removed:
#8838: As per our policy, the following features have been deprecated in the 6.X series and are now removed:
pytest._fillfuncargs function.pytest_warning_captured hook - use pytest_warning_recorded instead.-k -foobar syntax - use -k 'not foobar' instead.-k foobar: syntax.pytest.collect module - import from pytest directly.For more information consult Deprecations and Removals in the docs.
#9437: Dropped support for Python 3.6, which reached end-of-life at 2021-12-23.
#5192: Fixed test output for some data types where -v would show less information.
Also, when showing diffs for sequences, -q would produce full diffs instead of the expected diff.
#9362: pytest now avoids specialized assert formatting when it is detected that the default __eq__ is overridden in attrs or dataclasses.
#9536: When -vv is given on command line, show skipping and xfail reasons in full instead of truncating them to fit the terminal width.
#9644: More information about the location of resources that led Python to raise ResourceWarning{.interpreted-text role="class"} can now
be obtained by enabling tracemalloc{.interpreted-text role="mod"}.
See resource-warnings{.interpreted-text role="ref"} for more information.
#9678: More types are now accepted in the ids argument to @pytest.mark.parametrize.
Previously only [str]{.title-ref}, [float]{.title-ref}, [int]{.title-ref} and [bool]{.title-ref} were accepted;
now [bytes]{.title-ref}, [complex]{.title-ref}, [re.Pattern]{.title-ref}, [Enum]{.title-ref} and anything with a [__name__]{.title-ref} are also accepted.
#9692: pytest.approx{.interpreted-text role="func"} now raises a TypeError{.interpreted-text role="class"} when given an unordered sequence (such as set{.interpreted-text role="class"}).
Note that this implies that custom classes which only implement __iter__ and __len__ are no longer supported as they don't guarantee order.
#8242: The deprecation of raising unittest.SkipTest{.interpreted-text role="class"} to skip collection of
tests during the pytest collection phase is reverted - this is now a supported
feature again.
#9493: Symbolic link components are no longer resolved in conftest paths. This means that if a conftest appears twice in collection tree, using symlinks, it will be executed twice. For example, given
tests/real/conftest.py tests/real/test_it.py tests/link -> tests/real
running pytest tests now imports the conftest twice, once as tests/real/conftest.py and once as tests/link/conftest.py.
This is a fix to match a similar change made to test collection itself in pytest 6.0 (see 6523{.interpreted-text role="pull"} for details).
#9626: Fixed count of selected tests on terminal collection summary when there were errors or skipped modules.
If there were errors or skipped modules on collection, pytest would mistakenly subtract those from the selected count.
#9645: Fixed regression where --import-mode=importlib used together with PYTHONPATH{.interpreted-text role="envvar"} or pythonpath{.interpreted-text role="confval"} would cause import errors in test suites.
#9708: pytester{.interpreted-text role="fixture"} now requests a monkeypatch{.interpreted-text role="fixture"} fixture instead of creating one internally. This solves some issues with tests that involve pytest environment variables.
#9730: Malformed pyproject.toml files now produce a clearer error message.
\#9608: Fix invalid importing of importlib.readers in Python 3.9.
importlib.readers in Python 3.9.pythonpath plugin was renamed to python_path. This avoids a conflict with the pytest-pythonpath plugin.:: in the parametrize portion.~pytest.PytestWarning{.interpreted-text role="class"} about diamond inheritance involving ~pytest.Item{.interpreted-text role="class"} and
~pytest.Collector{.interpreted-text role="class"} so it can be filtered using standard warning filters <warnings>{.interpreted-text role="ref"}.#9608 : Fix invalid importing of importlib.readers in Python 3.9.
#9610 : Restore UnitTestFunction.obj to return unbound rather than bound method. Fixes a crash during a failed teardown in unittest TestCases with non-default init . Regressed in pytest 7.0.0.
#9636 : The pythonpath plugin was renamed to python_path . This avoids a conflict with the pytest-pythonpath plugin.
#9642 : Fix running tests by id with :: in the parametrize portion.
#9643 : Delay issuing a PytestWarning about diamond inheritance involving Item and Collector so it can be filtered using standard warning filters .
See uncooperative-constructors-deprecated{.interpreted-text role="ref"} for details.
(Please see the full set of changes for this release also in the 7.0.0rc1 notes below)
#9488: If custom subclasses of nodes like pytest.Item{.interpreted-text role="class"} override the
__init__ method, they should take **kwargs. See
uncooperative-constructors-deprecated{.interpreted-text role="ref"} for details.
Note that a deprection warning is only emitted when there is a conflict in the arguments pytest expected to pass. This deprecation was already part of pytest 7.0.0rc1 but wasn't documented.
pytest.Config.inifile{.interpreted-text role="attr"} is available during the pytest_cmdline_main <_pytest.hookspec.pytest_cmdline_main>{.interpreted-text role="func"} hook (regression during 7.0.0rc1).#7259: The Node.reportinfo() <non-python tests>{.interpreted-text role="ref"} function first return value type has been expanded from [py.path.local | str]{.title-ref} to [os.PathLike[str] | str]{.title-ref}.
Most plugins which refer to [reportinfo()]{.title-ref} only define it as part of a custom pytest.Item{.interpreted-text role="class"} implementation.
Since [py.path.local]{.title-ref} is a [os.PathLike[str]]{.title-ref}, these plugins are unaffacted.
Plugins and users which call [reportinfo()]{.title-ref}, use the first return value and interact with it as a [py.path.local]{.title-ref}, would need to adjust by calling [py.path.local(fspath)]{.title-ref}. Although preferably, avoid the legacy [py.path.local]{.title-ref} and use [pathlib.Path]{.title-ref}, or use [item.location]{.title-ref} or [item.path]{.title-ref}, instead.
Note: pytest was not able to provide a deprecation period for this change.
#8246: --version now writes version information to stdout rather than stderr.
#8733: Drop a workaround for pyreadline that made it work with --pdb.
The workaround was introduced in #1281 in 2015, however since then pyreadline seems to have gone unmaintained, is generating warnings, and will stop working on Python 3.10.
#9061: Using pytest.approx{.interpreted-text role="func"} in a boolean context now raises an error hinting at the proper usage.
It is apparently common for users to mistakenly use pytest.approx like this:
assert pytest.approx(actual, expected)
While the correct usage is:
assert actual == pytest.approx(expected)
The new error message helps catch those mistakes.
#9277: The pytest.Instance collector type has been removed.
Importing pytest.Instance or _pytest.python.Instance returns a dummy type and emits a deprecation warning.
See instance-collector-deprecation{.interpreted-text role="ref"} for details.
#9308: PytestRemovedIn7Warning deprecation warnings are now errors by default.
Following our plan to remove deprecated features with as little disruption as
possible, all warnings of type PytestRemovedIn7Warning now generate errors
instead of warning messages by default.
The affected features will be effectively removed in pytest 7.1, so please consult the
deprecations{.interpreted-text role="ref"} section in the docs for directions on how to update existing code.
In the pytest 7.0.X series, it is possible to change the errors back into warnings as a
stopgap measure by adding this to your pytest.ini file:
[pytest]
filterwarnings =
ignore::pytest.PytestRemovedIn7Warning
But this will stop working when pytest 7.1 is released.
If you have concerns about the removal of a specific feature, please add a
comment to 9308{.interpreted-text role="issue"}.
#7259: py.path.local arguments for hooks have been deprecated. See the deprecation note <legacy-path-hooks-deprecated>{.interpreted-text role="ref"} for full details.
py.path.local arguments to Node constructors have been deprecated. See the deprecation note <node-ctor-fspath-deprecation>{.interpreted-text role="ref"} for full details.
::: {.note} ::: {.admonition-title} Note :::
The name of the ~_pytest.nodes.Node{.interpreted-text role="class"} arguments and attributes (the
new attribute being path) is the opposite of the situation for hooks
(the old argument being path).
This is an unfortunate artifact due to historical reasons, which should be
resolved in future versions as we slowly get rid of the py{.interpreted-text role="pypi"}
dependency (see 9283{.interpreted-text role="issue"} for a longer discussion).
:::
#7469: Directly constructing the following classes is now deprecated:
_pytest.mark.structures.Mark_pytest.mark.structures.MarkDecorator_pytest.mark.structures.MarkGenerator_pytest.python.Metafunc_pytest.runner.CallInfo_pytest._code.ExceptionInfo_pytest.config.argparsing.Parser_pytest.config.argparsing.OptionGroup_pytest.pytester.HookRecorderThese constructors have always been considered private, but now issue a deprecation warning, which may become a hard error in pytest 8.
#8242: Raising unittest.SkipTest{.interpreted-text role="class"} to skip collection of tests during the
pytest collection phase is deprecated. Use pytest.skip{.interpreted-text role="func"} instead.
Note: This deprecation only relates to using unittest.SkipTest{.interpreted-text role="class"} during test
collection. You are probably not doing that. Ordinary usage of
unittest.SkipTest{.interpreted-text role="class"} / unittest.TestCase.skipTest{.interpreted-text role="meth"} /
unittest.skip{.interpreted-text role="func"} in unittest test cases is fully supported.
#8315: Several behaviors of Parser.addoption <pytest.Parser.addoption>{.interpreted-text role="meth"} are now
scheduled for removal in pytest 8 (deprecated since pytest 2.4.0):
parser.addoption(..., help=".. %default ..") - use %(default)s instead.parser.addoption(..., type="int/string/float/complex") - use type=int etc. instead.#8447: Defining a custom pytest node type which is both an pytest.Item <Item>{.interpreted-text role="class"} and a pytest.Collector <Collector>{.interpreted-text role="class"} (e.g. pytest.File <File>{.interpreted-text role="class"}) now issues a warning.
It was never sanely supported and triggers hard to debug errors.
See the deprecation note <diamond-inheritance-deprecated>{.interpreted-text role="ref"} for full details.
#8592: pytest_cmdline_preparse{.interpreted-text role="hook"} has been officially deprecated. It will be removed in a future release. Use pytest_load_initial_conftests{.interpreted-text role="hook"} instead.
See the deprecation note <cmdline-preparse-deprecated>{.interpreted-text role="ref"} for full details.
#8645: pytest.warns(None) <pytest.warns>{.interpreted-text role="func"} is now deprecated because many people used
it to mean "this code does not emit warnings", but it actually had the effect of
checking that the code emits at least one warning of any type - like pytest.warns()
or pytest.warns(Warning).
#8948: pytest.skip(msg=...) <pytest.skip>{.interpreted-text role="func"}, pytest.fail(msg=...) <pytest.fail>{.interpreted-text role="func"} and pytest.exit(msg=...) <pytest.exit>{.interpreted-text role="func"}
signatures now accept a reason argument instead of msg. Using msg still works, but is deprecated and will be removed in a future release.
This was changed for consistency with pytest.mark.skip <pytest.mark.skip>{.interpreted-text role="func"} and pytest.mark.xfail <pytest.mark.xfail>{.interpreted-text role="func"} which both accept
reason as an argument.
#8174: The following changes have been made to types reachable through pytest.ExceptionInfo.traceback{.interpreted-text role="attr"}:
path property of _pytest.code.Code returns Path instead of py.path.local.path property of _pytest.code.TracebackEntry returns Path instead of py.path.local.There was no deprecation period for this change (sorry!).
#5196: Tests are now ordered by definition order in more cases.
In a class hierarchy, tests from base classes are now consistently ordered before tests defined on their subclasses (reverse MRO order).
#7132: Added two environment variables PYTEST_THEME{.interpreted-text role="envvar"} and PYTEST_THEME_MODE{.interpreted-text role="envvar"} to let the users customize the pygments theme used.
#7259: Added cache.mkdir() <pytest.Cache.mkdir>{.interpreted-text role="meth"}, which is similar to the existing cache.makedir() <pytest.Cache.makedir>{.interpreted-text role="meth"},
but returns a pathlib.Path{.interpreted-text role="class"} instead of a legacy py.path.local.
Added a paths type to parser.addini() <pytest.Parser.addini>{.interpreted-text role="meth"},
as in parser.addini("mypaths", "my paths", type="paths"),
which is similar to the existing pathlist,
but returns a list of pathlib.Path{.interpreted-text role="class"} instead of legacy py.path.local.
#7469: The types of objects used in pytest's API are now exported so they may be used in type annotations.
The newly-exported types are:
pytest.Config for Config <pytest.Config>{.interpreted-text role="class"}.pytest.Mark for marks <pytest.Mark>{.interpreted-text role="class"}.pytest.MarkDecorator for mark decorators <pytest.MarkDecorator>{.interpreted-text role="class"}.pytest.MarkGenerator for the pytest.mark <pytest.MarkGenerator>{.interpreted-text role="class"} singleton.pytest.Metafunc for the metafunc <pytest.MarkGenerator>{.interpreted-text role="class"} argument to the pytest_generate_tests{.interpreted-text role="hook"} hook.pytest.CallInfo for the CallInfo <pytest.CallInfo>{.interpreted-text role="class"} type passed to various hooks.pytest.PytestPluginManager for PytestPluginManager <pytest.PytestPluginManager>{.interpreted-text role="class"}.pytest.ExceptionInfo for the ExceptionInfo <pytest.ExceptionInfo>{.interpreted-text role="class"} type returned from pytest.raises{.interpreted-text role="func"} and passed to various hooks.pytest.Parser for the Parser <pytest.Parser>{.interpreted-text role="class"} type passed to the pytest_addoption{.interpreted-text role="hook"} hook.pytest.OptionGroup for the OptionGroup <pytest.OptionGroup>{.interpreted-text role="class"} type returned from the parser.addgroup <pytest.Parser.getgroup>{.interpreted-text role="func"} method.pytest.HookRecorder for the HookRecorder <pytest.HookRecorder>{.interpreted-text role="class"} type returned from ~pytest.Pytester{.interpreted-text role="class"}.pytest.RecordedHookCall for the RecordedHookCall <pytest.HookRecorder>{.interpreted-text role="class"} type returned from ~pytest.HookRecorder{.interpreted-text role="class"}.pytest.RunResult for the RunResult <pytest.RunResult>{.interpreted-text role="class"} type returned from ~pytest.Pytester{.interpreted-text role="class"}.pytest.LineMatcher for the LineMatcher <pytest.RunResult>{.interpreted-text role="class"} type used in ~pytest.RunResult{.interpreted-text role="class"} and others.pytest.TestReport for the TestReport <pytest.TestReport>{.interpreted-text role="class"} type used in various hooks.pytest.CollectReport for the CollectReport <pytest.CollectReport>{.interpreted-text role="class"} type used in various hooks.Constructing most of them directly is not supported; they are only meant for use in type annotations. Doing so will emit a deprecation warning, and may become a hard-error in pytest 8.0.
Subclassing them is also not supported. This is not currently enforced at runtime, but is detected by type-checkers such as mypy.
#7856: --import-mode=importlib <import-modes>{.interpreted-text role="ref"} now works with features that
depend on modules being on :pysys.modules{.interpreted-text role="data"}, such as pickle{.interpreted-text role="mod"} and dataclasses{.interpreted-text role="mod"}.
#8144: The following hooks now receive an additional pathlib.Path argument, equivalent to an existing py.path.local argument:
pytest_ignore_collect{.interpreted-text role="hook"} - The collection_path parameter (equivalent to existing path parameter).pytest_collect_file{.interpreted-text role="hook"} - The file_path parameter (equivalent to existing path parameter).pytest_pycollect_makemodule{.interpreted-text role="hook"} - The module_path parameter (equivalent to existing path parameter).pytest_report_header{.interpreted-text role="hook"} - The start_path parameter (equivalent to existing startdir parameter).pytest_report_collectionfinish{.interpreted-text role="hook"} - The start_path parameter (equivalent to existing startdir parameter).::: {.note} ::: {.admonition-title} Note :::
The name of the ~_pytest.nodes.Node{.interpreted-text role="class"} arguments and attributes (the
new attribute being path) is the opposite of the situation for hooks
(the old argument being path).
This is an unfortunate artifact due to historical reasons, which should be
resolved in future versions as we slowly get rid of the py{.interpreted-text role="pypi"}
dependency (see 9283{.interpreted-text role="issue"} for a longer discussion).
:::
#8251: Implement Node.path as a pathlib.Path. Both the old fspath and this new attribute gets set no matter whether path or fspath (deprecated) is passed to the constructor. It is a replacement for the fspath attribute (which represents the same path as py.path.local). While fspath is not deprecated yet
due to the ongoing migration of methods like ~_pytest.Item.reportinfo{.interpreted-text role="meth"}, we expect to deprecate it in a future release.
::: {.note} ::: {.admonition-title} Note :::
The name of the ~_pytest.nodes.Node{.interpreted-text role="class"} arguments and attributes (the
new attribute being path) is the opposite of the situation for hooks
(the old argument being path).
This is an unfortunate artifact due to historical reasons, which should be
resolved in future versions as we slowly get rid of the py{.interpreted-text role="pypi"}
dependency (see 9283{.interpreted-text role="issue"} for a longer discussion).
:::
#8421: pytest.approx{.interpreted-text role="func"} now works on ~decimal.Decimal{.interpreted-text role="class"} within mappings/dicts and sequences/lists.
#8606: pytest invocations with --fixtures-per-test and --fixtures have been enriched with:
--verbose option.#8761: New version-tuple{.interpreted-text role="ref"} attribute, which makes it simpler for users to do something depending on the pytest version (such as declaring hooks which are introduced in later versions).
#8789: Switch TOML parser from toml to tomli for TOML v1.0.0 support in pyproject.toml.
#8920: Added pytest.Stash{.interpreted-text role="class"}, a facility for plugins to store their data on ~pytest.Config{.interpreted-text role="class"} and ~_pytest.nodes.Node{.interpreted-text role="class"}s in a type-safe and conflict-free manner.
See plugin-stash{.interpreted-text role="ref"} for details.
#8953: RunResult <_pytest.pytester.RunResult>{.interpreted-text role="class"} method assert_outcomes <_pytest.pytester.RunResult.assert_outcomes>{.interpreted-text role="meth"} now accepts a
warnings argument to assert the total number of warnings captured.
#8954: --debug flag now accepts a str{.interpreted-text role="class"} file to route debug logs into, remains defaulted to [pytestdebug.log]{.title-ref}.
#9023: Full diffs are now always shown for equality assertions of iterables when
[CI]{.title-ref} or BUILD_NUMBER is found in the environment, even when -v isn't
used.
#9113: RunResult <_pytest.pytester.RunResult>{.interpreted-text role="class"} method assert_outcomes <_pytest.pytester.RunResult.assert_outcomes>{.interpreted-text role="meth"} now accepts a
deselected argument to assert the total number of deselected tests.
#9114: Added pythonpath{.interpreted-text role="confval"} setting that adds listed paths to sys.path{.interpreted-text role="data"} for the duration of the test session. If you currently use the pytest-pythonpath or pytest-srcpaths plugins, you should be able to replace them with built-in [pythonpath]{.title-ref} setting.
#7480: A deprecation scheduled to be removed in a major version X (e.g. pytest 7, 8, 9, ...) now uses warning category [PytestRemovedInXWarning]{.title-ref},
a subclass of ~pytest.PytestDeprecationWarning{.interpreted-text role="class"},
instead of PytestDeprecationWarning{.interpreted-text role="class"} directly.
See backwards-compatibility{.interpreted-text role="ref"} for more details.
#7864: Improved error messages when parsing warning filters.
Previously pytest would show an internal traceback, which besides being ugly sometimes would hide the cause
of the problem (for example an ImportError while importing a specific warning type).
#8335: Improved pytest.approx{.interpreted-text role="func"} assertion messages for sequences of numbers.
The assertion messages now dumps a table with the index and the error of each diff. Example:
> assert [1, 2, 3, 4] == pytest.approx([1, 3, 3, 5])
E assert comparison failed for 2 values:
E Index | Obtained | Expected
E 1 | 2 | 3 +- 3.0e-06
E 3 | 4 | 5 +- 5.0e-06
#8403: By default, pytest will truncate long strings in assert errors so they don't clutter the output too much,
currently at 240 characters by default.
However, in some cases the longer output helps, or is even crucial, to diagnose a failure. Using -v will
now increase the truncation threshold to 2400 characters, and -vv or higher will disable truncation entirely.
#8509: Fixed issue where unittest.TestCase.setUpClass{.interpreted-text role="meth"} is not called when a test has [/]{.title-ref} in its name since pytest 6.2.0.
This refers to the path part in pytest node IDs, e.g. TestClass::test_it in the node ID tests/test_file.py::TestClass::test_it.
Now, instead of assuming that the test name does not contain /, it is assumed that test path does not contain ::. We plan to hopefully make both of these work in the future.
#8803: It is now possible to add colors to custom log levels on cli log.
By using add_color_level <_pytest.logging.add_color_level>{.interpreted-text role="func"} from a pytest_configure hook, colors can be added:
logging_plugin = config.pluginmanager.get_plugin('logging-plugin')
logging_plugin.log_cli_handler.formatter.add_color_level(logging.INFO, 'cyan')
logging_plugin.log_cli_handler.formatter.add_color_level(logging.SPAM, 'blue')
See log_colors{.interpreted-text role="ref"} for more information.
#8822: When showing fixture paths in [--fixtures]{.title-ref} or [--fixtures-by-test]{.title-ref}, fixtures coming from pytest itself now display an elided path, rather than the full path to the file in the [site-packages]{.title-ref} directory.
#8898: Complex numbers are now treated like floats and integers when generating parameterization IDs.
#9062: --stepwise-skip now implicitly enables --stepwise and can be used on its own.
#9205: pytest.Cache.set{.interpreted-text role="meth"} now preserves key order when saving dicts.
#7124: Fixed an issue where __main__.py would raise an ImportError when --doctest-modules was provided.
#8061: Fixed failing staticmethod test cases if they are inherited from a parent test class.
#8192: testdir.makefile now silently accepts values which don't start with . to maintain backward compatibility with older pytest versions.
pytester.makefile now issues a clearer error if the . is missing in the ext argument.
#8258: Fixed issue where pytest's faulthandler support would not dump traceback on crashes
if the faulthandler{.interpreted-text role="mod"} module was already enabled during pytest startup (using
python -X dev -m pytest for example).
#8317: Fixed an issue where illegal directory characters derived from getpass.getuser() raised an OSError.
#8367: Fix Class.from_parent so it forwards extra keyword arguments to the constructor.
#8377: The test selection options pytest -k and pytest -m now support matching
names containing forward slash (/) characters.
#8384: The @pytest.mark.skip decorator now correctly handles its arguments. When the reason argument is accidentally given both positional and as a keyword (e.g. because it was confused with skipif), a TypeError now occurs. Before, such tests were silently skipped, and the positional argument ignored. Additionally, reason is now documented correctly as positional or keyword (rather than keyword-only).
#8394: Use private names for internal fixtures that handle classic setup/teardown so that they don't show up with the default --fixtures invocation (but they still show up with --fixtures -v).
#8456: The required_plugins{.interpreted-text role="confval"} config option now works correctly when pre-releases of plugins are installed, rather than falsely claiming that those plugins aren't installed at all.
#8464: -c <config file> now also properly defines rootdir as the directory that contains <config file>.
#8503: pytest.MonkeyPatch.syspath_prepend{.interpreted-text role="meth"} no longer fails when
setuptools is not installed.
It now only calls pkg_resources.fixup_namespace_packages{.interpreted-text role="func"} if
pkg_resources was previously imported, because it is not needed otherwise.
#8548: Introduce fix to handle precision width in log-cli-format in turn to fix output coloring for certain formats.
#8796: Fixed internal error when skipping doctests.
#8983: The test selection options pytest -k and pytest -m now support matching names containing backslash ([\]{.title-ref}) characters.
Backslashes are treated literally, not as escape characters (the values being matched against are already escaped).
#8990: Fix [pytest -vv]{.title-ref} crashing with an internal exception [AttributeError: 'str' object has no attribute 'relative_to']{.title-ref} in some cases.
#9077: Fixed confusing error message when request.fspath / request.path was accessed from a session-scoped fixture.
#9163: The end line number and end column offset are now properly set for rewritten assert statements.
#9169: Support for the files API from importlib.resources within rewritten files.
#9272: The nose compatibility module-level fixtures [setup()]{.title-ref} and [teardown()]{.title-ref} are now only called once per module, instead of for each test function. They are now called even if object-level [setup]{.title-ref}/[teardown]{.title-ref} is defined.
plugin-list{.interpreted-text role="ref"}. The list is updated on a periodic schedule.pytest.approx{.interpreted-text role="func"} documentation.--pdbcls more accurately reflects the option's behavior.confcutdir being a configuration option: it can only be set through the --confcutdir command-line option.non-python tests{.interpreted-text role="ref"} are now correctly documented in the reference docs. They were undocumented previously.setuptools_scm 6.x to use SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST for more robust release tooling._pytest.code.getfslineno() function returns Path instead of py.path.local._pytest.python.path_matches_patterns() function takes Path instead of py.path.local._pytest._code.Traceback.cut() function accepts any os.PathLike[str], not just py.path.local.python.PyObjMixin inherit from nodes.Node to carry over typing information.pytest.skip{.interpreted-text role="func"} is used at module level without passing [allow_module_level=True]{.title-ref}.regendoc opts out of TOX_ENV cachedir selection to ensure independent example test runs.CallSpec2._arg2scopenum attribute has been removed after an internal refactoring.pytest_assertion_pass{.interpreted-text role="hook"} is no longer considered experimental and
future changes to it will be considered more carefully.( Please see the full set of changes for this release also in the 7.0.0rc1 notes below )
#9488 : If custom subclasses of nodes like pytest.Item override the init method, they should take **kwargs . See Constructors of custom Node subclasses should take **kwargs for details.
Note that a deprecation warning is only emitted when there is a conflict in the arguments pytest expected to pass. This deprecation was already part of pytest 7.0.0rc1 but wasn’t documented.
#9355 : Fixed error message prints function decorators when using assert in Python 3.8 and above.
#9396 : Ensure pytest.Config.inifile is available during the pytest_cmdline_main hook (regression during 7.0.0rc1 ).
#9404 : Added extra documentation on alternatives to common misuses of pytest.warns(None) ahead of its deprecation.
#9505 : Clarify where the configuration files are located. To avoid confusions documentation mentions that configuration file is located in the root of the repository.
#9521 : Add test coverage to assertion rewrite path.
Note: pytest was not able to provide a deprecation period for this change.
#7259 : The Node.reportinfo() function first return value type has been expanded from py.path.local | str to os.PathLike[str] | str .
Most plugins which refer to reportinfo() only define it as part of a custom pytest.Item implementation. Since py.path.local is an os.PathLike[str] , these plugins are unaffected.
Plugins and users which call reportinfo() , use the first return value and interact with it as a py.path.local , would need to adjust by calling py.path.local(fspath) . Although preferably, avoid the legacy py.path.local and use pathlib.Path , or use item.location or item.path , instead.
Note: pytest was not able to provide a deprecation period for this change.
#8246 : --version now writes version information to stdout rather than stderr .
#8592 : The pytest_cmdline_preparse hook has been removed following its deprecation. See the deprecation note for more details.
#8733 : Drop a workaround for pyreadline that made it work with --pdb .
The workaround was introduced in #1281 in 2015, however since then pyreadline seems to have gone unmaintained , is generating warnings , and will stop working on Python 3.10.
#9061 : Using pytest.approx() in a boolean context now raises an error hinting at the proper usage.
It is apparently common for users to mistakenly use pytest.approx like this:
assert pytest . approx ( actual , expected )
While the correct usage is:
assert actual == pytest . approx ( expected )
The new error message helps catch those mistakes.
#9277 : The pytest.Instance collector type has been removed. Importing pytest.Instance or _pytest.python.Instance returns a dummy type and emits a deprecation warning. See The pytest.Instance collector for details.
#9308 : PytestRemovedIn7Warning deprecation warnings are now errors by default.
Following our plan to remove deprecated features with as little disruption as possible, all warnings of type PytestRemovedIn7Warning now generate errors instead of warning messages by default.
The affected features will be effectively removed in pytest 7.1 , so please consult the Deprecations and Removals section in the docs for directions on how to update existing code.
In the pytest 7.0.X series, it is possible to change the errors back into warnings as a stopgap measure by adding this to your pytest.ini file:
[pytest] filterwarnings = ignore : :pytest.PytestRemovedIn7Warning
But this will stop working when pytest 7.1 is released.
If you have concerns about the removal of a specific feature, please add a comment to #9308 .
#7259 : py.path.local arguments for hooks have been deprecated. See the deprecation note for full details.
py.path.local arguments to Node constructors have been deprecated. See the deprecation note for full details.
Note
The name of the Node arguments and attributes (the new attribute being path ) is the opposite of the situation for hooks (the old argument being path ).
This is an unfortunate artifact due to historical reasons, which should be resolved in future versions as we slowly get rid of the py dependency (see #9283 for a longer discussion).
#7469 : Directly constructing the following classes is now deprecated:
_pytest.mark.structures.Mark
_pytest.mark.structures.MarkDecorator
_pytest.mark.structures.MarkGenerator
_pytest.python.Metafunc
_pytest.runner.CallInfo
_pytest._code.ExceptionInfo
_pytest.config.argparsing.Parser
_pytest.config.argparsing.OptionGroup
_pytest.pytester.HookRecorder
These constructors have always been considered private, but now issue a deprecation warning, which may become a hard error in pytest 8.
#8242 : Raising unittest.SkipTest to skip collection of tests during the pytest collection phase is deprecated. Use pytest.skip() instead.
Note: This deprecation only relates to using unittest.SkipTest during test collection. You are probably not doing that. Ordinary usage of unittest.SkipTest / unittest.TestCase.skipTest() / unittest.skip() in unittest test cases is fully supported.
Note
This deprecation has been reverted in pytest 7.1.0.
#8315 : Several behaviors of Parser.addoption are now scheduled for removal in pytest 8 (deprecated since pytest 2.4.0):
parser.addoption(..., help=".. %default ..") - use %(default)s instead.
parser.addoption(..., type="int/string/float/complex") - use type=int etc. instead.
#8447 : Defining a custom pytest node type which is both an Item and a Collector (e.g. File ) now issues a warning. It was never sanely supported and triggers hard to debug errors.
See the deprecation note for full details.
#8592 : pytest_cmdline_preparse has been officially deprecated. It will be removed in a future release. Use pytest_load_initial_conftests instead.
See the deprecation note for full details.
#8645 : pytest.warns(None) is now deprecated because many people used it to mean “this code does not emit warnings”, but it actually had the effect of checking that the code emits at least one warning of any type - like pytest.warns() or pytest.warns(Warning) .
#8948 : pytest.skip(msg=...) , pytest.fail(msg=...) and pytest.exit(msg=...) signatures now accept a reason argument instead of msg . Using msg still works, but is deprecated and will be removed in a future release.
This was changed for consistency with pytest.mark.skip and pytest.mark.xfail which both accept reason as an argument.
#8174 : The following changes have been made to types reachable through pytest.ExceptionInfo.traceback :
The path property of _pytest.code.Code returns Path instead of py.path.local .
The path property of _pytest.code.TracebackEntry returns Path instead of py.path.local .
There was no deprecation period for this change (sorry!).
#5196 : Tests are now ordered by definition order in more cases.
In a class hierarchy, tests from base classes are now consistently ordered before tests defined on their subclasses (reverse MRO order).
#7132 : Added two environment variables PYTEST_THEME and PYTEST_THEME_MODE to let the users customize the pygments theme used.
#7259 : Added cache.mkdir() , which is similar to the existing cache.makedir() , but returns a pathlib.Path instead of a legacy py.path.local .
Added a paths type to parser.addini() , as in parser.addini("mypaths", "my paths", type="paths") , which is similar to the existing pathlist , but returns a list of pathlib.Path instead of legacy py.path.local .
#7469 : The types of objects used in pytest’s API are now exported so they may be used in type annotations.
The newly-exported types are:
pytest.Config for Config .
pytest.Mark for marks .
pytest.MarkDecorator for mark decorators .
pytest.MarkGenerator for the pytest.mark singleton.
pytest.Metafunc for the metafunc argument to the pytest_generate_tests hook.
pytest.CallInfo for the CallInfo type passed to various hooks.
pytest.PytestPluginManager for PytestPluginManager .
pytest.ExceptionInfo for the ExceptionInfo type returned from pytest.raises() and passed to various hooks.
pytest.Parser for the Parser type passed to the pytest_addoption hook.
pytest.OptionGroup for the OptionGroup type returned from the parser.addgroup method.
pytest.HookRecorder for the HookRecorder type returned from Pytester .
pytest.RecordedHookCall for the RecordedHookCall type returned from HookRecorder .
pytest.RunResult for the RunResult type returned from Pytester .
pytest.LineMatcher for the LineMatcher type used in RunResult and others.
pytest.TestReport for the TestReport type used in various hooks.
pytest.CollectReport for the CollectReport type used in various hooks.
Constructing most of them directly is not supported; they are only meant for use in type annotations. Doing so will emit a deprecation warning, and may become a hard-error in pytest 8.0.
Subclassing them is also not supported. This is not currently enforced at runtime, but is detected by type-checkers such as mypy.
#7856 : –import-mode=importlib now works with features that depend on modules being on sys.modules , such as pickle and dataclasses .
#8144 : The following hooks now receive an additional pathlib.Path argument, equivalent to an existing py.path.local argument:
pytest_ignore_collect - The collection_path parameter (equivalent to existing path parameter).
pytest_collect_file - The file_path parameter (equivalent to existing path parameter).
pytest_pycollect_makemodule - The module_path parameter (equivalent to existing path parameter).
pytest_report_header - The start_path parameter (equivalent to existing startdir parameter).
pytest_report_collectionfinish - The start_path parameter (equivalent to existing startdir parameter).
Note
The name of the Node arguments and attributes (the new attribute being path ) is the opposite of the situation for hooks (the old argument being path ).
This is an unfortunate artifact due to historical reasons, which should be resolved in future versions as we slowly get rid of the py dependency (see #9283 for a longer discussion).
#8251 : Implement Node.path as a pathlib.Path . Both the old fspath and this new attribute gets set no matter whether path or fspath (deprecated) is passed to the constructor. It is a replacement for the fspath attribute (which represents the same path as py.path.local ). While fspath is not deprecated yet due to the ongoing migration of methods like reportinfo() , we expect to deprecate it in a future release.
Note
The name of the Node arguments and attributes (the new attribute being path ) is the opposite of the situation for hooks (the old argument being path ).
This is an unfortunate artifact due to historical reasons, which should be resolved in future versions as we slowly get rid of the py dependency (see #9283 for a longer discussion).
#8421 : pytest.approx() now works on Decimal within mappings/dicts and sequences/lists.
#8606 : pytest invocations with --fixtures-per-test and --fixtures have been enriched with:
Fixture location path printed with the fixture name.
First section of the fixture’s docstring printed under the fixture name.
Whole of fixture’s docstring printed under the fixture name using --verbose option.
#8761 : New pytest.version_tuple attribute, which makes it simpler for users to do something depending on the pytest version (such as declaring hooks which are introduced in later versions).
#8789 : Switch TOML parser from toml to tomli for TOML v1.0.0 support in pyproject.toml .
#8920 : Added pytest.Stash , a facility for plugins to store their data on Config and Node s in a type-safe and conflict-free manner. See Storing data on items across hook functions for details.
#8953 : RunResult method assert_outcomes() now accepts a warnings argument to assert the total number of warnings captured.
#8954 : --debug flag now accepts a str file to route debug logs into, remains defaulted to pytestdebug.log .
#9023 : Full diffs are now always shown for equality assertions of iterables when CI or BUILD_NUMBER is found in the environment, even when -v isn’t used.
#9113 : RunResult method assert_outcomes() now accepts a deselected argument to assert the total number of deselected tests.
#9114 : Added pythonpath setting that adds listed paths to sys.path for the duration of the test session. If you currently use the pytest-pythonpath or pytest-srcpaths plugins, you should be able to replace them with built-in pythonpath setting.
#7480 : A deprecation scheduled to be removed in a major version X (e.g. pytest 7, 8, 9, …) now uses warning category PytestRemovedInXWarning , a subclass of PytestDeprecationWarning , instead of PytestDeprecationWarning directly.
See Backwards Compatibility Policy for more details.
#7864 : Improved error messages when parsing warning filters.
Previously pytest would show an internal traceback, which besides being ugly sometimes would hide the cause of the problem (for example an ImportError while importing a specific warning type).
#8335 : Improved pytest.approx() assertion messages for sequences of numbers.
The assertion messages now dumps a table with the index and the error of each diff. Example:
assert [ 1 , 2 , 3 , 4 ] == pytest . approx ([ 1 , 3 , 3 , 5 ]) E assert comparison failed for 2 values : E Index | Obtained | Expected E 1 | 2 | 3 +- 3.0e-06 E 3 | 4 | 5 +- 5.0e-06
#8403 : By default, pytest will truncate long strings in assert errors so they don’t clutter the output too much, currently at 240 characters by default.
However, in some cases the longer output helps, or is even crucial, to diagnose a failure. Using -v will now increase the truncation threshold to 2400 characters, and -vv or higher will disable truncation entirely.
#8509 : Fixed issue where unittest.TestCase.setUpClass() is not called when a test has / in its name since pytest 6.2.0.
This refers to the path part in pytest node IDs, e.g. TestClass::test_it in the node ID tests/test_file.py::TestClass::test_it .
Now, instead of assuming that the test name does not contain / , it is assumed that test path does not contain :: . We plan to hopefully make both of these work in the future.
#8803 : It is now possible to add colors to custom log levels on cli log.
By using add_color_level from a pytest_configure hook, colors can be added:
logging_plugin = config . pluginmanager . get_plugin ( 'logging-plugin' ) logging_plugin . log_cli_handler . formatter . add_color_level ( logging . INFO , 'cyan' ) logging_plugin . log_cli_handler . formatter . add_color_level ( logging . SPAM , 'blue' )
See Customizing Colors for more information.
#8822 : When showing fixture paths in --fixtures or --fixtures-by-test , fixtures coming from pytest itself now display an elided path, rather than the full path to the file in the site-packages directory.
#8898 : Complex numbers are now treated like floats and integers when generating parameterization IDs.
#9062 : --stepwise-skip now implicitly enables --stepwise and can be used on its own.
#9205 : pytest.Cache.set() now preserves key order when saving dicts.
#7124 : Fixed an issue where main.py would raise an ImportError when --doctest-modules was provided.
#8061 : Fixed failing staticmethod test cases if they are inherited from a parent test class.
#8192 : testdir.makefile now silently accepts values which don’t start with . to maintain backward compatibility with older pytest versions.
pytester.makefile now issues a clearer error if the . is missing in the ext argument.
#8258 : Fixed issue where pytest’s faulthandler support would not dump traceback on crashes if the faulthandler module was already enabled during pytest startup (using python -X dev -m pytest for example).
#8317 : Fixed an issue where illegal directory characters derived from getpass.getuser() raised an OSError .
#8367 : Fix Class.from_parent so it forwards extra keyword arguments to the constructor.
#8377 : The test selection options pytest -k and pytest -m now support matching names containing forward slash ( / ) characters.
#8384 : The @pytest.mark.skip decorator now correctly handles its arguments. When the reason argument is accidentally given both positional and as a keyword (e.g. because it was confused with skipif ), a TypeError now occurs. Before, such tests were silently skipped, and the positional argument ignored. Additionally, reason is now documented correctly as positional or keyword (rather than keyword-only).
#8394 : Use private names for internal fixtures that handle classic setup/teardown so that they don’t show up with the default --fixtures invocation (but they still show up with --fixtures -v ).
#8456 : The required_plugins config option now works correctly when pre-releases of plugins are installed, rather than falsely claiming that those plugins aren’t installed at all.
#8464 : -c <config file> now also properly defines rootdir as the directory that contains <config file> .
#8503 : pytest.MonkeyPatch.syspath_prepend() no longer fails when setuptools is not installed. It now only calls pkg_resources.fixup_namespace_packages if pkg_resources was previously imported, because it is not needed otherwise.
#8548 : Introduce fix to handle precision width in log-cli-format in turn to fix output coloring for certain formats.
#8796 : Fixed internal error when skipping doctests.
#8983 : The test selection options pytest -k and pytest -m now support matching names containing backslash ( \ ) characters. Backslashes are treated literally, not as escape characters (the values being matched against are already escaped).
#8990 : Fix pytest -vv crashing with an internal exception AttributeError: 'str' object has no attribute 'relative_to' in some cases.
#9077 : Fixed confusing error message when request.fspath / request.path was accessed from a session-scoped fixture.
#9131 : Fixed the URL used by --pastebin to use bpa.st .
#9163 : The end line number and end column offset are now properly set for rewritten assert statements.
#9169 : Support for the files API from importlib.resources within rewritten files.
#9272 : The nose compatibility module-level fixtures setup() and teardown() are now only called once per module, instead of for each test function. They are now called even if object-level setup / teardown is defined.
#4320 : Improved docs for pytester.copy_example .
#5105 : Add automatically generated Pytest Plugin List . The list is updated on a periodic schedule.
#8337 : Recommend numpy.testing module on pytest.approx() documentation.
#8655 : Help text for --pdbcls more accurately reflects the option’s behavior.
#9210 : Remove incorrect docs about confcutdir being a configuration option: it can only be set through the --confcutdir command-line option.
#9242 : Upgrade readthedocs configuration to use a newer Ubuntu version https://blog.readthedocs.com/new-build-specification/`__ with better unicode support for PDF docs.
#9341 : Various methods commonly used for Working with non-python tests are now correctly documented in the reference docs. They were undocumented previously.
#8133 : Migrate to setuptools_scm 6.x to use SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST for more robust release tooling.
#8174 : The following changes have been made to internal pytest types/functions:
The _pytest.code.getfslineno() function returns Path instead of py.path.local .
The _pytest.python.path_matches_patterns() function takes Path instead of py.path.local .
The _pytest._code.Traceback.cut() function accepts any os.PathLike[str] , not just py.path.local .
#8248 : Internal Restructure: let python.PyObjMixin inherit from nodes.Node to carry over typing information.
#8432 : Improve error message when pytest.skip() is used at module level without passing allow_module_level=True .
#8818 : Ensure regendoc opts out of TOX_ENV cachedir selection to ensure independent example test runs.
#8913 : The private CallSpec2._arg2scopenum attribute has been removed after an internal refactoring.
#8967 : pytest_assertion_pass is no longer considered experimental and future changes to it will be considered more carefully.
#9202 : Add github action to upload coverage report to codecov instead of bash uploader.
#9225 : Changed the command used to create sdist and wheel artifacts: using the build package instead of setup.py.
#9351 : Correct minor typos in doc/en/example/special.rst.
\#8494: Python 3.10 is now supported.
\#8539: Fixed assertion rewriting on Python 3.10.
\#8414: pytest used to create directories under /tmp with world-readable permissions. This means that any user in the system was able to read informat
#8414: pytest used to create directories under /tmp with world-readable
permissions. This means that any user in the system was able to read
information written by tests in temporary directories (such as those created by
the tmp_path/tmpdir fixture). Now the directories are created with
private permissions.
pytest used silenty use a pre-existing /tmp/pytest-of-<username> directory,
even if owned by another user. This means another user could pre-create such a
directory and gain control of another user's temporary directory. Now such a
condition results in an error.
\#8152: Fixed "(<Skipped instance>)" being shown as a skip reason in the verbose test summary line when the reason is empty.
\#7678: Fixed bug where ImportPathMismatchError would be raised for files compiled in the host and loaded later from an UNC mounted path (Windows).
#7678: Fixed bug where ImportPathMismatchError would be raised for files compiled in
the host and loaded later from an UNC mounted path (Windows).
#8132: Fixed regression in approx: in 6.2.0 approx no longer raises
TypeError when dealing with non-numeric types, falling back to normal comparison.
Before 6.2.0, array types like tf.DeviceArray fell through to the scalar case,
and happened to compare correctly to a scalar if they had only one element.
After 6.2.0, these types began failing, because they inherited neither from
standard Python number hierarchy nor from numpy.ndarray.
approx now converts arguments to numpy.ndarray if they expose the array
protocol and are not scalars. This treats array-like objects like numpy arrays,
regardless of size.
\#7469: Directly constructing/calling the following classes/functions is now deprecated:
#7469: Directly constructing/calling the following classes/functions is now deprecated:
_pytest.cacheprovider.Cache_pytest.cacheprovider.Cache.for_config()_pytest.cacheprovider.Cache.clear_cache()_pytest.cacheprovider.Cache.cache_dir_from_config()_pytest.capture.CaptureFixture_pytest.fixtures.FixtureRequest_pytest.fixtures.SubRequest_pytest.logging.LogCaptureFixture_pytest.pytester.Pytester_pytest.pytester.Testdir_pytest.recwarn.WarningsRecorder_pytest.recwarn.WarningsChecker_pytest.tmpdir.TempPathFactory_pytest.tmpdir.TempdirFactoryThese have always been considered private, but now issue a deprecation warning, which may become a hard error in pytest 7.0.0.
#7530: The --strict command-line option has been deprecated, use --strict-markers instead.
We have plans to maybe in the future to reintroduce --strict and make it an encompassing flag for all strictness
related options (--strict-markers and --strict-config at the moment, more might be introduced in the future).
#7988: The @pytest.yield_fixture decorator/function is now deprecated. Use pytest.fixture instead.
yield_fixture has been an alias for fixture for a very long time, so can be search/replaced safely.
#5299: pytest now warns about unraisable exceptions and unhandled thread exceptions that occur in tests on Python>=3.8. See unraisable for more information.
#7425: New pytester fixture, which is identical to testdir but its methods return pathlib.Path when appropriate instead of py.path.local.
This is part of the movement to use pathlib.Path objects internally, in order to remove the dependency to py in the future.
Internally, the old Testdir <_pytest.pytester.Testdir> is now a thin wrapper around Pytester <_pytest.pytester.Pytester>, preserving the old interface.
#7695: A new hook was added, pytest_markeval_namespace which should return a dictionary. This dictionary will be used to augment the "global" variables available to evaluate skipif/xfail/xpass markers.
Pseudo example
conftest.py:
def pytest_markeval_namespace():
return {"color": "red"}
test_func.py:
@pytest.mark.skipif("color == 'blue'", reason="Color is not red")
def test_func():
assert False
#8006: It is now possible to construct a ~pytest.MonkeyPatch object directly as pytest.MonkeyPatch(),
in cases when the monkeypatch fixture cannot be used. Previously some users imported it
from the private _pytest.monkeypatch.MonkeyPatch namespace.
Additionally, MonkeyPatch.context <pytest.MonkeyPatch.context> is now a classmethod,
and can be used as with MonkeyPatch.context() as mp: .... This is the recommended way to use
MonkeyPatch directly, since unlike the monkeypatch fixture, an instance created directly
is not undo()-ed automatically.
#1265: Added an __str__ implementation to the ~pytest.pytester.LineMatcher class which is returned from pytester.run_pytest().stdout and similar. It returns the entire output, like the existing str() method.
#2044: Verbose mode now shows the reason that a test was skipped in the test's terminal line after the "SKIPPED", "XFAIL" or "XPASS".
#7469 The types of builtin pytest fixtures are now exported so they may be used in type annotations of test functions. The newly-exported types are:
pytest.FixtureRequest for the request fixture.pytest.Cache for the cache fixture.pytest.CaptureFixture[str] for the capfd and capsys fixtures.pytest.CaptureFixture[bytes] for the capfdbinary and capsysbinary fixtures.pytest.LogCaptureFixture for the caplog fixture.pytest.Pytester for the pytester fixture.pytest.Testdir for the testdir fixture.pytest.TempdirFactory for the tmpdir_factory fixture.pytest.TempPathFactory for the tmp_path_factory fixture.pytest.MonkeyPatch for the monkeypatch fixture.pytest.WarningsRecorder for the recwarn fixture.Constructing them is not supported (except for MonkeyPatch); they are only meant for use in type annotations. Doing so will emit a deprecation warning, and may become a hard-error in pytest 7.0.
Subclassing them is also not supported. This is not currently enforced at runtime, but is detected by type-checkers such as mypy.
#7527: When a comparison between namedtuple <collections.namedtuple> instances of the same type fails, pytest now shows the differing field names (possibly nested) instead of their indexes.
#7615: Node.warn <_pytest.nodes.Node.warn> now permits any subclass of Warning, not just PytestWarning <pytest.PytestWarning>.
#7701: Improved reporting when using --collected-only. It will now show the number of collected tests in the summary stats.
#7710: Use strict equality comparison for non-numeric types in pytest.approx instead of raising TypeError.
This was the undocumented behavior before 3.7, but is now officially a supported feature.
#7938: New --sw-skip argument which is a shorthand for --stepwise-skip.
#8023: Added 'node_modules' to default value for norecursedirs.
#8032: doClassCleanups <unittest.TestCase.doClassCleanups> (introduced in unittest in Python and 3.8) is now called appropriately.
--lf even though they contain tests that failed. Regressed in pytest 5.4.0.pytest --doctest-modules path/to/an/__init__.py.final class in the API reference._pytest.config.argparsing.Parser.addini() accepts explicit None and "string".\#7815: Improve deprecation warning message for pytest._fillfuncargs().
--lf even though they contain tests that failed. Regressed in pytest 5.4.0.pytest._fillfuncargs().\#7807: Fixed regression in pytest 6.1.0 causing incorrect rootdir to be determined in some non-trivial cases where parent directories have config fil
\#5585: As per our policy, the following features which have been deprecated in the 5.X series are now removed:
#5585: As per our policy, the following features which have been deprecated in the 5.X series are now removed:
funcargnames read-only property of FixtureRequest, Metafunc, and Function classes. Use fixturenames attribute.@pytest.fixture no longer supports positional arguments, pass all arguments by keyword instead.Node subclasses now raise an error, use from_parent instead.junit_family has changed to xunit2. If you require the old format, add junit_family=xunit1 to your configuration file.TerminalReporter no longer has a writer attribute. Plugin authors may use the public functions of the TerminalReporter instead of accessing the TerminalWriter object directly.--result-log option has been removed. Users are recommended to use the pytest-reportlog plugin instead.For more information consult Deprecations and Removals in the docs.
#6981: The pytest.collect module is deprecated: all its names can be imported from pytest directly.
#7097: The pytest._fillfuncargs function is deprecated. This function was kept
for backward compatibility with an older plugin.
It's functionality is not meant to be used directly, but if you must replace it, use function._request._fillfixtures() instead, though note this is not a public API and may break in the future.
#7210: The special -k '-expr' syntax to -k is deprecated. Use -k 'not expr'
instead.
The special -k 'expr:' syntax to -k is deprecated. Please open an issue
if you use this and want a replacement.
#7255: The pytest_warning_captured <_pytest.hookspec.pytest_warning_captured> hook is deprecated in favor of pytest_warning_recorded <_pytest.hookspec.pytest_warning_recorded>, and will be removed in a future version.
#7648: The gethookproxy() and isinitpath() methods of FSCollector and Package are deprecated;
use self.session.gethookproxy() and self.session.isinitpath() instead.
This should work on all pytest versions.
--durations-min command-line flag controls the minimal duration for inclusion in the slowest list of tests shown by --durations. Previously this was hard-coded to 0.005s.#6681: Internal pytest warnings issued during the early stages of initialization are now properly handled and can filtered through filterwarnings or --pythonwarnings/-W.
This also fixes a number of long standing issues: #2891, #7620, #7426.
#7572: When a plugin listed in required_plugins is missing or an unknown config key is used with --strict-config, a simple error message is now shown instead of a stacktrace.
#7685: Added two new attributes rootpath <_pytest.config.Config.rootpath> and inipath <_pytest.config.Config.inipath> to Config <_pytest.config.Config>. These attributes are pathlib.Path versions of the existing rootdir <_pytest.config.Config.rootdir> and inifile <_pytest.config.Config.inifile> attributes, and should be preferred over them when possible.
#7780: Public classes which are not designed to be inherited from are now marked @final.
Code which inherits from these classes will trigger a type-checking (e.g. mypy) error, but will still work in runtime.
Currently the final designation does not appear in the API Reference but hopefully will in the future.
#1953: Fixed error when overwriting a parametrized fixture, while also reusing the super fixture value.
# conftest.py
import pytest
@pytest.fixture(params=[1, 2])
def foo(request):
return request.param
# test_foo.py
import pytest
@pytest.fixture
def foo(foo):
return foo * 2
#4984: Fixed an internal error crash with IndexError: list index out of range when
collecting a module which starts with a decorated function, the decorator
raises, and assertion rewriting is enabled.
#7591: pylint shouldn't complain anymore about unimplemented abstract methods when inheriting from File <non-python tests>.
#7628: Fixed test collection when a full path without a drive letter was passed to pytest on Windows (for example \projects\tests\test.py instead of c:\projects\tests\pytest.py).
#7638: Fix handling of command-line options that appear as paths but trigger an OS-level syntax error on Windows, such as the options used internally by pytest-xdist.
#7742: Fixed INTERNALERROR when accessing locals / globals with faulty exec.
junitxml plugin has rewritten to use xml.etree.ElementTree.
The order of attributes in XML elements might differ. Some unneeded escaping is
no longer performed.more-itertools package has been removed.__class__,
__delattr__ and __new__) without consulting the python_classes and
python_functions configuration options and without passing them to plugins
using the pytest_pycollect_makeitem <_pytest.hookspec.pytest_pycollect_makeitem> hook.\#7148: Fixed --log-cli potentially causing unrelated print output to be swallowed.
--log-cli potentially causing unrelated print output to be swallowed.caplog.set_level is called more than once.--tb=line for example).\#7394: Passing an empty help value to Parser.add_option is now accepted instead of crashing when running pytest --help. Passing None raises a more in
help value to Parser.add_option is now accepted instead of crashing when running pytest --help.
Passing None raises a more informative TypeError.not-callable lint on pytest.mark.parametrize() and the other builtin marks:
skip, skipif, xfail, usefixtures, filterwarnings.TestReport.longreprtext (such as pytest-html) when TestReport.longrepr is not a string.caplog.set_level().Your coding agent can read these notes before it upgrades. Set up the MCP server →