Skip to content

Commit a489e0c

Browse files
committed
Add Final type annotations to PluginManager and HookCaller
These are help in understanding which parts of the class are mutable state.
1 parent 0b45952 commit a489e0c

File tree

2 files changed

+20
-16
lines changed

2 files changed

+20
-16
lines changed

src/pluggy/_hooks.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
if TYPE_CHECKING:
2626
from typing_extensions import TypedDict
27+
from typing_extensions import Final
2728

2829

2930
_T = TypeVar("_T")
@@ -61,7 +62,7 @@ class HookspecMarker:
6162
__slots__ = ("project_name",)
6263

6364
def __init__(self, project_name: str) -> None:
64-
self.project_name = project_name
65+
self.project_name: "Final" = project_name
6566

6667
@overload
6768
def __call__(
@@ -132,7 +133,7 @@ class HookimplMarker:
132133
__slots__ = ("project_name",)
133134

134135
def __init__(self, project_name: str) -> None:
135-
self.project_name = project_name
136+
self.project_name: "Final" = project_name
136137

137138
@overload
138139
def __call__(
@@ -277,6 +278,9 @@ def __getattr__(self, name: str) -> "_HookCaller":
277278
...
278279

279280

281+
_CallHistory = List[Tuple[Mapping[str, object], Optional[Callable[[Any], None]]]]
282+
283+
280284
class _HookCaller:
281285
__slots__ = (
282286
"name",
@@ -294,13 +298,11 @@ def __init__(
294298
specmodule_or_class: Optional[_Namespace] = None,
295299
spec_opts: Optional["_HookSpecOpts"] = None,
296300
) -> None:
297-
self.name = name
298-
self._hookexec = hook_execute
299-
self._wrappers: List[HookImpl] = []
300-
self._nonwrappers: List[HookImpl] = []
301-
self._call_history: Optional[
302-
List[Tuple[Mapping[str, object], Optional[Callable[[Any], None]]]]
303-
] = None
301+
self.name: "Final" = name
302+
self._hookexec: "Final" = hook_execute
303+
self._wrappers: "Final[List[HookImpl]]" = []
304+
self._nonwrappers: "Final[List[HookImpl]]" = []
305+
self._call_history: Optional[_CallHistory] = None
304306
self.spec: Optional[HookSpec] = None
305307
if specmodule_or_class is not None:
306308
assert spec_opts is not None
@@ -472,7 +474,7 @@ def __init__(
472474
function: _HookImplFunction[object],
473475
hook_impl_opts: "_HookImplOpts",
474476
) -> None:
475-
self.function = function
477+
self.function: "Final" = function
476478
self.argnames, self.kwargnames = varnames(self.function)
477479
self.plugin = plugin
478480
self.opts = hook_impl_opts

src/pluggy/_manager.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
import importlib_metadata
3939

4040
if TYPE_CHECKING:
41+
from typing_extensions import Final
42+
4143
from ._hooks import _HookImplOpts, _HookSpecOpts
4244

4345
_BeforeTrace = Callable[[str, Sequence[HookImpl], Mapping[str, Any]], None]
@@ -110,12 +112,12 @@ class PluginManager:
110112
)
111113

112114
def __init__(self, project_name: str) -> None:
113-
self.project_name = project_name
114-
self._name2plugin: Dict[str, _Plugin] = {}
115-
self._plugin2hookcallers: Dict[_Plugin, List[_HookCaller]] = {}
116-
self._plugin_distinfo: List[Tuple[_Plugin, DistFacade]] = []
117-
self.trace = _tracing.TagTracer().get("pluginmanage")
118-
self.hook = _HookRelay()
115+
self.project_name: "Final" = project_name
116+
self._name2plugin: "Final[Dict[str, _Plugin]]" = {}
117+
self._plugin2hookcallers: "Final[Dict[_Plugin, List[_HookCaller]]]" = {}
118+
self._plugin_distinfo: "Final[List[Tuple[_Plugin, DistFacade]]]" = []
119+
self.trace: "Final" = _tracing.TagTracer().get("pluginmanage")
120+
self.hook: "Final" = _HookRelay()
119121
self._inner_hookexec = _multicall
120122

121123
def _hookexec(

0 commit comments

Comments
 (0)