Skip to content

Commit 7a5f2fe

Browse files
authored
[7.4.x] Fixes for typed pluggy (#11355)
Since version 1.3 pluggy added typing, which requires some fixes to please mypy.
1 parent 6914071 commit 7a5f2fe

File tree

6 files changed

+25
-12
lines changed

6 files changed

+25
-12
lines changed

doc/en/reference/reference.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -978,10 +978,10 @@ TestShortLogReport
978978
.. autoclass:: pytest.TestShortLogReport()
979979
:members:
980980

981-
_Result
981+
Result
982982
~~~~~~~
983983

984-
Result object used within :ref:`hook wrappers <hookwrapper>`, see :py:class:`_Result in the pluggy documentation <pluggy._callers._Result>` for more information.
984+
Result object used within :ref:`hook wrappers <hookwrapper>`, see :py:class:`Result in the pluggy documentation <pluggy.Result>` for more information.
985985

986986
Stash
987987
~~~~~

src/_pytest/config/__init__.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -444,10 +444,10 @@ def parse_hookimpl_opts(self, plugin: _PluggyPlugin, name: str):
444444
# so we avoid accessing possibly non-readable attributes
445445
# (see issue #1073).
446446
if not name.startswith("pytest_"):
447-
return
447+
return None
448448
# Ignore names which can not be hooks.
449449
if name == "pytest_plugins":
450-
return
450+
return None
451451

452452
opts = super().parse_hookimpl_opts(plugin, name)
453453
if opts is not None:
@@ -456,9 +456,9 @@ def parse_hookimpl_opts(self, plugin: _PluggyPlugin, name: str):
456456
method = getattr(plugin, name)
457457
# Consider only actual functions for hooks (#3775).
458458
if not inspect.isroutine(method):
459-
return
459+
return None
460460
# Collect unmarked hooks as long as they have the `pytest_' prefix.
461-
return _get_legacy_hook_marks(
461+
return _get_legacy_hook_marks( # type: ignore[return-value]
462462
method, "impl", ("tryfirst", "trylast", "optionalhook", "hookwrapper")
463463
)
464464

@@ -467,7 +467,7 @@ def parse_hookspec_opts(self, module_or_class, name: str):
467467
if opts is None:
468468
method = getattr(module_or_class, name)
469469
if name.startswith("pytest_"):
470-
opts = _get_legacy_hook_marks(
470+
opts = _get_legacy_hook_marks( # type: ignore[assignment]
471471
method,
472472
"spec",
473473
("firstresult", "historic"),
@@ -1065,9 +1065,10 @@ def _ensure_unconfigure(self) -> None:
10651065
fin()
10661066

10671067
def get_terminal_writer(self) -> TerminalWriter:
1068-
terminalreporter: TerminalReporter = self.pluginmanager.get_plugin(
1068+
terminalreporter: Optional[TerminalReporter] = self.pluginmanager.get_plugin(
10691069
"terminalreporter"
10701070
)
1071+
assert terminalreporter is not None
10711072
return terminalreporter._tw
10721073

10731074
def pytest_cmdline_parse(

src/_pytest/helpconfig.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from _pytest.config import ExitCode
1212
from _pytest.config import PrintHelp
1313
from _pytest.config.argparsing import Parser
14+
from _pytest.terminal import TerminalReporter
1415

1516

1617
class HelpAction(Action):
@@ -159,7 +160,10 @@ def pytest_cmdline_main(config: Config) -> Optional[Union[int, ExitCode]]:
159160
def showhelp(config: Config) -> None:
160161
import textwrap
161162

162-
reporter = config.pluginmanager.get_plugin("terminalreporter")
163+
reporter: Optional[TerminalReporter] = config.pluginmanager.get_plugin(
164+
"terminalreporter"
165+
)
166+
assert reporter is not None
163167
tw = reporter._tw
164168
tw.write(config._parser.optparser.format_help())
165169
tw.line()

src/_pytest/logging.py

+2
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,8 @@ def __init__(self, config: Config) -> None:
660660
)
661661
if self._log_cli_enabled():
662662
terminal_reporter = config.pluginmanager.get_plugin("terminalreporter")
663+
# Guaranteed by `_log_cli_enabled()`.
664+
assert terminal_reporter is not None
663665
capture_manager = config.pluginmanager.get_plugin("capturemanager")
664666
# if capturemanager plugin is disabled, live logging still works.
665667
self.log_cli_handler: Union[

src/_pytest/pytester.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ def preserve_module(name):
752752

753753
def make_hook_recorder(self, pluginmanager: PytestPluginManager) -> HookRecorder:
754754
"""Create a new :class:`HookRecorder` for a :class:`PytestPluginManager`."""
755-
pluginmanager.reprec = reprec = HookRecorder(pluginmanager, _ispytest=True)
755+
pluginmanager.reprec = reprec = HookRecorder(pluginmanager, _ispytest=True) # type: ignore[attr-defined]
756756
self._request.addfinalizer(reprec.finish_recording)
757757
return reprec
758758

testing/test_pluginmanager.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,12 @@ def test_consider_module(
242242
mod = types.ModuleType("temp")
243243
mod.__dict__["pytest_plugins"] = ["pytest_p1", "pytest_p2"]
244244
pytestpm.consider_module(mod)
245-
assert pytestpm.get_plugin("pytest_p1").__name__ == "pytest_p1"
246-
assert pytestpm.get_plugin("pytest_p2").__name__ == "pytest_p2"
245+
p1 = pytestpm.get_plugin("pytest_p1")
246+
assert p1 is not None
247+
assert p1.__name__ == "pytest_p1"
248+
p2 = pytestpm.get_plugin("pytest_p2")
249+
assert p2 is not None
250+
assert p2.__name__ == "pytest_p2"
247251

248252
def test_consider_module_import_module(
249253
self, pytester: Pytester, _config_for_test: Config
@@ -336,6 +340,7 @@ def test_import_plugin_importname(
336340
len2 = len(pytestpm.get_plugins())
337341
assert len1 == len2
338342
plugin1 = pytestpm.get_plugin("pytest_hello")
343+
assert plugin1 is not None
339344
assert plugin1.__name__.endswith("pytest_hello")
340345
plugin2 = pytestpm.get_plugin("pytest_hello")
341346
assert plugin2 is plugin1
@@ -351,6 +356,7 @@ def test_import_plugin_dotted_name(
351356
pluginname = "pkg.plug"
352357
pytestpm.import_plugin(pluginname)
353358
mod = pytestpm.get_plugin("pkg.plug")
359+
assert mod is not None
354360
assert mod.x == 3
355361

356362
def test_consider_conftest_deps(

0 commit comments

Comments
 (0)