[7.4.x] Fixes for typed pluggy (#11355)
Since version 1.3 pluggy added typing, which requires some fixes to please mypy.
This commit is contained in:
		
							parent
							
								
									69140717d4
								
							
						
					
					
						commit
						7a5f2feefb
					
				| 
						 | 
					@ -978,10 +978,10 @@ TestShortLogReport
 | 
				
			||||||
.. autoclass:: pytest.TestShortLogReport()
 | 
					.. autoclass:: pytest.TestShortLogReport()
 | 
				
			||||||
    :members:
 | 
					    :members:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_Result
 | 
					Result
 | 
				
			||||||
~~~~~~~
 | 
					~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Result object used within :ref:`hook wrappers <hookwrapper>`, see :py:class:`_Result in the pluggy documentation <pluggy._callers._Result>` for more information.
 | 
					Result object used within :ref:`hook wrappers <hookwrapper>`, see :py:class:`Result in the pluggy documentation <pluggy.Result>` for more information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Stash
 | 
					Stash
 | 
				
			||||||
~~~~~
 | 
					~~~~~
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -444,10 +444,10 @@ class PytestPluginManager(PluginManager):
 | 
				
			||||||
        # so we avoid accessing possibly non-readable attributes
 | 
					        # so we avoid accessing possibly non-readable attributes
 | 
				
			||||||
        # (see issue #1073).
 | 
					        # (see issue #1073).
 | 
				
			||||||
        if not name.startswith("pytest_"):
 | 
					        if not name.startswith("pytest_"):
 | 
				
			||||||
            return
 | 
					            return None
 | 
				
			||||||
        # Ignore names which can not be hooks.
 | 
					        # Ignore names which can not be hooks.
 | 
				
			||||||
        if name == "pytest_plugins":
 | 
					        if name == "pytest_plugins":
 | 
				
			||||||
            return
 | 
					            return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        opts = super().parse_hookimpl_opts(plugin, name)
 | 
					        opts = super().parse_hookimpl_opts(plugin, name)
 | 
				
			||||||
        if opts is not None:
 | 
					        if opts is not None:
 | 
				
			||||||
| 
						 | 
					@ -456,9 +456,9 @@ class PytestPluginManager(PluginManager):
 | 
				
			||||||
        method = getattr(plugin, name)
 | 
					        method = getattr(plugin, name)
 | 
				
			||||||
        # Consider only actual functions for hooks (#3775).
 | 
					        # Consider only actual functions for hooks (#3775).
 | 
				
			||||||
        if not inspect.isroutine(method):
 | 
					        if not inspect.isroutine(method):
 | 
				
			||||||
            return
 | 
					            return None
 | 
				
			||||||
        # Collect unmarked hooks as long as they have the `pytest_' prefix.
 | 
					        # Collect unmarked hooks as long as they have the `pytest_' prefix.
 | 
				
			||||||
        return _get_legacy_hook_marks(
 | 
					        return _get_legacy_hook_marks(  # type: ignore[return-value]
 | 
				
			||||||
            method, "impl", ("tryfirst", "trylast", "optionalhook", "hookwrapper")
 | 
					            method, "impl", ("tryfirst", "trylast", "optionalhook", "hookwrapper")
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -467,7 +467,7 @@ class PytestPluginManager(PluginManager):
 | 
				
			||||||
        if opts is None:
 | 
					        if opts is None:
 | 
				
			||||||
            method = getattr(module_or_class, name)
 | 
					            method = getattr(module_or_class, name)
 | 
				
			||||||
            if name.startswith("pytest_"):
 | 
					            if name.startswith("pytest_"):
 | 
				
			||||||
                opts = _get_legacy_hook_marks(
 | 
					                opts = _get_legacy_hook_marks(  # type: ignore[assignment]
 | 
				
			||||||
                    method,
 | 
					                    method,
 | 
				
			||||||
                    "spec",
 | 
					                    "spec",
 | 
				
			||||||
                    ("firstresult", "historic"),
 | 
					                    ("firstresult", "historic"),
 | 
				
			||||||
| 
						 | 
					@ -1065,9 +1065,10 @@ class Config:
 | 
				
			||||||
            fin()
 | 
					            fin()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_terminal_writer(self) -> TerminalWriter:
 | 
					    def get_terminal_writer(self) -> TerminalWriter:
 | 
				
			||||||
        terminalreporter: TerminalReporter = self.pluginmanager.get_plugin(
 | 
					        terminalreporter: Optional[TerminalReporter] = self.pluginmanager.get_plugin(
 | 
				
			||||||
            "terminalreporter"
 | 
					            "terminalreporter"
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					        assert terminalreporter is not None
 | 
				
			||||||
        return terminalreporter._tw
 | 
					        return terminalreporter._tw
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def pytest_cmdline_parse(
 | 
					    def pytest_cmdline_parse(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,7 @@ from _pytest.config import Config
 | 
				
			||||||
from _pytest.config import ExitCode
 | 
					from _pytest.config import ExitCode
 | 
				
			||||||
from _pytest.config import PrintHelp
 | 
					from _pytest.config import PrintHelp
 | 
				
			||||||
from _pytest.config.argparsing import Parser
 | 
					from _pytest.config.argparsing import Parser
 | 
				
			||||||
 | 
					from _pytest.terminal import TerminalReporter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HelpAction(Action):
 | 
					class HelpAction(Action):
 | 
				
			||||||
| 
						 | 
					@ -159,7 +160,10 @@ def pytest_cmdline_main(config: Config) -> Optional[Union[int, ExitCode]]:
 | 
				
			||||||
def showhelp(config: Config) -> None:
 | 
					def showhelp(config: Config) -> None:
 | 
				
			||||||
    import textwrap
 | 
					    import textwrap
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    reporter = config.pluginmanager.get_plugin("terminalreporter")
 | 
					    reporter: Optional[TerminalReporter] = config.pluginmanager.get_plugin(
 | 
				
			||||||
 | 
					        "terminalreporter"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    assert reporter is not None
 | 
				
			||||||
    tw = reporter._tw
 | 
					    tw = reporter._tw
 | 
				
			||||||
    tw.write(config._parser.optparser.format_help())
 | 
					    tw.write(config._parser.optparser.format_help())
 | 
				
			||||||
    tw.line()
 | 
					    tw.line()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -660,6 +660,8 @@ class LoggingPlugin:
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        if self._log_cli_enabled():
 | 
					        if self._log_cli_enabled():
 | 
				
			||||||
            terminal_reporter = config.pluginmanager.get_plugin("terminalreporter")
 | 
					            terminal_reporter = config.pluginmanager.get_plugin("terminalreporter")
 | 
				
			||||||
 | 
					            # Guaranteed by `_log_cli_enabled()`.
 | 
				
			||||||
 | 
					            assert terminal_reporter is not None
 | 
				
			||||||
            capture_manager = config.pluginmanager.get_plugin("capturemanager")
 | 
					            capture_manager = config.pluginmanager.get_plugin("capturemanager")
 | 
				
			||||||
            # if capturemanager plugin is disabled, live logging still works.
 | 
					            # if capturemanager plugin is disabled, live logging still works.
 | 
				
			||||||
            self.log_cli_handler: Union[
 | 
					            self.log_cli_handler: Union[
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -752,7 +752,7 @@ class Pytester:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def make_hook_recorder(self, pluginmanager: PytestPluginManager) -> HookRecorder:
 | 
					    def make_hook_recorder(self, pluginmanager: PytestPluginManager) -> HookRecorder:
 | 
				
			||||||
        """Create a new :class:`HookRecorder` for a :class:`PytestPluginManager`."""
 | 
					        """Create a new :class:`HookRecorder` for a :class:`PytestPluginManager`."""
 | 
				
			||||||
        pluginmanager.reprec = reprec = HookRecorder(pluginmanager, _ispytest=True)
 | 
					        pluginmanager.reprec = reprec = HookRecorder(pluginmanager, _ispytest=True)  # type: ignore[attr-defined]
 | 
				
			||||||
        self._request.addfinalizer(reprec.finish_recording)
 | 
					        self._request.addfinalizer(reprec.finish_recording)
 | 
				
			||||||
        return reprec
 | 
					        return reprec
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -242,8 +242,12 @@ class TestPytestPluginManager:
 | 
				
			||||||
        mod = types.ModuleType("temp")
 | 
					        mod = types.ModuleType("temp")
 | 
				
			||||||
        mod.__dict__["pytest_plugins"] = ["pytest_p1", "pytest_p2"]
 | 
					        mod.__dict__["pytest_plugins"] = ["pytest_p1", "pytest_p2"]
 | 
				
			||||||
        pytestpm.consider_module(mod)
 | 
					        pytestpm.consider_module(mod)
 | 
				
			||||||
        assert pytestpm.get_plugin("pytest_p1").__name__ == "pytest_p1"
 | 
					        p1 = pytestpm.get_plugin("pytest_p1")
 | 
				
			||||||
        assert pytestpm.get_plugin("pytest_p2").__name__ == "pytest_p2"
 | 
					        assert p1 is not None
 | 
				
			||||||
 | 
					        assert p1.__name__ == "pytest_p1"
 | 
				
			||||||
 | 
					        p2 = pytestpm.get_plugin("pytest_p2")
 | 
				
			||||||
 | 
					        assert p2 is not None
 | 
				
			||||||
 | 
					        assert p2.__name__ == "pytest_p2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_consider_module_import_module(
 | 
					    def test_consider_module_import_module(
 | 
				
			||||||
        self, pytester: Pytester, _config_for_test: Config
 | 
					        self, pytester: Pytester, _config_for_test: Config
 | 
				
			||||||
| 
						 | 
					@ -336,6 +340,7 @@ class TestPytestPluginManager:
 | 
				
			||||||
        len2 = len(pytestpm.get_plugins())
 | 
					        len2 = len(pytestpm.get_plugins())
 | 
				
			||||||
        assert len1 == len2
 | 
					        assert len1 == len2
 | 
				
			||||||
        plugin1 = pytestpm.get_plugin("pytest_hello")
 | 
					        plugin1 = pytestpm.get_plugin("pytest_hello")
 | 
				
			||||||
 | 
					        assert plugin1 is not None
 | 
				
			||||||
        assert plugin1.__name__.endswith("pytest_hello")
 | 
					        assert plugin1.__name__.endswith("pytest_hello")
 | 
				
			||||||
        plugin2 = pytestpm.get_plugin("pytest_hello")
 | 
					        plugin2 = pytestpm.get_plugin("pytest_hello")
 | 
				
			||||||
        assert plugin2 is plugin1
 | 
					        assert plugin2 is plugin1
 | 
				
			||||||
| 
						 | 
					@ -351,6 +356,7 @@ class TestPytestPluginManager:
 | 
				
			||||||
        pluginname = "pkg.plug"
 | 
					        pluginname = "pkg.plug"
 | 
				
			||||||
        pytestpm.import_plugin(pluginname)
 | 
					        pytestpm.import_plugin(pluginname)
 | 
				
			||||||
        mod = pytestpm.get_plugin("pkg.plug")
 | 
					        mod = pytestpm.get_plugin("pkg.plug")
 | 
				
			||||||
 | 
					        assert mod is not None
 | 
				
			||||||
        assert mod.x == 3
 | 
					        assert mod.x == 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_consider_conftest_deps(
 | 
					    def test_consider_conftest_deps(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue