Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: pytest-dev/pytest
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 7.0.0
Choose a base ref
...
head repository: pytest-dev/pytest
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 7.0.1
Choose a head ref

Commits on Feb 4, 2022

  1. Prepare release 7.0.0 (#9598)

    * Prepare release version 7.0.0
    
    * Add note to changelog
    
    Co-authored-by: pytest bot <pytestbot@gmail.com>
    Co-authored-by: Florian Bruhin <me@the-compiler.org>
    3 people authored Feb 4, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    e37fbe5 View commit details
  2. [7.0.x] doc: Hide done training (#9605)

    Co-authored-by: Florian Bruhin <me@the-compiler.org>
    github-actions[bot] and The-Compiler authored Feb 4, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    5eb4d69 View commit details

Commits on Feb 8, 2022

  1. [7.0.x] work around test pollution caused by new setuptools mutating …

    …global logger level
    asottile authored and pytestbot committed Feb 8, 2022
    Copy the full SHA
    3c35477 View commit details
  2. Merge pull request #9648 from pytest-dev/backport-9638-to-7.0.x

    [7.0.x] work around test pollution caused by new setuptools mutating global logger level
    bluetech authored Feb 8, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    048a10b View commit details
  3. Copy the full SHA
    c588a47 View commit details
  4. Merge pull request #9647 from pytest-dev/backport-9609-to-7.0.x

    [7.0.x] importlib.readers not valid until python 3.10
    bluetech authored Feb 8, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    462a6f0 View commit details
  5. Copy the full SHA
    4bf8aff View commit details
  6. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    a24c78b View commit details

Commits on Feb 9, 2022

  1. Copy the full SHA
    453bcb1 View commit details
  2. Merge pull request #9653 from pytest-dev/backport-9651-to-7.0.x

    [7.0.x] Rename ``pythonpath`` plugin to ``python_path``
    bluetech authored Feb 9, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    ed8255c View commit details
  3. [7.0.x] unittest: restore UnitTestFunction.obj to return unbound ra…

    …ther than bound method (#9656)
    
    Co-authored-by: Ran Benita <ran@unusedvar.com>
    github-actions[bot] and bluetech authored Feb 9, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6684110 View commit details

Commits on Feb 10, 2022

  1. Copy the full SHA
    37d434f View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    0fae45b View commit details

Commits on Feb 11, 2022

  1. Copy the full SHA
    b5a154c View commit details
  2. Copy the full SHA
    e2753a2 View commit details
  3. Merge pull request #9672 from nicoddemus/backport-9669

    [7.0.x] Merge pull request #9669 from hugovk/ci-only-update-plugin-list-for-upstream
    nicoddemus authored Feb 11, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c891e40 View commit details
  4. Merge pull request #9671 from nicoddemus/backport-9668

    [7.0.x] Merge pull request #9668 from hugovk/test-me-latest-3.10
    nicoddemus authored Feb 11, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    ac37b1b View commit details
  5. Copy the full SHA
    6ca733e View commit details
  6. Merge pull request #9673 from nicoddemus/backport-9511

    [7.0.x] Enable testing with Python 3.11 (#9511)
    nicoddemus authored Feb 11, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    591d476 View commit details
  7. Copy the full SHA
    bc3021c View commit details
  8. Copy the full SHA
    3f12087 View commit details
14 changes: 12 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -37,6 +37,7 @@ jobs:
"windows-py38",
"windows-py39",
"windows-py310",
"windows-py311",

"ubuntu-py36",
"ubuntu-py37",
@@ -45,6 +46,7 @@ jobs:
"ubuntu-py38",
"ubuntu-py39",
"ubuntu-py310",
"ubuntu-py311",
"ubuntu-pypy3",

"macos-py37",
@@ -78,9 +80,13 @@ jobs:
os: windows-latest
tox_env: "py39-xdist"
- name: "windows-py310"
python: "3.10.1"
python: "3.10"
os: windows-latest
tox_env: "py310-xdist"
- name: "windows-py311"
python: "3.11-dev"
os: windows-latest
tox_env: "py311"

- name: "ubuntu-py36"
python: "3.6"
@@ -108,9 +114,13 @@ jobs:
os: ubuntu-latest
tox_env: "py39-xdist"
- name: "ubuntu-py310"
python: "3.10.1"
python: "3.10"
os: ubuntu-latest
tox_env: "py310-xdist"
- name: "ubuntu-py311"
python: "3.11-dev"
os: ubuntu-latest
tox_env: "py311"
- name: "ubuntu-pypy3"
python: "pypy-3.7"
os: ubuntu-latest
1 change: 1 addition & 0 deletions .github/workflows/update-plugin-list.yml
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ permissions: {}

jobs:
createPullRequest:
if: github.repository_owner == 'pytest-dev'
runs-on: ubuntu-latest
permissions:
contents: write
1 change: 0 additions & 1 deletion changelog/9355.bugfix.rst

This file was deleted.

1 change: 0 additions & 1 deletion changelog/9396.bugfix.rst

This file was deleted.

1 change: 0 additions & 1 deletion changelog/9404.doc.rst

This file was deleted.

7 changes: 0 additions & 7 deletions changelog/9488.deprecation.rst

This file was deleted.

2 changes: 0 additions & 2 deletions changelog/9505.doc.rst

This file was deleted.

1 change: 0 additions & 1 deletion changelog/9521.trivial.rst

This file was deleted.

2 changes: 2 additions & 0 deletions doc/en/announce/index.rst
Original file line number Diff line number Diff line change
@@ -6,6 +6,8 @@ Release announcements
:maxdepth: 2


release-7.0.1
release-7.0.0
release-7.0.0rc1
release-6.2.5
release-6.2.4
74 changes: 74 additions & 0 deletions doc/en/announce/release-7.0.0.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
pytest-7.0.0
=======================================

The pytest team is proud to announce the 7.0.0 release!

This release contains new features, improvements, bug fixes, and breaking changes, so users
are encouraged to take a look at the CHANGELOG carefully:

https://docs.pytest.org/en/stable/changelog.html

For complete documentation, please visit:

https://docs.pytest.org/en/stable/

As usual, you can upgrade from PyPI via:

pip install -U pytest

Thanks to all of the contributors to this release:

* Adam J. Stewart
* Alexander King
* Amin Alaee
* Andrew Neitsch
* Anthony Sottile
* Ben Davies
* Bernát Gábor
* Brian Okken
* Bruno Oliveira
* Cristian Vera
* Dan Alvizu
* David Szotten
* Eddie
* Emmanuel Arias
* Emmanuel Meric de Bellefon
* Eric Liu
* Florian Bruhin
* GergelyKalmar
* Graeme Smecher
* Harshna
* Hugo van Kemenade
* Jakub Kulík
* James Myatt
* Jeff Rasley
* Kale Kundert
* Kian Meng, Ang
* Miro Hrončok
* Naveen-Pratap
* Oleg Höfling
* Olga Matoula
* Ran Benita
* Ronny Pfannschmidt
* Simon K
* Srip
* Sören Wegener
* Taneli Hukkinen
* Terje Runde
* Thomas Grainger
* Thomas Hisch
* William Jamir Silva
* Yuval Shimon
* Zac Hatfield-Dodds
* andrewdotn
* denivyruck
* ericluoliu
* oleg.hoefling
* symonk
* ziebam
* Éloi Rivard
* Éric


Happy testing,
The pytest Development Team
20 changes: 20 additions & 0 deletions doc/en/announce/release-7.0.1.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
pytest-7.0.1
=======================================

pytest 7.0.1 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:

* Anthony Sottile
* Bruno Oliveira
* Ran Benita


Happy testing,
The pytest Development Team
4 changes: 2 additions & 2 deletions doc/en/builtin.rst
Original file line number Diff line number Diff line change
@@ -117,10 +117,10 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
`pytest-xdist <https://github.com/pytest-dev/pytest-xdist>`__ plugin. See
:issue:`7767` for details.
tmpdir_factory [session scope] -- .../_pytest/legacypath.py:292
tmpdir_factory [session scope] -- .../_pytest/legacypath.py:295
Return a :class:`pytest.TempdirFactory` instance for the test session.
tmpdir -- .../_pytest/legacypath.py:299
tmpdir -- .../_pytest/legacypath.py:302
Return a temporary directory path object which is unique to each test
function invocation, created as a sub directory of the base temporary
directory.
69 changes: 69 additions & 0 deletions doc/en/changelog.rst
Original file line number Diff line number Diff line change
@@ -28,6 +28,75 @@ with advance notice in the **Deprecations** section of releases.

.. towncrier release notes start
pytest 7.0.1 (2022-02-11)
=========================

Bug Fixes
---------

- `#9608 <https://github.com/pytest-dev/pytest/issues/9608>`_: Fix invalid importing of ``importlib.readers`` in Python 3.9.


- `#9610 <https://github.com/pytest-dev/pytest/issues/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 <https://github.com/pytest-dev/pytest/issues/9636>`_: The ``pythonpath`` plugin was renamed to ``python_path``. This avoids a conflict with the ``pytest-pythonpath`` plugin.


- `#9642 <https://github.com/pytest-dev/pytest/issues/9642>`_: Fix running tests by id with ``::`` in the parametrize portion.


- `#9643 <https://github.com/pytest-dev/pytest/issues/9643>`_: Delay issuing a :class:`~pytest.PytestWarning` about diamond inheritance involving :class:`~pytest.Item` and
:class:`~pytest.Collector` so it can be filtered using :ref:`standard warning filters <warnings>`.


pytest 7.0.0 (2022-02-03)
=========================

(**Please see the full set of changes for this release also in the 7.0.0rc1 notes below**)

Deprecations
------------

- `#9488 <https://github.com/pytest-dev/pytest/issues/9488>`_: If custom subclasses of nodes like :class:`pytest.Item` override the
``__init__`` method, they should take ``**kwargs``. See
:ref:`uncooperative-constructors-deprecated` 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.



Bug Fixes
---------

- `#9355 <https://github.com/pytest-dev/pytest/issues/9355>`_: Fixed error message prints function decorators when using assert in Python 3.8 and above.


- `#9396 <https://github.com/pytest-dev/pytest/issues/9396>`_: Ensure :attr:`pytest.Config.inifile` is available during the :func:`pytest_cmdline_main <_pytest.hookspec.pytest_cmdline_main>` hook (regression during ``7.0.0rc1``).



Improved Documentation
----------------------

- `#9404 <https://github.com/pytest-dev/pytest/issues/9404>`_: Added extra documentation on alternatives to common misuses of `pytest.warns(None)` ahead of its deprecation.


- `#9505 <https://github.com/pytest-dev/pytest/issues/9505>`_: Clarify where the configuration files are located. To avoid confusions documentation mentions
that configuration file is located in the root of the repository.



Trivial/Internal Changes
------------------------

- `#9521 <https://github.com/pytest-dev/pytest/issues/9521>`_: Add test coverage to assertion rewrite path.


pytest 7.0.0rc1 (2021-12-06)
============================

2 changes: 1 addition & 1 deletion doc/en/getting-started.rst
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ Install ``pytest``
.. code-block:: bash
$ pytest --version
pytest 7.0.0rc1
pytest 7.0.1
.. _`simpletest`:

7 changes: 4 additions & 3 deletions doc/en/index.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
:orphan:

.. sidebar:: Next Open Trainings
..
.. sidebar:: Next Open Trainings
- `Professional Testing with Python <https://www.python-academy.com/courses/specialtopics/python_course_testing.html>`_, via `Python Academy <https://www.python-academy.com/>`_, February 1st to 3rd, 2022, Leipzig (Germany) and remote.
- `Professional Testing with Python <https://www.python-academy.com/courses/specialtopics/python_course_testing.html>`_, via `Python Academy <https://www.python-academy.com/>`_, February 1st to 3rd, 2022, Leipzig (Germany) and remote.

Also see `previous talks and blogposts <talks.html>`_.
Also see `previous talks and blogposts <talks.html>`_.

.. _features:

10 changes: 6 additions & 4 deletions src/_pytest/assertion/rewrite.py
Original file line number Diff line number Diff line change
@@ -276,13 +276,15 @@ def get_data(self, pathname: Union[str, bytes]) -> bytes:
with open(pathname, "rb") as f:
return f.read()

if sys.version_info >= (3, 9):
if sys.version_info >= (3, 10):

def get_resource_reader(self, name: str) -> importlib.abc.TraversableResources: # type: ignore
from types import SimpleNamespace
from importlib.readers import FileReader
if sys.version_info < (3, 11):
from importlib.readers import FileReader
else:
from importlib.resources.readers import FileReader

return FileReader(SimpleNamespace(path=self._rewritten_names[name]))
return FileReader(types.SimpleNamespace(path=self._rewritten_names[name]))


def _write_pyc_fp(
2 changes: 1 addition & 1 deletion src/_pytest/config/__init__.py
Original file line number Diff line number Diff line change
@@ -255,7 +255,7 @@ def directory_arg(path: str, optname: str) -> str:
"warnings",
"logging",
"reports",
"pythonpath",
"python_path",
*(["unraisableexception", "threadexception"] if sys.version_info >= (3, 8) else []),
"faulthandler",
)
5 changes: 4 additions & 1 deletion src/_pytest/main.py
Original file line number Diff line number Diff line change
@@ -871,7 +871,10 @@ def resolve_collection_argument(
If the path doesn't exist, raise UsageError.
If the path is a directory and selection parts are present, raise UsageError.
"""
strpath, *parts = str(arg).split("::")
base, squacket, rest = str(arg).partition("[")
strpath, *parts = base.split("::")
if parts:
parts[-1] = f"{parts[-1]}{squacket}{rest}"
if as_pypath:
strpath = search_pypath(strpath)
fspath = invocation_path / strpath
45 changes: 31 additions & 14 deletions src/_pytest/nodes.py
Original file line number Diff line number Diff line change
@@ -656,20 +656,6 @@ class Item(Node):

nextitem = None

def __init_subclass__(cls) -> None:
problems = ", ".join(
base.__name__ for base in cls.__bases__ if issubclass(base, Collector)
)
if problems:
warnings.warn(
f"{cls.__name__} is an Item subclass and should not be a collector, "
f"however its bases {problems} are collectors.\n"
"Please split the Collectors and the Item into separate node types.\n"
"Pytest Doc example: https://docs.pytest.org/en/latest/example/nonpython.html\n"
"example pull request on a plugin: https://github.com/asmeurer/pytest-flakes/pull/40/",
PytestWarning,
)

def __init__(
self,
name,
@@ -697,6 +683,37 @@ def __init__(
#: for this test.
self.user_properties: List[Tuple[str, object]] = []

self._check_item_and_collector_diamond_inheritance()

def _check_item_and_collector_diamond_inheritance(self) -> None:
"""
Check if the current type inherits from both File and Collector
at the same time, emitting a warning accordingly (#8447).
"""
cls = type(self)

# We inject an attribute in the type to avoid issuing this warning
# for the same class more than once, which is not helpful.
# It is a hack, but was deemed acceptable in order to avoid
# flooding the user in the common case.
attr_name = "_pytest_diamond_inheritance_warning_shown"
if getattr(cls, attr_name, False):
return
setattr(cls, attr_name, True)

problems = ", ".join(
base.__name__ for base in cls.__bases__ if issubclass(base, Collector)
)
if problems:
warnings.warn(
f"{cls.__name__} is an Item subclass and should not be a collector, "
f"however its bases {problems} are collectors.\n"
"Please split the Collectors and the Item into separate node types.\n"
"Pytest Doc example: https://docs.pytest.org/en/latest/example/nonpython.html\n"
"example pull request on a plugin: https://github.com/asmeurer/pytest-flakes/pull/40/",
PytestWarning,
)

def runtest(self) -> None:
"""Run the test case for this item.
File renamed without changes.
9 changes: 9 additions & 0 deletions src/_pytest/unittest.py
Original file line number Diff line number Diff line change
@@ -185,6 +185,15 @@ class TestCaseFunction(Function):
_excinfo: Optional[List[_pytest._code.ExceptionInfo[BaseException]]] = None
_testcase: Optional["unittest.TestCase"] = None

def _getobj(self):
assert self.parent is not None
# Unlike a regular Function in a Class, where `item.obj` returns
# a *bound* method (attached to an instance), TestCaseFunction's
# `obj` returns an *unbound* method (not attached to an instance).
# This inconsistency is probably not desirable, but needs some
# consideration before changing.
return getattr(self.parent.obj, self.originalname) # type: ignore[attr-defined]

def setup(self) -> None:
# A bound method to be called during teardown() if set (see 'runtest()').
self._explicit_tearDown: Optional[Callable[[], None]] = None
14 changes: 10 additions & 4 deletions testing/test_assertion.py
Original file line number Diff line number Diff line change
@@ -1616,7 +1616,7 @@ def test_raise_assertion_error():
)


def test_raise_assertion_error_raisin_repr(pytester: Pytester) -> None:
def test_raise_assertion_error_raising_repr(pytester: Pytester) -> None:
pytester.makepyfile(
"""
class RaisingRepr(object):
@@ -1627,9 +1627,15 @@ def test_raising_repr():
"""
)
result = pytester.runpytest()
result.stdout.fnmatch_lines(
["E AssertionError: <unprintable AssertionError object>"]
)
if sys.version_info >= (3, 11):
# python 3.11 has native support for un-str-able exceptions
result.stdout.fnmatch_lines(
["E AssertionError: <exception str() failed>"]
)
else:
result.stdout.fnmatch_lines(
["E AssertionError: <unprintable AssertionError object>"]
)


def test_issue_1944(pytester: Pytester) -> None:
2 changes: 2 additions & 0 deletions testing/test_compat.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import enum
import sys
from functools import partial
from functools import wraps
from typing import TYPE_CHECKING
@@ -91,6 +92,7 @@ def foo(x):
assert get_real_func(partial(foo)) is foo


@pytest.mark.skipif(sys.version_info >= (3, 11), reason="couroutine removed")
def test_is_generator_asyncio(pytester: Pytester) -> None:
pytester.makepyfile(
"""
2 changes: 1 addition & 1 deletion testing/test_config.py
Original file line number Diff line number Diff line change
@@ -1275,7 +1275,7 @@ def pytest_load_initial_conftests(self):
("_pytest.config", "nonwrapper"),
(m.__module__, "nonwrapper"),
("_pytest.legacypath", "nonwrapper"),
("_pytest.pythonpath", "nonwrapper"),
("_pytest.python_path", "nonwrapper"),
("_pytest.capture", "wrapper"),
("_pytest.warnings", "wrapper"),
]
13 changes: 8 additions & 5 deletions testing/test_doctest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import inspect
import sys
import textwrap
from pathlib import Path
from typing import Callable
@@ -200,6 +201,7 @@ def test_doctest_unexpected_exception(self, pytester: Pytester):
"Traceback (most recent call last):",
' File "*/doctest.py", line *, in __run',
" *",
*((" *^^^^*",) if sys.version_info >= (3, 11) else ()),
' File "<doctest test_doctest_unexpected_exception.txt[1]>", line 1, in <module>',
"ZeroDivisionError: division by zero",
"*/test_doctest_unexpected_exception.txt:2: UnexpectedException",
@@ -802,11 +804,12 @@ def test_valid_setup_py(self, pytester: Pytester):
p = pytester.makepyfile(
setup="""
from setuptools import setup, find_packages
setup(name='sample',
version='0.0',
description='description',
packages=find_packages()
)
if __name__ == '__main__':
setup(name='sample',
version='0.0',
description='description',
packages=find_packages()
)
"""
)
result = pytester.runpytest(p, "--doctest-modules")
27 changes: 25 additions & 2 deletions testing/test_main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import argparse
import os
import re
import sys
from pathlib import Path
from typing import Optional

@@ -44,16 +45,32 @@ def pytest_internalerror(excrepr, excinfo):
assert result.ret == ExitCode.INTERNAL_ERROR
assert result.stdout.lines[0] == "INTERNALERROR> Traceback (most recent call last):"

end_lines = (
result.stdout.lines[-4:]
if sys.version_info >= (3, 11)
else result.stdout.lines[-3:]
)

if exc == SystemExit:
assert result.stdout.lines[-3:] == [
assert end_lines == [
f'INTERNALERROR> File "{c1}", line 4, in pytest_sessionstart',
'INTERNALERROR> raise SystemExit("boom")',
*(
("INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^",)
if sys.version_info >= (3, 11)
else ()
),
"INTERNALERROR> SystemExit: boom",
]
else:
assert result.stdout.lines[-3:] == [
assert end_lines == [
f'INTERNALERROR> File "{c1}", line 4, in pytest_sessionstart',
'INTERNALERROR> raise ValueError("boom")',
*(
("INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^",)
if sys.version_info >= (3, 11)
else ()
),
"INTERNALERROR> ValueError: boom",
]
if returncode is False:
@@ -171,6 +188,12 @@ def test_pypath(self, invocation_path: Path) -> None:
invocation_path, "pkg::foo::bar", as_pypath=True
)

def test_parametrized_name_with_colons(self, invocation_path: Path) -> None:
ret = resolve_collection_argument(
invocation_path, "src/pkg/test.py::test[a::b]"
)
assert ret == (invocation_path / "src/pkg/test.py", ["test[a::b]"])

def test_does_not_exist(self, invocation_path: Path) -> None:
"""Given a file/module that does not exist raises UsageError."""
with pytest.raises(
29 changes: 16 additions & 13 deletions testing/test_nodes.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import re
import warnings
from pathlib import Path
from typing import cast
from typing import List
@@ -58,30 +60,31 @@ def test_subclassing_both_item_and_collector_deprecated(
request, tmp_path: Path
) -> None:
"""
Verifies we warn on diamond inheritance
as well as correctly managing legacy inheritance ctors with missing args
as found in plugins
Verifies we warn on diamond inheritance as well as correctly managing legacy
inheritance constructors with missing args as found in plugins.
"""

with pytest.warns(
PytestWarning,
match=(
"(?m)SoWrong is an Item subclass and should not be a collector, however its bases File are collectors.\n"
"Please split the Collectors and the Item into separate node types.\n.*"
),
):
# We do not expect any warnings messages to issued during class definition.
with warnings.catch_warnings():
warnings.simplefilter("error")

class SoWrong(nodes.Item, nodes.File):
def __init__(self, fspath, parent):
"""Legacy ctor with legacy call # don't wana see"""
super().__init__(fspath, parent)

with pytest.warns(
PytestWarning, match=".*SoWrong.* not using a cooperative constructor.*"
):
with pytest.warns(PytestWarning) as rec:
SoWrong.from_parent(
request.session, fspath=legacy_path(tmp_path / "broken.txt")
)
messages = [str(x.message) for x in rec]
assert any(
re.search(".*SoWrong.* not using a cooperative constructor.*", x)
for x in messages
)
assert any(
re.search("(?m)SoWrong .* should not be a collector", x) for x in messages
)


@pytest.mark.parametrize(
4 changes: 2 additions & 2 deletions testing/test_pytester.py
Original file line number Diff line number Diff line change
@@ -743,8 +743,8 @@ def test_run_result_repr() -> None:

# known exit code
r = pytester_mod.RunResult(1, outlines, errlines, duration=0.5)
assert (
repr(r) == "<RunResult ret=ExitCode.TESTS_FAILED len(stdout.lines)=3"
assert repr(r) == (
f"<RunResult ret={str(pytest.ExitCode.TESTS_FAILED)} len(stdout.lines)=3"
" len(stderr.lines)=4 duration=0.50s>"
)

2 changes: 1 addition & 1 deletion testing/test_pythonpath.py → testing/test_python_path.py
Original file line number Diff line number Diff line change
@@ -81,7 +81,7 @@ def test_no_ini(pytester: Pytester, file_structure) -> None:


def test_clean_up(pytester: Pytester) -> None:
"""Test that the pythonpath plugin cleans up after itself."""
"""Test that the plugin cleans up after itself."""
# This is tough to test behaviorly because the cleanup really runs last.
# So the test make several implementation assumptions:
# - Cleanup is done in pytest_unconfigure().
26 changes: 26 additions & 0 deletions testing/test_unittest.py
Original file line number Diff line number Diff line change
@@ -1472,3 +1472,29 @@ def test_cleanup_called_the_right_number_of_times():
passed, skipped, failed = reprec.countoutcomes()
assert failed == 2
assert passed == 1


def test_traceback_pruning(pytester: Pytester) -> None:
"""Regression test for #9610 - doesn't crash during traceback pruning."""
pytester.makepyfile(
"""
import unittest
class MyTestCase(unittest.TestCase):
def __init__(self, test_method):
unittest.TestCase.__init__(self, test_method)
class TestIt(MyTestCase):
@classmethod
def tearDownClass(cls) -> None:
assert False
def test_it(self):
pass
"""
)
reprec = pytester.inline_run()
passed, skipped, failed = reprec.countoutcomes()
assert passed == 1
assert failed == 1
assert reprec.ret == 1
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ envlist =
py38
py39
py310
py311
pypy3
py37-{pexpect,xdist,unittestextras,numpy,pluggymain}
doctesting