From c0e8c834674cfd037dc63fa4e66532edff31fac6 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Sun, 16 Mar 2025 21:35:47 +0100 Subject: [PATCH 1/3] Result.from_call: remove type ambiguity for exception/result locals --- src/pluggy/_result.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pluggy/_result.py b/src/pluggy/_result.py index 656a5841..eb07448a 100644 --- a/src/pluggy/_result.py +++ b/src/pluggy/_result.py @@ -57,12 +57,12 @@ def exception(self) -> BaseException | None: def from_call(cls, func: Callable[[], ResultType]) -> Result[ResultType]: """:meta private:""" __tracebackhide__ = True - result = exception = None try: result = func() except BaseException as exc: - exception = exc - return cls(result, exception) + return cls(None, exc) + else: + return cls(result, None) def force_result(self, result: ResultType) -> None: """Force the result(s) to ``result``. From d7a5b6d8b61a67796304fa01248ae6131a795cb0 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Thu, 27 Mar 2025 10:51:13 +0100 Subject: [PATCH 2/3] pass tests initial --- pyproject.toml | 1 + src/pluggy/__init__.py | 3 +-- src/pluggy/_hookrelay.py | 25 +++++++++++++++++++++++++ src/pluggy/_hooks.py | 31 ++++++++++--------------------- src/pluggy/_manager.py | 8 ++++---- 5 files changed, 41 insertions(+), 27 deletions(-) create mode 100644 src/pluggy/_hookrelay.py diff --git a/pyproject.toml b/pyproject.toml index 54d72958..d8648256 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,6 +2,7 @@ requires = [ "setuptools>=65.0", "setuptools-scm[toml]>=8.0", + "mypy>=1.15", ] build-backend = "setuptools.build_meta" diff --git a/src/pluggy/__init__.py b/src/pluggy/__init__.py index 8a651f49..1b3e961c 100644 --- a/src/pluggy/__init__.py +++ b/src/pluggy/__init__.py @@ -7,7 +7,6 @@ "HookspecOpts", "HookimplOpts", "HookImpl", - "HookRelay", "HookspecMarker", "HookimplMarker", "Result", @@ -18,7 +17,7 @@ from ._hooks import HookImpl from ._hooks import HookimplMarker from ._hooks import HookimplOpts -from ._hooks import HookRelay +from ._hookrelay import HookRelay from ._hooks import HookspecMarker from ._hooks import HookspecOpts from ._manager import PluginManager diff --git a/src/pluggy/_hookrelay.py b/src/pluggy/_hookrelay.py new file mode 100644 index 00000000..cdf983d2 --- /dev/null +++ b/src/pluggy/_hookrelay.py @@ -0,0 +1,25 @@ +""" +separate module for only hookrelay as mypyc doesnt support dynamic attributes/getattr +""" + +from __future__ import annotations + +from typing import final, TYPE_CHECKING + +if TYPE_CHECKING: + from pluggy import HookCaller + + +@final +class HookRelay: + """Hook holder object for performing 1:N hook calls where N is the number + of registered plugins.""" + + __slots__ = ("__dict__",) + + def __init__(self) -> None: + """:meta private:""" + + if TYPE_CHECKING: + + def __getattr__(self, name: str) -> HookCaller: ... diff --git a/src/pluggy/_hooks.py b/src/pluggy/_hooks.py index 97fef0d7..48d29ae5 100644 --- a/src/pluggy/_hooks.py +++ b/src/pluggy/_hooks.py @@ -17,12 +17,12 @@ from typing import final from typing import Optional from typing import overload -from typing import TYPE_CHECKING from typing import TypedDict from typing import TypeVar from typing import Union import warnings +from ._hookrelay import HookRelay from ._result import Result @@ -30,11 +30,13 @@ _F = TypeVar("_F", bound=Callable[..., object]) _Namespace = Union[ModuleType, type] _Plugin = object -_HookExec = Callable[ - [str, Sequence["HookImpl"], Mapping[str, object], bool], - Union[object, list[object]], + +type _HookExec = Callable[ + [str, Sequence[HookImpl], Mapping[str, object], bool], + Union[object, list[object]] ] -_HookImplFunction = Callable[..., Union[_T, Generator[None, Result[_T], None]]] + +type _HookImplFunction[T] = Callable[..., Union[T, Generator[None, Result[T], None]]] class HookspecOpts(TypedDict): @@ -355,21 +357,6 @@ def varnames(func: object) -> tuple[tuple[str, ...], tuple[str, ...]]: return args, kwargs -@final -class HookRelay: - """Hook holder object for performing 1:N hook calls where N is the number - of registered plugins.""" - - __slots__ = ("__dict__",) - - def __init__(self) -> None: - """:meta private:""" - - if TYPE_CHECKING: - - def __getattr__(self, name: str) -> HookCaller: ... - - # Historical name (pluggy<=1.2), kept for backward compatibility. _HookRelay = HookRelay @@ -388,6 +375,8 @@ class HookCaller: "_call_history", ) + + _call_history: _CallHistory | None def __init__( self, name: str, @@ -407,7 +396,7 @@ def __init__( # 5. wrappers # 6. tryfirst wrappers self._hookimpls: Final[list[HookImpl]] = [] - self._call_history: _CallHistory | None = None + self._call_history = None # TODO: Document, or make private. self.spec: HookSpec | None = None if specmodule_or_class is not None: diff --git a/src/pluggy/_manager.py b/src/pluggy/_manager.py index ff1e3ce6..4578a048 100644 --- a/src/pluggy/_manager.py +++ b/src/pluggy/_manager.py @@ -5,7 +5,7 @@ from collections.abc import Sequence import inspect import types -from typing import Any +from typing import Any, TypeAlias from typing import Callable from typing import cast from typing import Final @@ -13,6 +13,7 @@ import warnings from . import _tracing +from ._hookrelay import HookRelay from ._callers import _multicall from ._hooks import _HookImplFunction from ._hooks import _Namespace @@ -21,7 +22,6 @@ from ._hooks import HookCaller from ._hooks import HookImpl from ._hooks import HookimplOpts -from ._hooks import HookRelay from ._hooks import HookspecOpts from ._hooks import normalize_hookimpl_opts from ._result import Result @@ -32,8 +32,8 @@ import importlib.metadata -_BeforeTrace = Callable[[str, Sequence[HookImpl], Mapping[str, Any]], None] -_AfterTrace = Callable[[Result[Any], str, Sequence[HookImpl], Mapping[str, Any]], None] +_BeforeTrace: TypeAlias = Callable[[str, Sequence[HookImpl], Mapping[str, Any]], None] +_AfterTrace: TypeAlias = Callable[[Result[Any], str, Sequence[HookImpl], Mapping[str, Any]], None] def _warn_for_function(warning: Warning, function: Callable[..., object]) -> None: From cddce6f301da6a91e97bd231a28ede5e32339b74 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Wed, 25 Jun 2025 17:35:42 +0200 Subject: [PATCH 3/3] pre-commit par --- src/pluggy/__init__.py | 1 - src/pluggy/_hookrelay.py | 4 +++- src/pluggy/_hooks.py | 5 ++--- src/pluggy/_manager.py | 9 ++++++--- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/pluggy/__init__.py b/src/pluggy/__init__.py index 1b3e961c..233433a7 100644 --- a/src/pluggy/__init__.py +++ b/src/pluggy/__init__.py @@ -17,7 +17,6 @@ from ._hooks import HookImpl from ._hooks import HookimplMarker from ._hooks import HookimplOpts -from ._hookrelay import HookRelay from ._hooks import HookspecMarker from ._hooks import HookspecOpts from ._manager import PluginManager diff --git a/src/pluggy/_hookrelay.py b/src/pluggy/_hookrelay.py index cdf983d2..a42493bf 100644 --- a/src/pluggy/_hookrelay.py +++ b/src/pluggy/_hookrelay.py @@ -4,7 +4,9 @@ from __future__ import annotations -from typing import final, TYPE_CHECKING +from typing import final +from typing import TYPE_CHECKING + if TYPE_CHECKING: from pluggy import HookCaller diff --git a/src/pluggy/_hooks.py b/src/pluggy/_hooks.py index 48d29ae5..6bc39010 100644 --- a/src/pluggy/_hooks.py +++ b/src/pluggy/_hooks.py @@ -32,8 +32,7 @@ _Plugin = object type _HookExec = Callable[ - [str, Sequence[HookImpl], Mapping[str, object], bool], - Union[object, list[object]] + [str, Sequence[HookImpl], Mapping[str, object], bool], Union[object, list[object]] ] type _HookImplFunction[T] = Callable[..., Union[T, Generator[None, Result[T], None]]] @@ -375,8 +374,8 @@ class HookCaller: "_call_history", ) - _call_history: _CallHistory | None + def __init__( self, name: str, diff --git a/src/pluggy/_manager.py b/src/pluggy/_manager.py index 4578a048..170babf7 100644 --- a/src/pluggy/_manager.py +++ b/src/pluggy/_manager.py @@ -5,16 +5,17 @@ from collections.abc import Sequence import inspect import types -from typing import Any, TypeAlias +from typing import Any from typing import Callable from typing import cast from typing import Final from typing import TYPE_CHECKING +from typing import TypeAlias import warnings from . import _tracing -from ._hookrelay import HookRelay from ._callers import _multicall +from ._hookrelay import HookRelay from ._hooks import _HookImplFunction from ._hooks import _Namespace from ._hooks import _Plugin @@ -33,7 +34,9 @@ _BeforeTrace: TypeAlias = Callable[[str, Sequence[HookImpl], Mapping[str, Any]], None] -_AfterTrace: TypeAlias = Callable[[Result[Any], str, Sequence[HookImpl], Mapping[str, Any]], None] +_AfterTrace: TypeAlias = Callable[ + [Result[Any], str, Sequence[HookImpl], Mapping[str, Any]], None +] def _warn_for_function(warning: Warning, function: Callable[..., object]) -> None: