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 2023-06-21 22:36:57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pytest (Old) and /work/SRC/openSUSE:Factory/.python-pytest.new.15902 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pytest" Wed Jun 21 22:36:57 2023 rev:77 rq:1093826 version:7.3.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pytest/python-pytest.changes 2023-06-14 16:29:00.862348353 +0200 +++ /work/SRC/openSUSE:Factory/.python-pytest.new.15902/python-pytest.changes 2023-06-21 22:37:07.737385318 +0200 @@ -1,0 +2,18 @@ +Mon Jun 19 20:12:27 UTC 2023 - Dirk Müller <dmuel...@suse.com> + +- update to 7.3.2: + * Fix bug where very long option + names could cause pytest to break with ``OSError: [Errno 36] + File name too long`` on some systems. + * Support for Python 3.12 + * honored to load root ``conftests``. + * The `monkeypatch` `setitem`/`delitem` type annotations now + allow `TypedDict` arguments. + * Fixed bug in assertion rewriting + where a variable assigned with the walrus operator could not + be used later in a function call. + * Fixed ``--last-failed``'s + "(skipped N files)" functionality for files inside of + packages (directories with `__init__.py` files). + +------------------------------------------------------------------- Old: ---- pytest-7.3.1.tar.gz New: ---- pytest-7.3.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pytest.spec ++++++ --- /var/tmp/diff_new_pack.6sk6Hk/_old 2023-06-21 22:37:08.465389700 +0200 +++ /var/tmp/diff_new_pack.6sk6Hk/_new 2023-06-21 22:37:08.473389748 +0200 @@ -33,7 +33,7 @@ %{?sle15_python_module_pythons} Name: python-pytest%{psuffix} -Version: 7.3.1 +Version: 7.3.2 Release: 0 Summary: Simple powerful testing with Python License: MIT ++++++ pytest-7.3.1.tar.gz -> pytest-7.3.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/.github/workflows/test.yml new/pytest-7.3.2/.github/workflows/test.yml --- old/pytest-7.3.1/.github/workflows/test.yml 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/.github/workflows/test.yml 2023-06-10 21:28:00.000000000 +0200 @@ -43,6 +43,7 @@ "windows-py39", "windows-py310", "windows-py311", + "windows-py312", "ubuntu-py37", "ubuntu-py37-pluggy", @@ -51,12 +52,13 @@ "ubuntu-py39", "ubuntu-py310", "ubuntu-py311", + "ubuntu-py312", "ubuntu-pypy3", "macos-py37", - "macos-py38", "macos-py39", "macos-py310", + "macos-py312", "docs", "doctesting", @@ -86,9 +88,13 @@ os: windows-latest tox_env: "py310-xdist" - name: "windows-py311" - python: "3.11-dev" + python: "3.11" os: windows-latest tox_env: "py311" + - name: "windows-py312" + python: "3.12-dev" + os: windows-latest + tox_env: "py312" - name: "ubuntu-py37" python: "3.7" @@ -116,10 +122,15 @@ os: ubuntu-latest tox_env: "py310-xdist" - name: "ubuntu-py311" - python: "3.11-dev" + python: "3.11" os: ubuntu-latest tox_env: "py311" use_coverage: true + - name: "ubuntu-py312" + python: "3.12-dev" + os: ubuntu-latest + tox_env: "py312" + use_coverage: true - name: "ubuntu-pypy3" python: "pypy-3.7" os: ubuntu-latest @@ -129,19 +140,19 @@ python: "3.7" os: macos-latest tox_env: "py37-xdist" - - name: "macos-py38" - python: "3.8" - os: macos-latest - tox_env: "py38-xdist" - use_coverage: true - name: "macos-py39" python: "3.9" os: macos-latest tox_env: "py39-xdist" + use_coverage: true - name: "macos-py310" python: "3.10" os: macos-latest tox_env: "py310-xdist" + - name: "macos-py312" + python: "3.12-dev" + os: macos-latest + tox_env: "py312-xdist" - name: "plugins" python: "3.9" @@ -168,6 +179,7 @@ uses: actions/setup-python@v4 with: python-version: ${{ matrix.python }} + check-latest: ${{ endsWith(matrix.python, '-dev') }} - name: Install dependencies run: | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/.pre-commit-config.yaml new/pytest-7.3.2/.pre-commit-config.yaml --- old/pytest-7.3.1/.pre-commit-config.yaml 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/.pre-commit-config.yaml 2023-06-10 21:28:00.000000000 +0200 @@ -52,7 +52,7 @@ rev: v2.2.0 hooks: - id: setup-cfg-fmt - args: ["--max-py-version=3.11", "--include-version-classifiers"] + args: ["--max-py-version=3.12", "--include-version-classifiers"] - repo: https://github.com/pre-commit/pygrep-hooks rev: v1.10.0 hooks: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/AUTHORS new/pytest-7.3.2/AUTHORS --- old/pytest-7.3.1/AUTHORS 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/AUTHORS 2023-06-10 21:28:00.000000000 +0200 @@ -8,6 +8,7 @@ Abdelrahman Elbehery Abhijeet Kasurde Adam Johnson +Adam Stewart Adam Uhlir Ahn Ki-Wook Akiomi Kamakura diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/PKG-INFO new/pytest-7.3.2/PKG-INFO --- old/pytest-7.3.1/PKG-INFO 2023-04-14 20:11:06.886402100 +0200 +++ new/pytest-7.3.2/PKG-INFO 2023-06-10 21:28:30.317522000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pytest -Version: 7.3.1 +Version: 7.3.2 Summary: pytest: simple powerful testing with Python Home-page: https://docs.pytest.org/en/latest/ Author: Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin and others @@ -28,6 +28,7 @@ Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 Classifier: Topic :: Software Development :: Libraries Classifier: Topic :: Software Development :: Testing Classifier: Topic :: Utilities diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/doc/en/announce/index.rst new/pytest-7.3.2/doc/en/announce/index.rst --- old/pytest-7.3.1/doc/en/announce/index.rst 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/doc/en/announce/index.rst 2023-06-10 21:28:00.000000000 +0200 @@ -6,6 +6,7 @@ :maxdepth: 2 + release-7.3.2 release-7.3.1 release-7.3.0 release-7.2.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/doc/en/announce/release-7.3.2.rst new/pytest-7.3.2/doc/en/announce/release-7.3.2.rst --- old/pytest-7.3.1/doc/en/announce/release-7.3.2.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/pytest-7.3.2/doc/en/announce/release-7.3.2.rst 2023-06-10 21:28:00.000000000 +0200 @@ -0,0 +1,21 @@ +pytest-7.3.2 +======================================= + +pytest 7.3.2 has just been released to PyPI. + +This is a bug-fix release, being a drop-in replacement. To upgrade:: + + pip install --upgrade pytest + +The full changelog is available at https://docs.pytest.org/en/stable/changelog.html. + +Thanks to all of the contributors to this release: + +* Adam J. Stewart +* Alessio Izzo +* Bruno Oliveira +* Ran Benita + + +Happy testing, +The pytest Development Team diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/doc/en/backwards-compatibility.rst new/pytest-7.3.2/doc/en/backwards-compatibility.rst --- old/pytest-7.3.1/doc/en/backwards-compatibility.rst 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/doc/en/backwards-compatibility.rst 2023-06-10 21:28:00.000000000 +0200 @@ -92,3 +92,5 @@ 5.0 - 6.1 3.5+ 3.3 - 4.6 2.7, 3.4+ ============== =================== + +`Status of Python Versions <https://devguide.python.org/versions/>`__. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/doc/en/builtin.rst new/pytest-7.3.2/doc/en/builtin.rst --- old/pytest-7.3.1/doc/en/builtin.rst 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/doc/en/builtin.rst 2023-06-10 21:28:00.000000000 +0200 @@ -207,7 +207,7 @@ * caplog.record_tuples -> list of (logger_name, level, message) tuples * caplog.clear() -> clear captured records and formatted log output string - monkeypatch -- .../_pytest/monkeypatch.py:29 + monkeypatch -- .../_pytest/monkeypatch.py:30 A convenient fixture for monkey-patching. The fixture provides these methods to modify objects, dictionaries, or diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/doc/en/changelog.rst new/pytest-7.3.2/doc/en/changelog.rst --- old/pytest-7.3.1/doc/en/changelog.rst 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/doc/en/changelog.rst 2023-06-10 21:28:00.000000000 +0200 @@ -28,6 +28,30 @@ .. towncrier release notes start +pytest 7.3.2 (2023-06-10) +========================= + +Bug Fixes +--------- + +- `#10169 <https://github.com/pytest-dev/pytest/issues/10169>`_: Fix bug where very long option names could cause pytest to break with ``OSError: [Errno 36] File name too long`` on some systems. + + +- `#10894 <https://github.com/pytest-dev/pytest/issues/10894>`_: Support for Python 3.12 (beta at the time of writing). + + +- `#10987 <https://github.com/pytest-dev/pytest/issues/10987>`_: :confval:`testpaths` is now honored to load root ``conftests``. + + +- `#10999 <https://github.com/pytest-dev/pytest/issues/10999>`_: The `monkeypatch` `setitem`/`delitem` type annotations now allow `TypedDict` arguments. + + +- `#11028 <https://github.com/pytest-dev/pytest/issues/11028>`_: Fixed bug in assertion rewriting where a variable assigned with the walrus operator could not be used later in a function call. + + +- `#11054 <https://github.com/pytest-dev/pytest/issues/11054>`_: Fixed ``--last-failed``'s "(skipped N files)" functionality for files inside of packages (directories with `__init__.py` files). + + pytest 7.3.1 (2023-04-14) ========================= @@ -567,7 +591,7 @@ - `#7259 <https://github.com/pytest-dev/pytest/issues/7259>`_: The :ref:`Node.reportinfo() <non-python tests>` 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 :class:`pytest.Item` implementation. - Since `py.path.local` is a `os.PathLike[str]`, these plugins are unaffacted. + Since `py.path.local` is an `os.PathLike[str]`, these plugins are unaffacted. 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. @@ -4067,7 +4091,7 @@ See our :ref:`docs <calling fixtures directly deprecated>` on information on how to update your code. -- :issue:`4546`: Remove ``Node.get_marker(name)`` the return value was not usable for more than a existence check. +- :issue:`4546`: Remove ``Node.get_marker(name)`` the return value was not usable for more than an existence check. Use ``Node.get_closest_marker(name)`` as a replacement. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/doc/en/conf.py new/pytest-7.3.2/doc/en/conf.py --- old/pytest-7.3.1/doc/en/conf.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/doc/en/conf.py 2023-06-10 21:28:00.000000000 +0200 @@ -341,7 +341,7 @@ # The scheme of the identifier. Typical schemes are ISBN or URL. # epub_scheme = '' -# The unique identifier of the text. This can be a ISBN number +# The unique identifier of the text. This can be an ISBN number # or the project homepage. # epub_identifier = '' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/doc/en/example/nonpython/conftest.py new/pytest-7.3.2/doc/en/example/nonpython/conftest.py --- old/pytest-7.3.1/doc/en/example/nonpython/conftest.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/doc/en/example/nonpython/conftest.py 2023-06-10 21:28:00.000000000 +0200 @@ -38,6 +38,7 @@ " no further details known at this point.", ] ) + return super().repr_failure(excinfo) def reportinfo(self): return self.path, 0, f"usecase: {self.name}" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/doc/en/getting-started.rst new/pytest-7.3.2/doc/en/getting-started.rst --- old/pytest-7.3.1/doc/en/getting-started.rst 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/doc/en/getting-started.rst 2023-06-10 21:28:00.000000000 +0200 @@ -22,7 +22,7 @@ .. code-block:: bash $ pytest --version - pytest 7.3.1 + pytest 7.3.2 .. _`simpletest`: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/doc/en/index.rst new/pytest-7.3.2/doc/en/index.rst --- old/pytest-7.3.1/doc/en/index.rst 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/doc/en/index.rst 2023-06-10 21:28:00.000000000 +0200 @@ -1,11 +1,10 @@ :orphan: -.. - .. sidebar:: Next Open Trainings +.. sidebar:: Next Open Trainings - - `Professional Testing with Python <https://python-academy.com/courses/python_course_testing.html>`_, via `Python Academy <https://www.python-academy.com/>`_, March 7th to 9th 2023 (3 day in-depth training), Remote + - `Professional Testing with Python <https://python-academy.com/courses/python_course_testing.html>`_, via `Python Academy <https://www.python-academy.com/>`_, March 5th to 7th 2024 (3 day in-depth training), Leipzig/Remote - Also see :doc:`previous talks and blogposts <talks>`. + Also see :doc:`previous talks and blogposts <talks>`. .. _features: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/doc/en/reference/reference.rst new/pytest-7.3.2/doc/en/reference/reference.rst --- old/pytest-7.3.1/doc/en/reference/reference.rst 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/doc/en/reference/reference.rst 2023-06-10 21:28:00.000000000 +0200 @@ -1049,11 +1049,11 @@ .. envvar:: CI -When set (regardless of value), pytest acknowledges that is running in a CI process. Alterative to ``BUILD_NUMBER`` variable. +When set (regardless of value), pytest acknowledges that is running in a CI process. Alternative to ``BUILD_NUMBER`` variable. .. envvar:: BUILD_NUMBER -When set (regardless of value), pytest acknowledges that is running in a CI process. Alterative to CI variable. +When set (regardless of value), pytest acknowledges that is running in a CI process. Alternative to CI variable. .. envvar:: PYTEST_ADDOPTS @@ -1713,13 +1713,12 @@ .. confval:: testpaths - - Sets list of directories that should be searched for tests when no specific directories, files or test ids are given in the command line when executing pytest from the :ref:`rootdir <rootdir>` directory. File system paths may use shell-style wildcards, including the recursive ``**`` pattern. + Useful when all project tests are in a known location to speed up test collection and to avoid picking up undesired tests by accident. @@ -1728,8 +1727,17 @@ [pytest] testpaths = testing doc - This tells pytest to only look for tests in ``testing`` and ``doc`` - directories when executing from the root directory. + This configuration means that executing: + + .. code-block:: console + + pytest + + has the same practical effects as executing: + + .. code-block:: console + + pytest testing doc .. confval:: tmp_path_retention_count @@ -1744,7 +1752,7 @@ [pytest] tmp_path_retention_count = 3 - Default: 3 + Default: ``3`` .. confval:: tmp_path_retention_policy @@ -1763,7 +1771,7 @@ [pytest] tmp_path_retention_policy = "all" - Default: all + Default: ``all`` .. confval:: usefixtures @@ -1996,7 +2004,7 @@ Auto-indent multiline messages passed to the logging module. Accepts true|on, false|off or an integer. --log-disable=LOGGER_DISABLE - Disable a logger by name. Can be passed multipe + Disable a logger by name. Can be passed multiple times. [pytest] ini-options in the first pytest.ini|tox.ini|setup.cfg|pyproject.toml file found: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/setup.cfg new/pytest-7.3.2/setup.cfg --- old/pytest-7.3.1/setup.cfg 2023-04-14 20:11:06.886402100 +0200 +++ new/pytest-7.3.2/setup.cfg 2023-06-10 21:28:30.317522000 +0200 @@ -22,6 +22,7 @@ Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 + Programming Language :: Python :: 3.12 Topic :: Software Development :: Libraries Topic :: Software Development :: Testing Topic :: Utilities @@ -73,6 +74,7 @@ nose pygments>=2.7.2 requests + setuptools xmlschema [options.package_data] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/src/_pytest/_py/path.py new/pytest-7.3.2/src/_pytest/_py/path.py --- old/pytest-7.3.1/src/_pytest/_py/path.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/src/_pytest/_py/path.py 2023-06-10 21:28:00.000000000 +0200 @@ -953,7 +953,7 @@ else: p.dirpath()._ensuredirs() if not p.check(file=1): - p.open("w").close() + p.open("wb").close() return p @overload diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/src/_pytest/_version.py new/pytest-7.3.2/src/_pytest/_version.py --- old/pytest-7.3.1/src/_pytest/_version.py 2023-04-14 20:11:06.000000000 +0200 +++ new/pytest-7.3.2/src/_pytest/_version.py 2023-06-10 21:28:30.000000000 +0200 @@ -1,4 +1,4 @@ # file generated by setuptools_scm # don't change, don't track in version control -__version__ = version = '7.3.1' -__version_tuple__ = version_tuple = (7, 3, 1) +__version__ = version = '7.3.2' +__version_tuple__ = version_tuple = (7, 3, 2) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/src/_pytest/assertion/rewrite.py new/pytest-7.3.2/src/_pytest/assertion/rewrite.py --- old/pytest-7.3.1/src/_pytest/assertion/rewrite.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/src/_pytest/assertion/rewrite.py 2023-06-10 21:28:00.000000000 +0200 @@ -46,8 +46,14 @@ if sys.version_info >= (3, 8): namedExpr = ast.NamedExpr + astNameConstant = ast.Constant + astStr = ast.Constant + astNum = ast.Constant else: namedExpr = ast.Expr + astNameConstant = ast.NameConstant + astStr = ast.Str + astNum = ast.Num assertstate_key = StashKey["AssertionState"]() @@ -680,9 +686,12 @@ if ( expect_docstring and isinstance(item, ast.Expr) - and isinstance(item.value, ast.Str) + and isinstance(item.value, astStr) ): - doc = item.value.s + if sys.version_info >= (3, 8): + doc = item.value.value + else: + doc = item.value.s if self.is_rewrite_disabled(doc): return expect_docstring = False @@ -814,7 +823,7 @@ current = self.stack.pop() if self.stack: self.explanation_specifiers = self.stack[-1] - keys = [ast.Str(key) for key in current.keys()] + keys = [astStr(key) for key in current.keys()] format_dict = ast.Dict(keys, list(current.values())) form = ast.BinOp(expl_expr, ast.Mod(), format_dict) name = "@py_format" + str(next(self.variable_counter)) @@ -868,16 +877,16 @@ negation = ast.UnaryOp(ast.Not(), top_condition) if self.enable_assertion_pass_hook: # Experimental pytest_assertion_pass hook - msg = self.pop_format_context(ast.Str(explanation)) + msg = self.pop_format_context(astStr(explanation)) # Failed if assert_.msg: assertmsg = self.helper("_format_assertmsg", assert_.msg) gluestr = "\n>assert " else: - assertmsg = ast.Str("") + assertmsg = astStr("") gluestr = "assert " - err_explanation = ast.BinOp(ast.Str(gluestr), ast.Add(), msg) + err_explanation = ast.BinOp(astStr(gluestr), ast.Add(), msg) err_msg = ast.BinOp(assertmsg, ast.Add(), err_explanation) err_name = ast.Name("AssertionError", ast.Load()) fmt = self.helper("_format_explanation", err_msg) @@ -893,8 +902,8 @@ hook_call_pass = ast.Expr( self.helper( "_call_assertion_pass", - ast.Num(assert_.lineno), - ast.Str(orig), + astNum(assert_.lineno), + astStr(orig), fmt_pass, ) ) @@ -913,7 +922,7 @@ variables = [ ast.Name(name, ast.Store()) for name in self.format_variables ] - clear_format = ast.Assign(variables, ast.NameConstant(None)) + clear_format = ast.Assign(variables, astNameConstant(None)) self.statements.append(clear_format) else: # Original assertion rewriting @@ -924,9 +933,9 @@ assertmsg = self.helper("_format_assertmsg", assert_.msg) explanation = "\n>assert " + explanation else: - assertmsg = ast.Str("") + assertmsg = astStr("") explanation = "assert " + explanation - template = ast.BinOp(assertmsg, ast.Add(), ast.Str(explanation)) + template = ast.BinOp(assertmsg, ast.Add(), astStr(explanation)) msg = self.pop_format_context(template) fmt = self.helper("_format_explanation", msg) err_name = ast.Name("AssertionError", ast.Load()) @@ -938,7 +947,7 @@ # Clear temporary variables by setting them to None. if self.variables: variables = [ast.Name(name, ast.Store()) for name in self.variables] - clear = ast.Assign(variables, ast.NameConstant(None)) + clear = ast.Assign(variables, astNameConstant(None)) self.statements.append(clear) # Fix locations (line numbers/column offsets). for stmt in self.statements: @@ -952,20 +961,20 @@ # thinks it's acceptable. locs = ast.Call(self.builtin("locals"), [], []) target_id = name.target.id # type: ignore[attr-defined] - inlocs = ast.Compare(ast.Str(target_id), [ast.In()], [locs]) + inlocs = ast.Compare(astStr(target_id), [ast.In()], [locs]) dorepr = self.helper("_should_repr_global_name", name) test = ast.BoolOp(ast.Or(), [inlocs, dorepr]) - expr = ast.IfExp(test, self.display(name), ast.Str(target_id)) + expr = ast.IfExp(test, self.display(name), astStr(target_id)) return name, self.explanation_param(expr) def visit_Name(self, name: ast.Name) -> Tuple[ast.Name, str]: # Display the repr of the name if it's a local variable or # _should_repr_global_name() thinks it's acceptable. locs = ast.Call(self.builtin("locals"), [], []) - inlocs = ast.Compare(ast.Str(name.id), [ast.In()], [locs]) + inlocs = ast.Compare(astStr(name.id), [ast.In()], [locs]) dorepr = self.helper("_should_repr_global_name", name) test = ast.BoolOp(ast.Or(), [inlocs, dorepr]) - expr = ast.IfExp(test, self.display(name), ast.Str(name.id)) + expr = ast.IfExp(test, self.display(name), astStr(name.id)) return name, self.explanation_param(expr) def visit_BoolOp(self, boolop: ast.BoolOp) -> Tuple[ast.Name, str]: @@ -996,12 +1005,14 @@ ] ): pytest_temp = self.variable() - self.variables_overwrite[v.left.target.id] = pytest_temp + self.variables_overwrite[ + v.left.target.id + ] = v.left # type:ignore[assignment] v.left.target.id = pytest_temp self.push_format_context() res, expl = self.visit(v) body.append(ast.Assign([ast.Name(res_var, ast.Store())], res)) - expl_format = self.pop_format_context(ast.Str(expl)) + expl_format = self.pop_format_context(astStr(expl)) call = ast.Call(app, [expl_format], []) self.expl_stmts.append(ast.Expr(call)) if i < levels: @@ -1013,7 +1024,7 @@ self.statements = body = inner self.statements = save self.expl_stmts = fail_save - expl_template = self.helper("_format_boolop", expl_list, ast.Num(is_or)) + expl_template = self.helper("_format_boolop", expl_list, astNum(is_or)) expl = self.pop_format_context(expl_template) return ast.Name(res_var, ast.Load()), self.explanation_param(expl) @@ -1037,10 +1048,19 @@ new_args = [] new_kwargs = [] for arg in call.args: + if isinstance(arg, ast.Name) and arg.id in self.variables_overwrite: + arg = self.variables_overwrite[arg.id] # type:ignore[assignment] res, expl = self.visit(arg) arg_expls.append(expl) new_args.append(res) for keyword in call.keywords: + if ( + isinstance(keyword.value, ast.Name) + and keyword.value.id in self.variables_overwrite + ): + keyword.value = self.variables_overwrite[ + keyword.value.id + ] # type:ignore[assignment] res, expl = self.visit(keyword.value) new_kwargs.append(ast.keyword(keyword.arg, res)) if keyword.arg: @@ -1075,7 +1095,13 @@ self.push_format_context() # We first check if we have overwritten a variable in the previous assert if isinstance(comp.left, ast.Name) and comp.left.id in self.variables_overwrite: - comp.left.id = self.variables_overwrite[comp.left.id] + comp.left = self.variables_overwrite[ + comp.left.id + ] # type:ignore[assignment] + if isinstance(comp.left, namedExpr): + self.variables_overwrite[ + comp.left.target.id + ] = comp.left # type:ignore[assignment] left_res, left_expl = self.visit(comp.left) if isinstance(comp.left, (ast.Compare, ast.BoolOp)): left_expl = f"({left_expl})" @@ -1093,15 +1119,17 @@ and next_operand.target.id == left_res.id ): next_operand.target.id = self.variable() - self.variables_overwrite[left_res.id] = next_operand.target.id + self.variables_overwrite[ + left_res.id + ] = next_operand # type:ignore[assignment] next_res, next_expl = self.visit(next_operand) if isinstance(next_operand, (ast.Compare, ast.BoolOp)): next_expl = f"({next_expl})" results.append(next_res) sym = BINOP_MAP[op.__class__] - syms.append(ast.Str(sym)) + syms.append(astStr(sym)) expl = f"{left_expl} {sym} {next_expl}" - expls.append(ast.Str(expl)) + expls.append(astStr(expl)) res_expr = ast.Compare(left_res, [op], [next_res]) self.statements.append(ast.Assign([store_names[i]], res_expr)) left_res, left_expl = next_res, next_expl diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/src/_pytest/cacheprovider.py new/pytest-7.3.2/src/_pytest/cacheprovider.py --- old/pytest-7.3.1/src/_pytest/cacheprovider.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/src/_pytest/cacheprovider.py 2023-06-10 21:28:00.000000000 +0200 @@ -213,7 +213,7 @@ @hookimpl(hookwrapper=True) def pytest_make_collect_report(self, collector: nodes.Collector): - if isinstance(collector, Session): + if isinstance(collector, (Session, Package)): out = yield res: CollectReport = out.get_result() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/src/_pytest/capture.py new/pytest-7.3.2/src/_pytest/capture.py --- old/pytest-7.3.1/src/_pytest/capture.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/src/_pytest/capture.py 2023-06-10 21:28:00.000000000 +0200 @@ -241,7 +241,7 @@ raise UnsupportedOperation("redirected stdin is pseudofile, has no tell()") def truncate(self, size: Optional[int] = None) -> int: - raise UnsupportedOperation("cannont truncate stdin") + raise UnsupportedOperation("cannot truncate stdin") def write(self, data: str) -> int: raise UnsupportedOperation("cannot write to stdin") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/src/_pytest/config/__init__.py new/pytest-7.3.2/src/_pytest/config/__init__.py --- old/pytest-7.3.1/src/_pytest/config/__init__.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/src/_pytest/config/__init__.py 2023-06-10 21:28:00.000000000 +0200 @@ -526,7 +526,10 @@ # Internal API for local conftest plugin handling. # def _set_initial_conftests( - self, namespace: argparse.Namespace, rootpath: Path + self, + namespace: argparse.Namespace, + rootpath: Path, + testpaths_ini: Sequence[str], ) -> None: """Load initial conftest files given a preparsed "namespace". @@ -543,7 +546,7 @@ ) self._noconftest = namespace.noconftest self._using_pyargs = namespace.pyargs - testpaths = namespace.file_or_dir + testpaths = namespace.file_or_dir + testpaths_ini foundanchor = False for testpath in testpaths: path = str(testpath) @@ -552,7 +555,14 @@ if i != -1: path = path[:i] anchor = absolutepath(current / path) - if anchor.exists(): # we found some file object + + # Ensure we do not break if what appears to be an anchor + # is in fact a very long option (#10169). + try: + anchor_exists = anchor.exists() + except OSError: # pragma: no cover + anchor_exists = False + if anchor_exists: self._try_load_conftest(anchor, namespace.importmode, rootpath) foundanchor = True if not foundanchor: @@ -1131,7 +1141,9 @@ @hookimpl(trylast=True) def pytest_load_initial_conftests(self, early_config: "Config") -> None: self.pluginmanager._set_initial_conftests( - early_config.known_args_namespace, rootpath=early_config.rootpath + early_config.known_args_namespace, + rootpath=early_config.rootpath, + testpaths_ini=self.getini("testpaths"), ) def _initini(self, args: Sequence[str]) -> None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/src/_pytest/faulthandler.py new/pytest-7.3.2/src/_pytest/faulthandler.py --- old/pytest-7.3.1/src/_pytest/faulthandler.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/src/_pytest/faulthandler.py 2023-06-10 21:28:00.000000000 +0200 @@ -2,7 +2,6 @@ import os import sys from typing import Generator -from typing import TextIO import pytest from _pytest.config import Config @@ -11,7 +10,7 @@ from _pytest.stash import StashKey -fault_handler_stderr_key = StashKey[TextIO]() +fault_handler_stderr_fd_key = StashKey[int]() fault_handler_originally_enabled_key = StashKey[bool]() @@ -26,10 +25,9 @@ def pytest_configure(config: Config) -> None: import faulthandler - stderr_fd_copy = os.dup(get_stderr_fileno()) - config.stash[fault_handler_stderr_key] = open(stderr_fd_copy, "w") + config.stash[fault_handler_stderr_fd_key] = os.dup(get_stderr_fileno()) config.stash[fault_handler_originally_enabled_key] = faulthandler.is_enabled() - faulthandler.enable(file=config.stash[fault_handler_stderr_key]) + faulthandler.enable(file=config.stash[fault_handler_stderr_fd_key]) def pytest_unconfigure(config: Config) -> None: @@ -37,9 +35,9 @@ faulthandler.disable() # Close the dup file installed during pytest_configure. - if fault_handler_stderr_key in config.stash: - config.stash[fault_handler_stderr_key].close() - del config.stash[fault_handler_stderr_key] + if fault_handler_stderr_fd_key in config.stash: + os.close(config.stash[fault_handler_stderr_fd_key]) + del config.stash[fault_handler_stderr_fd_key] if config.stash.get(fault_handler_originally_enabled_key, False): # Re-enable the faulthandler if it was originally enabled. faulthandler.enable(file=get_stderr_fileno()) @@ -67,10 +65,10 @@ @pytest.hookimpl(hookwrapper=True, trylast=True) def pytest_runtest_protocol(item: Item) -> Generator[None, None, None]: timeout = get_timeout_config_value(item.config) - stderr = item.config.stash[fault_handler_stderr_key] - if timeout > 0 and stderr is not None: + if timeout > 0: import faulthandler + stderr = item.config.stash[fault_handler_stderr_fd_key] faulthandler.dump_traceback_later(timeout, file=stderr) try: yield diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/src/_pytest/hookspec.py new/pytest-7.3.2/src/_pytest/hookspec.py --- old/pytest-7.3.1/src/_pytest/hookspec.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/src/_pytest/hookspec.py 2023-06-10 21:28:00.000000000 +0200 @@ -21,7 +21,7 @@ from typing_extensions import Literal from _pytest._code.code import ExceptionRepr - from _pytest.code import ExceptionInfo + from _pytest._code.code import ExceptionInfo from _pytest.config import Config from _pytest.config import ExitCode from _pytest.config import PytestPluginManager diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/src/_pytest/logging.py new/pytest-7.3.2/src/_pytest/logging.py --- old/pytest-7.3.1/src/_pytest/logging.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/src/_pytest/logging.py 2023-06-10 21:28:00.000000000 +0200 @@ -302,7 +302,7 @@ action="append", default=[], dest="logger_disable", - help="Disable a logger by name. Can be passed multipe times.", + help="Disable a logger by name. Can be passed multiple times.", ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/src/_pytest/mark/expression.py new/pytest-7.3.2/src/_pytest/mark/expression.py --- old/pytest-7.3.1/src/_pytest/mark/expression.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/src/_pytest/mark/expression.py 2023-06-10 21:28:00.000000000 +0200 @@ -18,6 +18,7 @@ import dataclasses import enum import re +import sys import types from typing import Callable from typing import Iterator @@ -26,6 +27,11 @@ from typing import Optional from typing import Sequence +if sys.version_info >= (3, 8): + astNameConstant = ast.Constant +else: + astNameConstant = ast.NameConstant + __all__ = [ "Expression", @@ -132,7 +138,7 @@ def expression(s: Scanner) -> ast.Expression: if s.accept(TokenType.EOF): - ret: ast.expr = ast.NameConstant(False) + ret: ast.expr = astNameConstant(False) else: ret = expr(s) s.accept(TokenType.EOF, reject=True) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/src/_pytest/monkeypatch.py new/pytest-7.3.2/src/_pytest/monkeypatch.py --- old/pytest-7.3.1/src/_pytest/monkeypatch.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/src/_pytest/monkeypatch.py 2023-06-10 21:28:00.000000000 +0200 @@ -7,6 +7,7 @@ from typing import Any from typing import Generator from typing import List +from typing import Mapping from typing import MutableMapping from typing import Optional from typing import overload @@ -129,7 +130,7 @@ def __init__(self) -> None: self._setattr: List[Tuple[object, str, object]] = [] - self._setitem: List[Tuple[MutableMapping[Any, Any], object, object]] = [] + self._setitem: List[Tuple[Mapping[Any, Any], object, object]] = [] self._cwd: Optional[str] = None self._savesyspath: Optional[List[str]] = None @@ -290,12 +291,13 @@ self._setattr.append((target, name, oldval)) delattr(target, name) - def setitem(self, dic: MutableMapping[K, V], name: K, value: V) -> None: + def setitem(self, dic: Mapping[K, V], name: K, value: V) -> None: """Set dictionary entry ``name`` to value.""" self._setitem.append((dic, name, dic.get(name, notset))) - dic[name] = value + # Not all Mapping types support indexing, but MutableMapping doesn't support TypedDict + dic[name] = value # type: ignore[index] - def delitem(self, dic: MutableMapping[K, V], name: K, raising: bool = True) -> None: + def delitem(self, dic: Mapping[K, V], name: K, raising: bool = True) -> None: """Delete ``name`` from dict. Raises ``KeyError`` if it doesn't exist, unless ``raising`` is set to @@ -306,7 +308,8 @@ raise KeyError(name) else: self._setitem.append((dic, name, dic.get(name, notset))) - del dic[name] + # Not all Mapping types support indexing, but MutableMapping doesn't support TypedDict + del dic[name] # type: ignore[attr-defined] def setenv(self, name: str, value: str, prepend: Optional[str] = None) -> None: """Set environment variable ``name`` to ``value``. @@ -401,11 +404,13 @@ for dictionary, key, value in reversed(self._setitem): if value is notset: try: - del dictionary[key] + # Not all Mapping types support indexing, but MutableMapping doesn't support TypedDict + del dictionary[key] # type: ignore[attr-defined] except KeyError: pass # Was already deleted, so we have the desired state. else: - dictionary[key] = value + # Not all Mapping types support indexing, but MutableMapping doesn't support TypedDict + dictionary[key] = value # type: ignore[index] self._setitem[:] = [] if self._savesyspath is not None: sys.path[:] = self._savesyspath diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/src/_pytest/tmpdir.py new/pytest-7.3.2/src/_pytest/tmpdir.py --- old/pytest-7.3.1/src/_pytest/tmpdir.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/src/_pytest/tmpdir.py 2023-06-10 21:28:00.000000000 +0200 @@ -100,7 +100,7 @@ policy = config.getini("tmp_path_retention_policy") if policy not in ("all", "failed", "none"): raise ValueError( - f"tmp_path_retention_policy must be either all, failed, none. Current intput: {policy}." + f"tmp_path_retention_policy must be either all, failed, none. Current input: {policy}." ) return cls( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/src/_pytest/warning_types.py new/pytest-7.3.2/src/_pytest/warning_types.py --- old/pytest-7.3.1/src/_pytest/warning_types.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/src/_pytest/warning_types.py 2023-06-10 21:28:00.000000000 +0200 @@ -149,7 +149,7 @@ """ Issue the warning :param:`message` for the definition of the given :param:`method` - this helps to log warnigns for functions defined prior to finding an issue with them + this helps to log warnings for functions defined prior to finding an issue with them (like hook wrappers being marked in a legacy mechanism) """ lineno = method.__code__.co_firstlineno diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/src/pytest.egg-info/PKG-INFO new/pytest-7.3.2/src/pytest.egg-info/PKG-INFO --- old/pytest-7.3.1/src/pytest.egg-info/PKG-INFO 2023-04-14 20:11:06.000000000 +0200 +++ new/pytest-7.3.2/src/pytest.egg-info/PKG-INFO 2023-06-10 21:28:30.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pytest -Version: 7.3.1 +Version: 7.3.2 Summary: pytest: simple powerful testing with Python Home-page: https://docs.pytest.org/en/latest/ Author: Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin and others @@ -28,6 +28,7 @@ Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 Classifier: Topic :: Software Development :: Libraries Classifier: Topic :: Software Development :: Testing Classifier: Topic :: Utilities diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/src/pytest.egg-info/SOURCES.txt new/pytest-7.3.2/src/pytest.egg-info/SOURCES.txt --- old/pytest-7.3.1/src/pytest.egg-info/SOURCES.txt 2023-04-14 20:11:06.000000000 +0200 +++ new/pytest-7.3.2/src/pytest.egg-info/SOURCES.txt 2023-06-10 21:28:30.000000000 +0200 @@ -229,6 +229,7 @@ doc/en/announce/release-7.2.2.rst doc/en/announce/release-7.3.0.rst doc/en/announce/release-7.3.1.rst +doc/en/announce/release-7.3.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-7.3.1/src/pytest.egg-info/requires.txt new/pytest-7.3.2/src/pytest.egg-info/requires.txt --- old/pytest-7.3.1/src/pytest.egg-info/requires.txt 2023-04-14 20:11:06.000000000 +0200 +++ new/pytest-7.3.2/src/pytest.egg-info/requires.txt 2023-06-10 21:28:30.000000000 +0200 @@ -20,4 +20,5 @@ nose pygments>=2.7.2 requests +setuptools xmlschema diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/testing/acceptance_test.py new/pytest-7.3.2/testing/acceptance_test.py --- old/pytest-7.3.1/testing/acceptance_test.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/testing/acceptance_test.py 2023-06-10 21:28:00.000000000 +0200 @@ -695,11 +695,15 @@ monkeypatch.chdir("world") # pgk_resources.declare_namespace has been deprecated in favor of implicit namespace packages. + # pgk_resources has been deprecated entirely. # While we could change the test to use implicit namespace packages, seems better # to still ensure the old declaration via declare_namespace still works. - ignore_w = r"-Wignore:Deprecated call to `pkg_resources.declare_namespace" + ignore_w = ( + r"-Wignore:Deprecated call to `pkg_resources.declare_namespace", + r"-Wignore:pkg_resources is deprecated", + ) result = pytester.runpytest( - "--pyargs", "-v", "ns_pkg.hello", "ns_pkg/world", ignore_w + "--pyargs", "-v", "ns_pkg.hello", "ns_pkg/world", *ignore_w ) assert result.ret == 0 result.stdout.fnmatch_lines( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/testing/python/collect.py new/pytest-7.3.2/testing/python/collect.py --- old/pytest-7.3.1/testing/python/collect.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/testing/python/collect.py 2023-06-10 21:28:00.000000000 +0200 @@ -897,25 +897,29 @@ def test_issue2369_collect_module_fileext(self, pytester: Pytester) -> None: """Ensure we can collect files with weird file extensions as Python modules (#2369)""" - # We'll implement a little finder and loader to import files containing + # Implement a little meta path finder to import files containing # Python source code whose file extension is ".narf". pytester.makeconftest( """ - import sys, os, imp + import sys + import os.path + from importlib.util import spec_from_loader + from importlib.machinery import SourceFileLoader from _pytest.python import Module - class Loader(object): - def load_module(self, name): - return imp.load_source(name, name + ".narf") - class Finder(object): - def find_module(self, name, path=None): - if os.path.exists(name + ".narf"): - return Loader() - sys.meta_path.append(Finder()) + class MetaPathFinder: + def find_spec(self, fullname, path, target=None): + if os.path.exists(fullname + ".narf"): + return spec_from_loader( + fullname, + SourceFileLoader(fullname, fullname + ".narf"), + ) + sys.meta_path.append(MetaPathFinder()) def pytest_collect_file(file_path, parent): if file_path.suffix == ".narf": - return Module.from_parent(path=file_path, parent=parent)""" + return Module.from_parent(path=file_path, parent=parent) + """ ) pytester.makefile( ".narf", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/testing/test_assertrewrite.py new/pytest-7.3.2/testing/test_assertrewrite.py --- old/pytest-7.3.1/testing/test_assertrewrite.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/testing/test_assertrewrite.py 2023-06-10 21:28:01.000000000 +0200 @@ -1437,6 +1437,96 @@ @pytest.mark.skipif( + sys.version_info < (3, 8), reason="walrus operator not available in py<38" +) +class TestIssue11028: + def test_assertion_walrus_operator_in_operand(self, pytester: Pytester) -> None: + pytester.makepyfile( + """ + def test_in_string(): + assert (obj := "foo") in obj + """ + ) + result = pytester.runpytest() + assert result.ret == 0 + + def test_assertion_walrus_operator_in_operand_json_dumps( + self, pytester: Pytester + ) -> None: + pytester.makepyfile( + """ + import json + + def test_json_encoder(): + assert (obj := "foo") in json.dumps(obj) + """ + ) + result = pytester.runpytest() + assert result.ret == 0 + + def test_assertion_walrus_operator_equals_operand_function( + self, pytester: Pytester + ) -> None: + pytester.makepyfile( + """ + def f(a): + return a + + def test_call_other_function_arg(): + assert (obj := "foo") == f(obj) + """ + ) + result = pytester.runpytest() + assert result.ret == 0 + + def test_assertion_walrus_operator_equals_operand_function_keyword_arg( + self, pytester: Pytester + ) -> None: + pytester.makepyfile( + """ + def f(a='test'): + return a + + def test_call_other_function_k_arg(): + assert (obj := "foo") == f(a=obj) + """ + ) + result = pytester.runpytest() + assert result.ret == 0 + + def test_assertion_walrus_operator_equals_operand_function_arg_as_function( + self, pytester: Pytester + ) -> None: + pytester.makepyfile( + """ + def f(a='test'): + return a + + def test_function_of_function(): + assert (obj := "foo") == f(f(obj)) + """ + ) + result = pytester.runpytest() + assert result.ret == 0 + + def test_assertion_walrus_operator_gt_operand_function( + self, pytester: Pytester + ) -> None: + pytester.makepyfile( + """ + def add_one(a): + return a + 1 + + def test_gt(): + assert (obj := 4) > add_one(obj) + """ + ) + result = pytester.runpytest() + assert result.ret == 1 + result.stdout.fnmatch_lines(["*assert 4 > 5", "*where 5 = add_one(4)"]) + + +@pytest.mark.skipif( sys.maxsize <= (2**31 - 1), reason="Causes OverflowError on 32bit systems" ) @pytest.mark.parametrize("offset", [-1, +1]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/testing/test_cacheprovider.py new/pytest-7.3.2/testing/test_cacheprovider.py --- old/pytest-7.3.1/testing/test_cacheprovider.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/testing/test_cacheprovider.py 2023-06-10 21:28:01.000000000 +0200 @@ -420,7 +420,13 @@ result = pytester.runpytest() result.stdout.fnmatch_lines(["*1 failed in*"]) - def test_terminal_report_lastfailed(self, pytester: Pytester) -> None: + @pytest.mark.parametrize("parent", ("session", "package")) + def test_terminal_report_lastfailed(self, pytester: Pytester, parent: str) -> None: + if parent == "package": + pytester.makepyfile( + __init__="", + ) + test_a = pytester.makepyfile( test_a=""" def test_a1(): pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/testing/test_collection.py new/pytest-7.3.2/testing/test_collection.py --- old/pytest-7.3.1/testing/test_collection.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/testing/test_collection.py 2023-06-10 21:28:01.000000000 +0200 @@ -1247,6 +1247,48 @@ result.stdout.fnmatch_lines(["*1 passed in*"]) +def test_initial_conftests_with_testpaths(pytester: Pytester) -> None: + """The testpaths ini option should load conftests in those paths as 'initial' (#10987).""" + p = pytester.mkdir("some_path") + p.joinpath("conftest.py").write_text( + textwrap.dedent( + """ + def pytest_sessionstart(session): + raise Exception("pytest_sessionstart hook successfully run") + """ + ) + ) + pytester.makeini( + """ + [pytest] + testpaths = some_path + """ + ) + result = pytester.runpytest() + result.stdout.fnmatch_lines( + "INTERNALERROR* Exception: pytest_sessionstart hook successfully run" + ) + + +def test_large_option_breaks_initial_conftests(pytester: Pytester) -> None: + """Long option values do not break initial conftests handling (#10169).""" + option_value = "x" * 1024 * 1000 + pytester.makeconftest( + """ + def pytest_addoption(parser): + parser.addoption("--xx", default=None) + """ + ) + pytester.makepyfile( + f""" + def test_foo(request): + assert request.config.getoption("xx") == {option_value!r} + """ + ) + result = pytester.runpytest(f"--xx={option_value}") + assert result.ret == 0 + + def test_collect_symlink_file_arg(pytester: Pytester) -> None: """Collect a direct symlink works even if it does not match python_files (#4325).""" real = pytester.makepyfile( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/testing/test_conftest.py new/pytest-7.3.2/testing/test_conftest.py --- old/pytest-7.3.1/testing/test_conftest.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/testing/test_conftest.py 2023-06-10 21:28:01.000000000 +0200 @@ -35,7 +35,7 @@ self.importmode = "prepend" namespace = cast(argparse.Namespace, Namespace()) - conftest._set_initial_conftests(namespace, rootpath=Path(args[0])) + conftest._set_initial_conftests(namespace, rootpath=Path(args[0]), testpaths_ini=[]) @pytest.mark.usefixtures("_sys_snapshot") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/testing/test_monkeypatch.py new/pytest-7.3.2/testing/test_monkeypatch.py --- old/pytest-7.3.1/testing/test_monkeypatch.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/testing/test_monkeypatch.py 2023-06-10 21:28:01.000000000 +0200 @@ -425,9 +425,7 @@ assert A.x == 1 -@pytest.mark.filterwarnings( - "ignore:Deprecated call to `pkg_resources.declare_namespace" -) +@pytest.mark.filterwarnings(r"ignore:.*\bpkg_resources\b:DeprecationWarning") def test_syspath_prepend_with_namespace_packages( pytester: Pytester, monkeypatch: MonkeyPatch ) -> None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/testing/test_python_path.py new/pytest-7.3.2/testing/test_python_path.py --- old/pytest-7.3.1/testing/test_python_path.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/testing/test_python_path.py 2023-06-10 21:28:01.000000000 +0200 @@ -82,7 +82,7 @@ def test_clean_up(pytester: Pytester) -> None: """Test that the plugin cleans up after itself.""" - # This is tough to test behaviorly because the cleanup really runs last. + # This is tough to test behaviorally because the cleanup really runs last. # So the test make several implementation assumptions: # - Cleanup is done in pytest_unconfigure(). # - Not a hookwrapper. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-7.3.1/testing/typing_checks.py new/pytest-7.3.2/testing/typing_checks.py --- old/pytest-7.3.1/testing/typing_checks.py 2023-04-14 20:10:43.000000000 +0200 +++ new/pytest-7.3.2/testing/typing_checks.py 2023-06-10 21:28:01.000000000 +0200 @@ -9,6 +9,7 @@ from typing_extensions import assert_type import pytest +from pytest import MonkeyPatch # Issue #7488. @@ -29,6 +30,19 @@ pass +# Issue #10999. +def check_monkeypatch_typeddict(monkeypatch: MonkeyPatch) -> None: + from typing import TypedDict + + class Foo(TypedDict): + x: int + y: float + + a: Foo = {"x": 1, "y": 3.14} + monkeypatch.setitem(a, "x", 2) + monkeypatch.delitem(a, "y") + + def check_raises_is_a_context_manager(val: bool) -> None: with pytest.raises(RuntimeError) if val else contextlib.nullcontext() as excinfo: pass