Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-pytest for openSUSE:Factory checked in at 2025-09-14 18:49:03 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pytest (Old) and /work/SRC/openSUSE:Factory/.python-pytest.new.1977 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pytest" Sun Sep 14 18:49:03 2025 rev:91 rq:1304278 version:8.4.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pytest/python-pytest.changes 2025-08-08 15:10:41.541197635 +0200 +++ /work/SRC/openSUSE:Factory/.python-pytest.new.1977/python-pytest.changes 2025-09-14 18:49:27.984313761 +0200 @@ -1,0 +2,32 @@ +Fri Sep 5 09:16:27 UTC 2025 - Dirk Müller <[email protected]> + +- update to 8.4.2: + * #13478: Fixed a crash when using + :confval:`console_output_style` with times and a module is + skipped. + * #13530: Fixed a crash when using :func:`pytest.approx` and + :class:`decimal.Decimal` instances with the + :class:`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 + :meth:`pytest.Parser.addini`. + * #13563: :func:`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 + :user:`ogrisel`. + +------------------------------------------------------------------- Old: ---- pytest-8.4.1.tar.gz New: ---- pytest-8.4.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pytest.spec ++++++ --- /var/tmp/diff_new_pack.C5kta3/_old 2025-09-14 18:49:29.056358684 +0200 +++ /var/tmp/diff_new_pack.C5kta3/_new 2025-09-14 18:49:29.056358684 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-pytest # -# Copyright (c) 2025 SUSE LLC +# Copyright (c) 2025 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -33,7 +33,7 @@ %{?sle15_python_module_pythons} Name: python-pytest%{psuffix} -Version: 8.4.1 +Version: 8.4.2 Release: 0 Summary: Simple powerful testing with Python License: MIT ++++++ pytest-8.4.1.tar.gz -> pytest-8.4.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/.github/workflows/deploy.yml new/pytest-8.4.2/.github/workflows/deploy.yml --- old/pytest-8.4.1/.github/workflows/deploy.yml 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/.github/workflows/deploy.yml 2025-09-04 16:33:06.000000000 +0200 @@ -109,8 +109,8 @@ tox -e generate-gh-release-notes -- "$VERSION" scripts/latest-release-notes.md - name: Publish GitHub Release - uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 - with: - body_path: scripts/latest-release-notes.md - files: dist/* - tag_name: ${{ github.event.inputs.version }} + env: + VERSION: ${{ github.event.inputs.version }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release create --notes-file scripts/latest-release-notes.md --verify-tag "$VERSION" dist/* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/AUTHORS new/pytest-8.4.2/AUTHORS --- old/pytest-8.4.1/AUTHORS 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/AUTHORS 2025-09-04 16:33:06.000000000 +0200 @@ -261,6 +261,7 @@ Lev Maximov Levon Saldamli Lewis Cowles +Liam DeVoe Llandy Riveron Del Risco Loic Esteve lovetheguitar diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/PKG-INFO new/pytest-8.4.2/PKG-INFO --- old/pytest-8.4.1/PKG-INFO 2025-06-18 00:28:42.778136500 +0200 +++ new/pytest-8.4.2/PKG-INFO 2025-09-04 16:33:11.294580700 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: pytest -Version: 8.4.1 +Version: 8.4.2 Summary: pytest: simple powerful testing with Python Author: Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin, Others (See AUTHORS) License: MIT diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/doc/en/announce/index.rst new/pytest-8.4.2/doc/en/announce/index.rst --- old/pytest-8.4.1/doc/en/announce/index.rst 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/doc/en/announce/index.rst 2025-09-04 16:33:06.000000000 +0200 @@ -6,6 +6,7 @@ :maxdepth: 2 + release-8.4.2 release-8.4.1 release-8.4.0 release-8.3.5 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/doc/en/announce/release-8.4.2.rst new/pytest-8.4.2/doc/en/announce/release-8.4.2.rst --- old/pytest-8.4.1/doc/en/announce/release-8.4.2.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/pytest-8.4.2/doc/en/announce/release-8.4.2.rst 2025-09-04 16:33:06.000000000 +0200 @@ -0,0 +1,27 @@ +pytest-8.4.2 +======================================= + +pytest 8.4.2 has just been released to PyPI. + +This is a bug-fix release, being a drop-in replacement. + +The full changelog is available at https://docs.pytest.org/en/stable/changelog.html. + +Thanks to all of the contributors to this release: + +* AD +* Aditi De +* Bruno Oliveira +* Florian Bruhin +* John Litborn +* Liam DeVoe +* Marc Mueller +* NayeemJohn +* Olivier Grisel +* Ran Benita +* bengartner +* 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) + + +Happy testing, +The pytest Development Team diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/doc/en/builtin.rst new/pytest-8.4.2/doc/en/builtin.rst --- old/pytest-8.4.1/doc/en/builtin.rst 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/doc/en/builtin.rst 2025-09-04 16:33:06.000000000 +0200 @@ -142,7 +142,7 @@ For more details: :ref:`doctest_namespace`. - pytestconfig [session scope] -- .../_pytest/fixtures.py:1424 + pytestconfig [session scope] -- .../_pytest/fixtures.py:1425 Session-scoped fixture that returns the session's :class:`pytest.Config` object. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/doc/en/changelog.rst new/pytest-8.4.2/doc/en/changelog.rst --- old/pytest-8.4.1/doc/en/changelog.rst 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/doc/en/changelog.rst 2025-09-04 16:33:06.000000000 +0200 @@ -31,6 +31,49 @@ .. towncrier release notes start +pytest 8.4.2 (2025-09-03) +========================= + +Bug fixes +--------- + +- `#13478 <https://github.com/pytest-dev/pytest/issues/13478>`_: Fixed a crash when using :confval:`console_output_style` with ``times`` and a module is skipped. + + +- `#13530 <https://github.com/pytest-dev/pytest/issues/13530>`_: Fixed a crash when using :func:`pytest.approx` and :class:`decimal.Decimal` instances with the :class:`decimal.FloatOperation` trap set. + + +- `#13549 <https://github.com/pytest-dev/pytest/issues/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 <https://github.com/pytest-dev/pytest/issues/13559>`_: Added missing `int` and `float` variants to the `Literal` type annotation of the `type` parameter in :meth:`pytest.Parser.addini`. + + +- `#13563 <https://github.com/pytest-dev/pytest/issues/13563>`_: :func:`pytest.approx` now only imports ``numpy`` if NumPy is already in ``sys.modules``. This fixes unconditional import behavior introduced in `8.4.0`. + + + +Improved documentation +---------------------- + +- `#13577 <https://github.com/pytest-dev/pytest/issues/13577>`_: Clarify that ``pytest_generate_tests`` is discovered in test modules/classes; other hooks must be in ``conftest.py`` or plugins. + + + +Contributor-facing changes +-------------------------- + +- `#13480 <https://github.com/pytest-dev/pytest/issues/13480>`_: Self-testing: fixed a few test failures when run with ``-Wdefault`` or a similar override. + + +- `#13547 <https://github.com/pytest-dev/pytest/issues/13547>`_: Self-testing: corrected expected message for ``test_doctest_unexpected_exception`` in Python ``3.14``. + + +- `#13684 <https://github.com/pytest-dev/pytest/issues/13684>`_: Make pytest's own testsuite insensitive to the presence of the ``CI`` environment variable -- by :user:`ogrisel`. + + pytest 8.4.1 (2025-06-17) ========================= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/doc/en/example/parametrize.rst new/pytest-8.4.2/doc/en/example/parametrize.rst --- old/pytest-8.4.1/doc/en/example/parametrize.rst 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/doc/en/example/parametrize.rst 2025-09-04 16:33:06.000000000 +0200 @@ -162,7 +162,7 @@ rootdir: /home/sweet/project collected 8 items - <Dir parametrize.rst-208> + <Dir parametrize.rst-209> <Module test_time.py> <Function test_timedistance_v0[a0-b0-expected0]> <Function test_timedistance_v0[a1-b1-expected1]> @@ -239,7 +239,7 @@ rootdir: /home/sweet/project collected 4 items - <Dir parametrize.rst-208> + <Dir parametrize.rst-209> <Module test_scenarios.py> <Class TestSampleWithScenarios> <Function test_demo1[basic]> @@ -318,7 +318,7 @@ rootdir: /home/sweet/project collected 2 items - <Dir parametrize.rst-208> + <Dir parametrize.rst-209> <Module test_backends.py> <Function test_db_initialized[d1]> <Function test_db_initialized[d2]> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/doc/en/example/pythoncollection.rst new/pytest-8.4.2/doc/en/example/pythoncollection.rst --- old/pytest-8.4.1/doc/en/example/pythoncollection.rst 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/doc/en/example/pythoncollection.rst 2025-09-04 16:33:06.000000000 +0200 @@ -152,7 +152,7 @@ configfile: pytest.ini collected 2 items - <Dir pythoncollection.rst-209> + <Dir pythoncollection.rst-210> <Module check_myapp.py> <Class CheckMyApp> <Function simple_check> @@ -215,7 +215,7 @@ configfile: pytest.ini collected 3 items - <Dir pythoncollection.rst-209> + <Dir pythoncollection.rst-210> <Dir CWD> <Module pythoncollection.py> <Function test_function> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/doc/en/getting-started.rst new/pytest-8.4.2/doc/en/getting-started.rst --- old/pytest-8.4.1/doc/en/getting-started.rst 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/doc/en/getting-started.rst 2025-09-04 16:33:06.000000000 +0200 @@ -22,7 +22,7 @@ .. code-block:: bash $ pytest --version - pytest 8.4.1 + pytest 8.4.2 .. _`simpletest`: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/doc/en/how-to/fixtures.rst new/pytest-8.4.2/doc/en/how-to/fixtures.rst --- old/pytest-8.4.1/doc/en/how-to/fixtures.rst 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/doc/en/how-to/fixtures.rst 2025-09-04 16:33:06.000000000 +0200 @@ -1423,7 +1423,7 @@ rootdir: /home/sweet/project collected 12 items - <Dir fixtures.rst-229> + <Dir fixtures.rst-230> <Module test_anothersmtp.py> <Function test_showhelo[smtp.gmail.com]> <Function test_showhelo[mail.python.org]> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/doc/en/how-to/parametrize.rst new/pytest-8.4.2/doc/en/how-to/parametrize.rst --- old/pytest-8.4.1/doc/en/how-to/parametrize.rst 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/doc/en/how-to/parametrize.rst 2025-09-04 16:33:06.000000000 +0200 @@ -240,6 +240,13 @@ if "stringinput" in metafunc.fixturenames: metafunc.parametrize("stringinput", metafunc.config.getoption("stringinput")) +.. note:: + + The :hook:`pytest_generate_tests` hook can also be implemented directly in a test + module or inside a test class; unlike other hooks, pytest will discover it there + as well. Other hooks must live in a :ref:`conftest.py <localplugin>` or a plugin. + See :ref:`writinghooks`. + If we now pass two stringinput values, our test will run twice: .. code-block:: pytest diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/doc/en/how-to/writing_hook_functions.rst new/pytest-8.4.2/doc/en/how-to/writing_hook_functions.rst --- old/pytest-8.4.1/doc/en/how-to/writing_hook_functions.rst 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/doc/en/how-to/writing_hook_functions.rst 2025-09-04 16:33:06.000000000 +0200 @@ -235,6 +235,12 @@ """ print(config.hook) +.. note:: + + Unlike other hooks, the :hook:`pytest_generate_tests` hook is also discovered when + defined inside a test module or test class. Other hooks must live in + :ref:`conftest.py plugins <localplugin>` or external plugins. + See :ref:`parametrize-basics` and the :ref:`hook-reference`. .. _`addoptionhooks`: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/doc/en/index.rst new/pytest-8.4.2/doc/en/index.rst --- old/pytest-8.4.1/doc/en/index.rst 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/doc/en/index.rst 2025-09-04 16:33:06.000000000 +0200 @@ -2,7 +2,7 @@ .. sidebar:: **Next Open Trainings and Events** - - `pytest - simple, rapid and fun testing with Python <https://ep2025.europython.eu/session/pytest-simple-rapid-and-fun-testing-with-python/>`_, at `EuroPython 2025 <https://ep2025.europython.eu/>`_, **July 14th** (3h), Prague, Czech Republic + - `Testen mit pytest <https://www.letsboot.ch/kurs/pytest>`_ (German), via `Letsboot <https://www.letsboot.ch/>`_ (3 day in-depth training), **October 29th -- 31st**, Zurich (CH) - `Professional Testing with Python <https://python-academy.com/courses/python_course_testing.html>`_, via `Python Academy <https://www.python-academy.com/>`_ (3 day in-depth training), **March 3th -- 5th 2026**, Leipzig (DE) / Remote Also see :doc:`previous talks and blogposts <talks>` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/pyproject.toml new/pytest-8.4.2/pyproject.toml --- old/pytest-8.4.1/pyproject.toml 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/pyproject.toml 2025-09-04 16:33:06.000000000 +0200 @@ -426,6 +426,9 @@ "slow", # experimental mark for all tests using pexpect "uses_pexpect", + # Disables the `remove_ci_env_var` autouse fixture on a given test that + # actually inspects whether the CI environment variable is set. + "keep_ci_var", ] [tool.towncrier] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/scripts/prepare-release-pr.py new/pytest-8.4.2/scripts/prepare-release-pr.py --- old/pytest-8.4.1/scripts/prepare-release-pr.py 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/scripts/prepare-release-pr.py 2025-09-04 16:33:06.000000000 +0200 @@ -135,6 +135,7 @@ f"--head={release_branch}", f"--title=Release {version}", f"--body={body}", + "--draft", ], check=True, ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/src/_pytest/_version.py new/pytest-8.4.2/src/_pytest/_version.py --- old/pytest-8.4.1/src/_pytest/_version.py 2025-06-18 00:28:42.000000000 +0200 +++ new/pytest-8.4.2/src/_pytest/_version.py 2025-09-04 16:33:11.000000000 +0200 @@ -1,7 +1,14 @@ # file generated by setuptools-scm # don't change, don't track in version control -__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"] +__all__ = [ + "__version__", + "__version_tuple__", + "version", + "version_tuple", + "__commit_id__", + "commit_id", +] TYPE_CHECKING = False if TYPE_CHECKING: @@ -9,13 +16,19 @@ from typing import Union VERSION_TUPLE = Tuple[Union[int, str], ...] + COMMIT_ID = Union[str, None] else: VERSION_TUPLE = object + COMMIT_ID = object version: str __version__: str __version_tuple__: VERSION_TUPLE version_tuple: VERSION_TUPLE +commit_id: COMMIT_ID +__commit_id__: COMMIT_ID -__version__ = version = '8.4.1' -__version_tuple__ = version_tuple = (8, 4, 1) +__version__ = version = '8.4.2' +__version_tuple__ = version_tuple = (8, 4, 2) + +__commit_id__ = commit_id = None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/src/_pytest/compat.py new/pytest-8.4.2/src/_pytest/compat.py --- old/pytest-8.4.1/src/_pytest/compat.py 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/src/_pytest/compat.py 2025-09-04 16:33:06.000000000 +0200 @@ -8,7 +8,7 @@ import functools import inspect from inspect import Parameter -from inspect import signature +from inspect import Signature import os from pathlib import Path import sys @@ -19,6 +19,10 @@ import py +if sys.version_info >= (3, 14): + from annotationlib import Format + + #: constant to prepare valuing pylib path replacements/lazy proxies later on # intended for removal in pytest 8.0 or 9.0 @@ -60,6 +64,13 @@ return iscoroutinefunction(func) or inspect.isasyncgenfunction(func) +def signature(obj: Callable[..., Any]) -> Signature: + """Return signature without evaluating annotations.""" + if sys.version_info >= (3, 14): + return inspect.signature(obj, annotation_format=Format.STRING) + return inspect.signature(obj) + + def getlocation(function, curdir: str | os.PathLike[str] | None = None) -> str: function = get_real_func(function) fn = Path(inspect.getfile(function)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/src/_pytest/config/argparsing.py new/pytest-8.4.2/src/_pytest/config/argparsing.py --- old/pytest-8.4.1/src/_pytest/config/argparsing.py 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/src/_pytest/config/argparsing.py 2025-09-04 16:33:06.000000000 +0200 @@ -174,7 +174,9 @@ self, name: str, help: str, - type: Literal["string", "paths", "pathlist", "args", "linelist", "bool"] + type: Literal[ + "string", "paths", "pathlist", "args", "linelist", "bool", "int", "float" + ] | None = None, default: Any = NOT_SET, ) -> None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/src/_pytest/fixtures.py new/pytest-8.4.2/src/_pytest/fixtures.py --- old/pytest-8.4.1/src/_pytest/fixtures.py 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/src/_pytest/fixtures.py 2025-09-04 16:33:06.000000000 +0200 @@ -49,6 +49,7 @@ from _pytest.compat import NotSetType from _pytest.compat import safe_getattr from _pytest.compat import safe_isclass +from _pytest.compat import signature from _pytest.config import _PluggyPlugin from _pytest.config import Config from _pytest.config import ExitCode @@ -804,8 +805,8 @@ path, lineno = getfslineno(factory) if isinstance(path, Path): path = bestrelpath(self._pyfuncitem.session.path, path) - signature = inspect.signature(factory) - return f"{path}:{lineno + 1}: def {factory.__name__}{signature}" + sig = signature(factory) + return f"{path}:{lineno + 1}: def {factory.__name__}{sig}" def addfinalizer(self, finalizer: Callable[[], object]) -> None: self._fixturedef.addfinalizer(finalizer) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/src/_pytest/nodes.py new/pytest-8.4.2/src/_pytest/nodes.py --- old/pytest-8.4.1/src/_pytest/nodes.py 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/src/_pytest/nodes.py 2025-09-04 16:33:06.000000000 +0200 @@ -8,7 +8,6 @@ from collections.abc import MutableMapping from functools import cached_property from functools import lru_cache -from inspect import signature import os import pathlib from pathlib import Path @@ -29,6 +28,7 @@ from _pytest._code.code import Traceback from _pytest._code.code import TracebackStyle from _pytest.compat import LEGACY_PATH +from _pytest.compat import signature from _pytest.config import Config from _pytest.config import ConftestImportFailure from _pytest.config.compat import _check_path diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/src/_pytest/python_api.py new/pytest-8.4.2/src/_pytest/python_api.py --- old/pytest-8.4.1/src/_pytest/python_api.py 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/src/_pytest/python_api.py 2025-09-04 16:33:06.000000000 +0200 @@ -426,12 +426,9 @@ # Check if `val` is a native bool or numpy bool. if isinstance(val, bool): return True - try: - import numpy as np - + if np := sys.modules.get("numpy"): return isinstance(val, np.bool_) - except ImportError: - return False + return False asarray = _as_numpy_array(actual) if asarray is not None: @@ -531,6 +528,25 @@ DEFAULT_ABSOLUTE_TOLERANCE = Decimal("1e-12") DEFAULT_RELATIVE_TOLERANCE = Decimal("1e-6") + def __repr__(self) -> str: + if isinstance(self.rel, float): + rel = Decimal.from_float(self.rel) + else: + rel = self.rel + + if isinstance(self.abs, float): + abs_ = Decimal.from_float(self.abs) + else: + abs_ = self.abs + + tol_str = "???" + if rel is not None and Decimal("1e-3") <= rel <= Decimal("1e3"): + tol_str = f"{rel:.1e}" + elif abs_ is not None: + tol_str = f"{abs_:.1e}" + + return f"{self.expected} ± {tol_str}" + def approx(expected, rel=None, abs=None, nan_ok: bool = False) -> ApproxBase: """Assert that two numbers (or two ordered sequences of numbers) are equal to each other diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/src/_pytest/raises.py new/pytest-8.4.2/src/_pytest/raises.py --- old/pytest-8.4.1/src/_pytest/raises.py 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/src/_pytest/raises.py 2025-09-04 16:33:06.000000000 +0200 @@ -457,7 +457,7 @@ return cast(type[BaseExcT_1], origin_exc) else: raise ValueError( - f"Only `ExceptionGroup[Exception]` or `BaseExceptionGroup[BaseExeption]` " + f"Only `ExceptionGroup[Exception]` or `BaseExceptionGroup[BaseException]` " f"are accepted as generic types but got `{exc}`. " f"As `raises` will catch all instances of the specified group regardless of the " f"generic argument specific nested exceptions has to be checked " @@ -559,7 +559,7 @@ The type is checked with :func:`isinstance`, and does not need to be an exact match. If that is wanted you can use the ``check`` parameter. - :kwparam str | Pattern[str] match + :kwparam str | Pattern[str] match: A regex to match. :kwparam Callable[[BaseException], bool] check: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/src/_pytest/terminal.py new/pytest-8.4.2/src/_pytest/terminal.py --- old/pytest-8.4.1/src/_pytest/terminal.py 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/src/_pytest/terminal.py 2025-09-04 16:33:06.000000000 +0200 @@ -734,7 +734,9 @@ last_in_module = tests_completed == tests_in_module if self.showlongtestinfo or last_in_module: self._timing_nodeids_reported.update(r.nodeid for r in not_reported) - return format_node_duration(sum(r.duration for r in not_reported)) + return format_node_duration( + sum(r.duration for r in not_reported if isinstance(r, TestReport)) + ) return "" if collected: return f" [{len(self._progress_nodeids_reported) * 100 // collected:3d}%]" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/src/pytest.egg-info/PKG-INFO new/pytest-8.4.2/src/pytest.egg-info/PKG-INFO --- old/pytest-8.4.1/src/pytest.egg-info/PKG-INFO 2025-06-18 00:28:42.000000000 +0200 +++ new/pytest-8.4.2/src/pytest.egg-info/PKG-INFO 2025-09-04 16:33:11.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: pytest -Version: 8.4.1 +Version: 8.4.2 Summary: pytest: simple powerful testing with Python Author: Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin, Others (See AUTHORS) License: MIT diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/src/pytest.egg-info/SOURCES.txt new/pytest-8.4.2/src/pytest.egg-info/SOURCES.txt --- old/pytest-8.4.1/src/pytest.egg-info/SOURCES.txt 2025-06-18 00:28:42.000000000 +0200 +++ new/pytest-8.4.2/src/pytest.egg-info/SOURCES.txt 2025-09-04 16:33:11.000000000 +0200 @@ -253,6 +253,7 @@ doc/en/announce/release-8.3.5.rst doc/en/announce/release-8.4.0.rst doc/en/announce/release-8.4.1.rst +doc/en/announce/release-8.4.2.rst doc/en/announce/sprint2016.rst doc/en/example/attic.rst doc/en/example/conftest.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/testing/conftest.py new/pytest-8.4.2/testing/conftest.py --- old/pytest-8.4.1/testing/conftest.py 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/testing/conftest.py 2025-09-04 16:33:06.000000000 +0200 @@ -237,3 +237,15 @@ result = MockTiming() result.patch(monkeypatch) return result + + [email protected](autouse=True) +def remove_ci_env_var(monkeypatch: MonkeyPatch, request: pytest.FixtureRequest) -> None: + """Make the test insensitive if it is running in CI or not. + + Use `@pytest.mark.keep_ci_var` in a test to avoid applying this fixture, letting the test + see the real `CI` variable (if present). + """ + has_keep_ci_mark = request.node.get_closest_marker("keep_ci_var") is not None + if not has_keep_ci_mark: + monkeypatch.delenv("CI", raising=False) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/testing/python/approx.py new/pytest-8.4.2/testing/python/approx.py --- old/pytest-8.4.1/testing/python/approx.py 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/testing/python/approx.py 2025-09-04 16:33:06.000000000 +0200 @@ -2,6 +2,7 @@ from __future__ import annotations from contextlib import contextmanager +import decimal from decimal import Decimal from fractions import Fraction from math import sqrt @@ -1015,6 +1016,11 @@ expected_repr = "approx([1 ± 1.0e-06, 2 ± 2.0e-06, 3 ± 3.0e-06, 4 ± 4.0e-06])" assert repr(approx(expected)) == expected_repr + def test_decimal_approx_repr(self, monkeypatch) -> None: + monkeypatch.setitem(decimal.getcontext().traps, decimal.FloatOperation, True) + approx_obj = pytest.approx(decimal.Decimal("2.60")) + assert decimal.Decimal("2.600001") == approx_obj + def test_allow_ordered_sequences_only(self) -> None: """pytest.approx() should raise an error on unordered sequences (#9692).""" with pytest.raises(TypeError, match="only supports ordered sequences"): @@ -1079,10 +1085,10 @@ ] def test_map_over_mixed_sequence(self): - assert _recursive_sequence_map(sqrt, [4, (25, 64), [(49)]]) == [ + assert _recursive_sequence_map(sqrt, [4, (25, 64), [49]]) == [ 2, (5, 8), - [(7)], + [7], ] def test_map_over_sequence_like(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/testing/python/raises_group.py new/pytest-8.4.2/testing/python/raises_group.py --- old/pytest-8.4.1/testing/python/raises_group.py 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/testing/python/raises_group.py 2025-09-04 16:33:06.000000000 +0200 @@ -1304,7 +1304,7 @@ def test_annotated_group() -> None: # repr depends on if exceptiongroup backport is being used or not t = repr(ExceptionGroup[ValueError]) - msg = "Only `ExceptionGroup[Exception]` or `BaseExceptionGroup[BaseExeption]` are accepted as generic types but got `{}`. As `raises` will catch all instances of the specified group regardless of the generic argument specific nested exceptions has to be checked with `RaisesGroup`." + msg = "Only `ExceptionGroup[Exception]` or `BaseExceptionGroup[BaseException]` are accepted as generic types but got `{}`. As `raises` will catch all instances of the specified group regardless of the generic argument specific nested exceptions has to be checked with `RaisesGroup`." fail_msg = wrap_escape(msg.format(t)) with pytest.raises(ValueError, match=fail_msg): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/testing/test_collection.py new/pytest-8.4.2/testing/test_collection.py --- old/pytest-8.4.1/testing/test_collection.py 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/testing/test_collection.py 2025-09-04 16:33:06.000000000 +0200 @@ -1895,3 +1895,43 @@ ) # Assert that no tests were collected result.stdout.fnmatch_lines(["*collected 0 items*"]) + + +def test_annotations_deferred_future(pytester: Pytester): + """Ensure stringified annotations don't raise any errors.""" + pytester.makepyfile( + """ + from __future__ import annotations + import pytest + + @pytest.fixture + def func() -> X: ... # X is undefined + + def test_func(): + assert True + """ + ) + result = pytester.runpytest() + assert result.ret == 0 + result.stdout.fnmatch_lines(["*1 passed*"]) + + [email protected]( + sys.version_info < (3, 14), reason="Annotations are only skipped on 3.14+" +) +def test_annotations_deferred_314(pytester: Pytester): + """Ensure annotation eval is deferred.""" + pytester.makepyfile( + """ + import pytest + + @pytest.fixture + def func() -> X: ... # X is undefined + + def test_func(): + assert True + """ + ) + result = pytester.runpytest() + assert result.ret == 0 + result.stdout.fnmatch_lines(["*1 passed*"]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/testing/test_doctest.py new/pytest-8.4.2/testing/test_doctest.py --- old/pytest-8.4.1/testing/test_doctest.py 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/testing/test_doctest.py 2025-09-04 16:33:06.000000000 +0200 @@ -223,9 +223,12 @@ "002 >>> 0 / i", "UNEXPECTED EXCEPTION: ZeroDivisionError*", "Traceback (most recent call last):", - ' File "*/doctest.py", line *, in __run', - " *", - *((" *^^^^*", " *", " *") if sys.version_info >= (3, 13) else ()), + *( + (' File "*/doctest.py", line *, in __run', " *") + if sys.version_info <= (3, 14) + else () + ), + *((" *^^^^*", " *", " *") if sys.version_info[:2] == (3, 13) else ()), ' File "<doctest test_doctest_unexpected_exception.txt[1]>", line 1, in <module>', "ZeroDivisionError: division by zero", "*/test_doctest_unexpected_exception.txt:2: UnexpectedException", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/testing/test_faulthandler.py new/pytest-8.4.2/testing/test_faulthandler.py --- old/pytest-8.4.1/testing/test_faulthandler.py 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/testing/test_faulthandler.py 2025-09-04 16:33:06.000000000 +0200 @@ -71,6 +71,7 @@ assert result.ret == 0 [email protected]_ci_var @pytest.mark.parametrize( "enabled", [ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/testing/test_terminal.py new/pytest-8.4.2/testing/test_terminal.py --- old/pytest-8.4.1/testing/test_terminal.py 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/testing/test_terminal.py 2025-09-04 16:33:06.000000000 +0200 @@ -112,6 +112,31 @@ [" def test_func():", "> assert 0", "E assert 0"] ) + def test_console_output_style_times_with_skipped_and_passed( + self, pytester: Pytester + ) -> None: + pytester.makepyfile( + test_repro=""" + def test_hello(): + pass + """, + test_repro_skip=""" + import pytest + pytest.importorskip("fakepackage_does_not_exist") + """, + ) + result = pytester.runpytest( + "test_repro.py", + "test_repro_skip.py", + "-o", + "console_output_style=times", + ) + + result.stdout.fnmatch_lines("* 1 passed, 1 skipped in *") + + combined = "\n".join(result.stdout.lines + result.stderr.lines) + assert "INTERNALERROR" not in combined + def test_internalerror(self, pytester: Pytester, linecomp) -> None: modcol = pytester.getmodulecol("def test_one(): pass") rep = TerminalReporter(modcol.config, file=linecomp.stringio) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/testing/test_threadexception.py new/pytest-8.4.2/testing/test_threadexception.py --- old/pytest-8.4.1/testing/test_threadexception.py 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/testing/test_threadexception.py 2025-09-04 16:33:06.000000000 +0200 @@ -211,7 +211,7 @@ """ ) - result = pytester.runpytest() + result = pytester.runpytest("-Werror") # TODO: should be a test failure or error assert result.ret == pytest.ExitCode.INTERNAL_ERROR diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/testing/test_warnings.py new/pytest-8.4.2/testing/test_warnings.py --- old/pytest-8.4.1/testing/test_warnings.py 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/testing/test_warnings.py 2025-09-04 16:33:06.000000000 +0200 @@ -149,6 +149,7 @@ ) [email protected]("issue #13485") def test_works_with_filterwarnings(pytester: Pytester) -> None: """Ensure our warnings capture does not mess with pre-installed filters (#2430).""" pytester.makepyfile( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-8.4.1/tox.ini new/pytest-8.4.2/tox.ini --- old/pytest-8.4.1/tox.ini 2025-06-18 00:28:38.000000000 +0200 +++ new/pytest-8.4.2/tox.ini 2025-09-04 16:33:06.000000000 +0200 @@ -52,6 +52,7 @@ PYTEST_ADDOPTS TERM SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST + CI setenv = _PYTEST_TOX_DEFAULT_POSARGS={env:_PYTEST_TOX_POSARGS_DOCTESTING:} {env:_PYTEST_TOX_POSARGS_LSOF:} {env:_PYTEST_TOX_POSARGS_XDIST:} {env:_PYTEST_FILES:}
