diff --git a/changelog/14728.misc.rst b/changelog/14728.misc.rst new file mode 100644 index 00000000000..803859bb52a --- /dev/null +++ b/changelog/14728.misc.rst @@ -0,0 +1 @@ +Improved the type annotations of ``Node.ihook`` and ``Session.gethookproxy``. diff --git a/doc/en/conf.py b/doc/en/conf.py index 04ba1cfc616..d275c75fc60 100644 --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -80,6 +80,7 @@ ("py:class", "_pytest.logging.LogCaptureHandler"), ("py:class", "_pytest.mark.structures.ParameterSet"), # Intentionally undocumented/private + ("py:class", "FSHookProxy"), ("py:class", "_pytest._code.code.Traceback"), ("py:class", "_pytest._py.path.LocalPath"), ("py:class", "_pytest.capture.CaptureResult"), diff --git a/src/_pytest/main.py b/src/_pytest/main.py index c4df4e46983..df54d91fb35 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -728,7 +728,7 @@ def isinitpath( else: return path_ in self._initialpaths - def gethookproxy(self, fspath: os.PathLike[str]) -> pluggy.HookRelay: + def gethookproxy(self, fspath: os.PathLike[str]) -> pluggy.HookRelay | FSHookProxy: # Optimization: Path(Path(...)) is much slower than isinstance. path = fspath if isinstance(fspath, Path) else Path(fspath) pm = self.config.pluginmanager @@ -736,10 +736,10 @@ def gethookproxy(self, fspath: os.PathLike[str]) -> pluggy.HookRelay: # hooks with all conftest.py files. my_conftestmodules = pm._getconftestmodules(path) remove_mods = pm._conftest_plugins.difference(my_conftestmodules) - proxy: pluggy.HookRelay + proxy: pluggy.HookRelay | FSHookProxy if remove_mods: # One or more conftests are not in use at this path. - proxy = FSHookProxy(pm, remove_mods) # type: ignore[assignment] + proxy = FSHookProxy(pm, remove_mods) else: # All plugins are active for this fspath. proxy = self.config.hook diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index f0629c2daf7..51a3fea3f22 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -44,6 +44,7 @@ from typing_extensions import Self # Imported here due to circular import. + from _pytest.main import FSHookProxy from _pytest.main import Session @@ -225,7 +226,7 @@ def from_parent(cls, parent: Node, **kw) -> Self: return cls._create(parent=parent, **kw) @property - def ihook(self) -> pluggy.HookRelay: + def ihook(self) -> pluggy.HookRelay | FSHookProxy: """Path-sensitive hook proxy used to call pytest hooks.""" return self.session.gethookproxy(self.path)