Skip to content

Commit e22c188

Browse files
authored
Merge pull request #12746 from pytest-dev/patchback/backports/8.3.x/c947145fbb4aeec810a259b19f70fcb52fd53ad4/pr-12744
[PR #12744/c947145f backport][8.3.x] Replaced `typing.Self` with `typing_extensions.Self`
2 parents 6d59143 + 6af50c0 commit e22c188

30 files changed

+76
-80
lines changed

.pre-commit-config.yaml

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/astral-sh/ruff-pre-commit
3-
rev: "v0.5.2"
3+
rev: "v0.6.2"
44
hooks:
55
- id: ruff
66
args: ["--fix"]
@@ -21,7 +21,7 @@ repos:
2121
hooks:
2222
- id: python-use-type-annotations
2323
- repo: https://github.com/pre-commit/mirrors-mypy
24-
rev: v1.10.1
24+
rev: v1.11.2
2525
hooks:
2626
- id: mypy
2727
files: ^(src/|testing/|scripts/)
@@ -32,19 +32,19 @@ repos:
3232
- pluggy>=1.5.0
3333
- packaging
3434
- tomli
35-
- types-pkg_resources
35+
- types-setuptools
3636
- types-tabulate
3737
# for mypy running on python>=3.11 since exceptiongroup is only a dependency
3838
# on <3.11
3939
- exceptiongroup>=1.0.0rc8
4040
- repo: https://github.com/tox-dev/pyproject-fmt
41-
rev: "2.1.4"
41+
rev: "2.2.1"
4242
hooks:
4343
- id: pyproject-fmt
4444
# https://pyproject-fmt.readthedocs.io/en/latest/#calculating-max-supported-python-version
4545
additional_dependencies: ["tox>=4.9"]
4646
- repo: https://github.com/asottile/pyupgrade
47-
rev: v3.16.0
47+
rev: v3.17.0
4848
hooks:
4949
- id: pyupgrade
5050
stages: [manual]

changelog/12744.bugfix.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed typing compatibility with Python 3.9 or less -- replaced `typing.Self` with `typing_extensions.Self` -- by :user:`Avasam`

doc/en/broken-dep-constraints.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33

44
# Pin towncrier temporarily due to incompatibility with sphinxcontrib-towncrier:
55
# https://github.com/sphinx-contrib/sphinxcontrib-towncrier/issues/92
6-
towncrier!=24.7.0,!=24.7.1
6+
towncrier<24.7

src/_pytest/_io/pprint.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,15 @@ def _format(
111111
p(self, object, stream, indent, allowance, context, level + 1)
112112
context.remove(objid)
113113
elif (
114-
_dataclasses.is_dataclass(object)
114+
_dataclasses.is_dataclass(object) # type:ignore[unreachable]
115115
and not isinstance(object, type)
116116
and object.__dataclass_params__.repr
117117
and
118118
# Check dataclass has generated repr method.
119119
hasattr(object.__repr__, "__wrapped__")
120120
and "__create_fn__" in object.__repr__.__wrapped__.__qualname__
121121
):
122-
context.add(objid)
122+
context.add(objid) # type:ignore[unreachable]
123123
self._pprint_dataclass(
124124
object, stream, indent, allowance, context, level + 1
125125
)

src/_pytest/cacheprovider.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ def pytest_collectreport(self, report: CollectReport) -> None:
369369
@hookimpl(wrapper=True, tryfirst=True)
370370
def pytest_collection_modifyitems(
371371
self, config: Config, items: list[nodes.Item]
372-
) -> Generator[None, None, None]:
372+
) -> Generator[None]:
373373
res = yield
374374

375375
if not self.active:
@@ -439,9 +439,7 @@ def __init__(self, config: Config) -> None:
439439
self.cached_nodeids = set(config.cache.get("cache/nodeids", []))
440440

441441
@hookimpl(wrapper=True, tryfirst=True)
442-
def pytest_collection_modifyitems(
443-
self, items: list[nodes.Item]
444-
) -> Generator[None, None, None]:
442+
def pytest_collection_modifyitems(self, items: list[nodes.Item]) -> Generator[None]:
445443
res = yield
446444

447445
if self.active:

src/_pytest/capture.py

+12-11
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def _reopen_stdio(f, mode):
135135

136136

137137
@hookimpl(wrapper=True)
138-
def pytest_load_initial_conftests(early_config: Config) -> Generator[None, None, None]:
138+
def pytest_load_initial_conftests(early_config: Config) -> Generator[None]:
139139
ns = early_config.known_args_namespace
140140
if ns.capture == "fd":
141141
_windowsconsoleio_workaround(sys.stdout)
@@ -202,6 +202,7 @@ def write(self, s: str) -> int:
202202
class DontReadFromInput(TextIO):
203203
@property
204204
def encoding(self) -> str:
205+
assert sys.__stdin__ is not None
205206
return sys.__stdin__.encoding
206207

207208
def read(self, size: int = -1) -> str:
@@ -817,7 +818,7 @@ def resume_fixture(self) -> None:
817818
# Helper context managers
818819

819820
@contextlib.contextmanager
820-
def global_and_fixture_disabled(self) -> Generator[None, None, None]:
821+
def global_and_fixture_disabled(self) -> Generator[None]:
821822
"""Context manager to temporarily disable global and current fixture capturing."""
822823
do_fixture = self._capture_fixture and self._capture_fixture._is_started()
823824
if do_fixture:
@@ -834,7 +835,7 @@ def global_and_fixture_disabled(self) -> Generator[None, None, None]:
834835
self.resume_fixture()
835836

836837
@contextlib.contextmanager
837-
def item_capture(self, when: str, item: Item) -> Generator[None, None, None]:
838+
def item_capture(self, when: str, item: Item) -> Generator[None]:
838839
self.resume_global_capture()
839840
self.activate_fixture()
840841
try:
@@ -869,17 +870,17 @@ def pytest_make_collect_report(
869870
return rep
870871

871872
@hookimpl(wrapper=True)
872-
def pytest_runtest_setup(self, item: Item) -> Generator[None, None, None]:
873+
def pytest_runtest_setup(self, item: Item) -> Generator[None]:
873874
with self.item_capture("setup", item):
874875
return (yield)
875876

876877
@hookimpl(wrapper=True)
877-
def pytest_runtest_call(self, item: Item) -> Generator[None, None, None]:
878+
def pytest_runtest_call(self, item: Item) -> Generator[None]:
878879
with self.item_capture("call", item):
879880
return (yield)
880881

881882
@hookimpl(wrapper=True)
882-
def pytest_runtest_teardown(self, item: Item) -> Generator[None, None, None]:
883+
def pytest_runtest_teardown(self, item: Item) -> Generator[None]:
883884
with self.item_capture("teardown", item):
884885
return (yield)
885886

@@ -961,7 +962,7 @@ def _is_started(self) -> bool:
961962
return False
962963

963964
@contextlib.contextmanager
964-
def disabled(self) -> Generator[None, None, None]:
965+
def disabled(self) -> Generator[None]:
965966
"""Temporarily disable capturing while inside the ``with`` block."""
966967
capmanager: CaptureManager = self.request.config.pluginmanager.getplugin(
967968
"capturemanager"
@@ -974,7 +975,7 @@ def disabled(self) -> Generator[None, None, None]:
974975

975976

976977
@fixture
977-
def capsys(request: SubRequest) -> Generator[CaptureFixture[str], None, None]:
978+
def capsys(request: SubRequest) -> Generator[CaptureFixture[str]]:
978979
r"""Enable text capturing of writes to ``sys.stdout`` and ``sys.stderr``.
979980
980981
The captured output is made available via ``capsys.readouterr()`` method
@@ -1002,7 +1003,7 @@ def test_output(capsys):
10021003

10031004

10041005
@fixture
1005-
def capsysbinary(request: SubRequest) -> Generator[CaptureFixture[bytes], None, None]:
1006+
def capsysbinary(request: SubRequest) -> Generator[CaptureFixture[bytes]]:
10061007
r"""Enable bytes capturing of writes to ``sys.stdout`` and ``sys.stderr``.
10071008
10081009
The captured output is made available via ``capsysbinary.readouterr()``
@@ -1030,7 +1031,7 @@ def test_output(capsysbinary):
10301031

10311032

10321033
@fixture
1033-
def capfd(request: SubRequest) -> Generator[CaptureFixture[str], None, None]:
1034+
def capfd(request: SubRequest) -> Generator[CaptureFixture[str]]:
10341035
r"""Enable text capturing of writes to file descriptors ``1`` and ``2``.
10351036
10361037
The captured output is made available via ``capfd.readouterr()`` method
@@ -1058,7 +1059,7 @@ def test_system_echo(capfd):
10581059

10591060

10601061
@fixture
1061-
def capfdbinary(request: SubRequest) -> Generator[CaptureFixture[bytes], None, None]:
1062+
def capfdbinary(request: SubRequest) -> Generator[CaptureFixture[bytes]]:
10621063
r"""Enable bytes capturing of writes to file descriptors ``1`` and ``2``.
10631064
10641065
The captured output is made available via ``capfd.readouterr()`` method

src/_pytest/doctest.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@
4444

4545
if TYPE_CHECKING:
4646
import doctest
47-
from typing import Self
47+
48+
from typing_extensions import Self
4849

4950
DOCTEST_REPORT_CHOICE_NONE = "none"
5051
DOCTEST_REPORT_CHOICE_CDIFF = "cdiff"
@@ -467,7 +468,7 @@ def _is_mocked(obj: object) -> bool:
467468

468469

469470
@contextmanager
470-
def _patch_unwrap_mock_aware() -> Generator[None, None, None]:
471+
def _patch_unwrap_mock_aware() -> Generator[None]:
471472
"""Context manager which replaces ``inspect.unwrap`` with a version
472473
that's aware of mock objects and doesn't recurse into them."""
473474
real_unwrap = inspect.unwrap

src/_pytest/faulthandler.py

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ def get_stderr_fileno() -> int:
6464
# pytest-xdist monkeypatches sys.stderr with an object that is not an actual file.
6565
# https://docs.python.org/3/library/faulthandler.html#issue-with-file-descriptors
6666
# This is potentially dangerous, but the best we can do.
67+
assert sys.__stderr__ is not None
6768
return sys.__stderr__.fileno()
6869

6970

src/_pytest/logging.py

+10-12
Original file line numberDiff line numberDiff line change
@@ -554,9 +554,7 @@ def set_level(self, level: int | str, logger: str | None = None) -> None:
554554
self._initial_disabled_logging_level = initial_disabled_logging_level
555555

556556
@contextmanager
557-
def at_level(
558-
self, level: int | str, logger: str | None = None
559-
) -> Generator[None, None, None]:
557+
def at_level(self, level: int | str, logger: str | None = None) -> Generator[None]:
560558
"""Context manager that sets the level for capturing of logs. After
561559
the end of the 'with' statement the level is restored to its original
562560
value.
@@ -580,7 +578,7 @@ def at_level(
580578
logging.disable(original_disable_level)
581579

582580
@contextmanager
583-
def filtering(self, filter_: logging.Filter) -> Generator[None, None, None]:
581+
def filtering(self, filter_: logging.Filter) -> Generator[None]:
584582
"""Context manager that temporarily adds the given filter to the caplog's
585583
:meth:`handler` for the 'with' statement block, and removes that filter at the
586584
end of the block.
@@ -597,7 +595,7 @@ def filtering(self, filter_: logging.Filter) -> Generator[None, None, None]:
597595

598596

599597
@fixture
600-
def caplog(request: FixtureRequest) -> Generator[LogCaptureFixture, None, None]:
598+
def caplog(request: FixtureRequest) -> Generator[LogCaptureFixture]:
601599
"""Access and control log capturing.
602600
603601
Captured logs are available through the following properties/methods::
@@ -776,15 +774,15 @@ def _log_cli_enabled(self) -> bool:
776774
return True
777775

778776
@hookimpl(wrapper=True, tryfirst=True)
779-
def pytest_sessionstart(self) -> Generator[None, None, None]:
777+
def pytest_sessionstart(self) -> Generator[None]:
780778
self.log_cli_handler.set_when("sessionstart")
781779

782780
with catching_logs(self.log_cli_handler, level=self.log_cli_level):
783781
with catching_logs(self.log_file_handler, level=self.log_file_level):
784782
return (yield)
785783

786784
@hookimpl(wrapper=True, tryfirst=True)
787-
def pytest_collection(self) -> Generator[None, None, None]:
785+
def pytest_collection(self) -> Generator[None]:
788786
self.log_cli_handler.set_when("collection")
789787

790788
with catching_logs(self.log_cli_handler, level=self.log_cli_level):
@@ -813,7 +811,7 @@ def pytest_runtest_logstart(self) -> None:
813811
def pytest_runtest_logreport(self) -> None:
814812
self.log_cli_handler.set_when("logreport")
815813

816-
def _runtest_for(self, item: nodes.Item, when: str) -> Generator[None, None, None]:
814+
def _runtest_for(self, item: nodes.Item, when: str) -> Generator[None]:
817815
"""Implement the internals of the pytest_runtest_xxx() hooks."""
818816
with catching_logs(
819817
self.caplog_handler,
@@ -834,21 +832,21 @@ def _runtest_for(self, item: nodes.Item, when: str) -> Generator[None, None, Non
834832
item.add_report_section(when, "log", log)
835833

836834
@hookimpl(wrapper=True)
837-
def pytest_runtest_setup(self, item: nodes.Item) -> Generator[None, None, None]:
835+
def pytest_runtest_setup(self, item: nodes.Item) -> Generator[None]:
838836
self.log_cli_handler.set_when("setup")
839837

840838
empty: dict[str, list[logging.LogRecord]] = {}
841839
item.stash[caplog_records_key] = empty
842840
yield from self._runtest_for(item, "setup")
843841

844842
@hookimpl(wrapper=True)
845-
def pytest_runtest_call(self, item: nodes.Item) -> Generator[None, None, None]:
843+
def pytest_runtest_call(self, item: nodes.Item) -> Generator[None]:
846844
self.log_cli_handler.set_when("call")
847845

848846
yield from self._runtest_for(item, "call")
849847

850848
@hookimpl(wrapper=True)
851-
def pytest_runtest_teardown(self, item: nodes.Item) -> Generator[None, None, None]:
849+
def pytest_runtest_teardown(self, item: nodes.Item) -> Generator[None]:
852850
self.log_cli_handler.set_when("teardown")
853851

854852
try:
@@ -862,7 +860,7 @@ def pytest_runtest_logfinish(self) -> None:
862860
self.log_cli_handler.set_when("finish")
863861

864862
@hookimpl(wrapper=True, tryfirst=True)
865-
def pytest_sessionfinish(self) -> Generator[None, None, None]:
863+
def pytest_sessionfinish(self) -> Generator[None]:
866864
self.log_cli_handler.set_when("sessionfinish")
867865

868866
with catching_logs(self.log_cli_handler, level=self.log_cli_level):

src/_pytest/monkeypatch.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929

3030
@fixture
31-
def monkeypatch() -> Generator[MonkeyPatch, None, None]:
31+
def monkeypatch() -> Generator[MonkeyPatch]:
3232
"""A convenient fixture for monkey-patching.
3333
3434
The fixture provides these methods to modify objects, dictionaries, or
@@ -135,7 +135,7 @@ def __init__(self) -> None:
135135

136136
@classmethod
137137
@contextmanager
138-
def context(cls) -> Generator[MonkeyPatch, None, None]:
138+
def context(cls) -> Generator[MonkeyPatch]:
139139
"""Context manager that returns a new :class:`MonkeyPatch` object
140140
which undoes any patching done inside the ``with`` block upon exit.
141141

src/_pytest/nodes.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343

4444

4545
if TYPE_CHECKING:
46-
from typing import Self
46+
from typing_extensions import Self
4747

4848
# Imported here due to circular import.
4949
from _pytest.main import Session

src/_pytest/pytester.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ def pytester(
491491

492492

493493
@fixture
494-
def _sys_snapshot() -> Generator[None, None, None]:
494+
def _sys_snapshot() -> Generator[None]:
495495
snappaths = SysPathsSnapshot()
496496
snapmods = SysModulesSnapshot()
497497
yield
@@ -500,7 +500,7 @@ def _sys_snapshot() -> Generator[None, None, None]:
500500

501501

502502
@fixture
503-
def _config_for_test() -> Generator[Config, None, None]:
503+
def _config_for_test() -> Generator[Config]:
504504
from _pytest.config import get_config
505505

506506
config = get_config()

src/_pytest/python.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878

7979

8080
if TYPE_CHECKING:
81-
from typing import Self
81+
from typing_extensions import Self
8282

8383

8484
def pytest_addoption(parser: Parser) -> None:
@@ -568,7 +568,7 @@ def _register_setup_module_fixture(self) -> None:
568568
if setup_module is None and teardown_module is None:
569569
return
570570

571-
def xunit_setup_module_fixture(request) -> Generator[None, None, None]:
571+
def xunit_setup_module_fixture(request) -> Generator[None]:
572572
module = request.module
573573
if setup_module is not None:
574574
_call_with_optional_argument(setup_module, module)
@@ -599,7 +599,7 @@ def _register_setup_function_fixture(self) -> None:
599599
if setup_function is None and teardown_function is None:
600600
return
601601

602-
def xunit_setup_function_fixture(request) -> Generator[None, None, None]:
602+
def xunit_setup_function_fixture(request) -> Generator[None]:
603603
if request.instance is not None:
604604
# in this case we are bound to an instance, so we need to let
605605
# setup_method handle this
@@ -780,7 +780,7 @@ def _register_setup_class_fixture(self) -> None:
780780
if setup_class is None and teardown_class is None:
781781
return
782782

783-
def xunit_setup_class_fixture(request) -> Generator[None, None, None]:
783+
def xunit_setup_class_fixture(request) -> Generator[None]:
784784
cls = request.cls
785785
if setup_class is not None:
786786
func = getimfunc(setup_class)
@@ -813,7 +813,7 @@ def _register_setup_method_fixture(self) -> None:
813813
if setup_method is None and teardown_method is None:
814814
return
815815

816-
def xunit_setup_method_fixture(request) -> Generator[None, None, None]:
816+
def xunit_setup_method_fixture(request) -> Generator[None]:
817817
instance = request.instance
818818
method = request.function
819819
if setup_method is not None:

0 commit comments

Comments
 (0)