11
11
from typing import Any
12
12
from typing import Callable
13
13
from typing import Final
14
+ from typing import final
14
15
from typing import Generator
15
16
from typing import List
16
17
from typing import Mapping
37
38
_HookImplFunction = Callable [..., Union [_T , Generator [None , Result [_T ], None ]]]
38
39
39
40
40
- class HookSpecOpts (TypedDict ):
41
+ class HookspecOpts (TypedDict ):
41
42
"""Options for a hook specification."""
42
43
43
44
#: Whether the hook is :ref:`first result only <firstresult>`.
@@ -48,7 +49,7 @@ class HookSpecOpts(TypedDict):
48
49
warn_on_impl : Warning | None
49
50
50
51
51
- class HookImplOpts (TypedDict ):
52
+ class HookimplOpts (TypedDict ):
52
53
"""Options for a hook implementation."""
53
54
54
55
#: Whether the hook implementation is a :ref:`wrapper <hookwrapper>`.
@@ -69,6 +70,7 @@ class HookImplOpts(TypedDict):
69
70
specname : str | None
70
71
71
72
73
+ @final
72
74
class HookspecMarker :
73
75
"""Decorator for marking functions as hook specifications.
74
76
@@ -132,7 +134,7 @@ def __call__( # noqa: F811
132
134
def setattr_hookspec_opts (func : _F ) -> _F :
133
135
if historic and firstresult :
134
136
raise ValueError ("cannot have a historic firstresult hook" )
135
- opts : HookSpecOpts = {
137
+ opts : HookspecOpts = {
136
138
"firstresult" : firstresult ,
137
139
"historic" : historic ,
138
140
"warn_on_impl" : warn_on_impl ,
@@ -146,6 +148,7 @@ def setattr_hookspec_opts(func: _F) -> _F:
146
148
return setattr_hookspec_opts
147
149
148
150
151
+ @final
149
152
class HookimplMarker :
150
153
"""Decorator for marking functions as hook implementations.
151
154
@@ -247,7 +250,7 @@ def __call__( # noqa: F811
247
250
"""
248
251
249
252
def setattr_hookimpl_opts (func : _F ) -> _F :
250
- opts : HookImplOpts = {
253
+ opts : HookimplOpts = {
251
254
"wrapper" : wrapper ,
252
255
"hookwrapper" : hookwrapper ,
253
256
"optionalhook" : optionalhook ,
@@ -264,7 +267,7 @@ def setattr_hookimpl_opts(func: _F) -> _F:
264
267
return setattr_hookimpl_opts (function )
265
268
266
269
267
- def normalize_hookimpl_opts (opts : HookImplOpts ) -> None :
270
+ def normalize_hookimpl_opts (opts : HookimplOpts ) -> None :
268
271
opts .setdefault ("tryfirst" , False )
269
272
opts .setdefault ("trylast" , False )
270
273
opts .setdefault ("wrapper" , False )
@@ -341,6 +344,7 @@ def varnames(func: object) -> tuple[tuple[str, ...], tuple[str, ...]]:
341
344
return args , kwargs
342
345
343
346
347
+ @final
344
348
class HookRelay :
345
349
"""Hook holder object for performing 1:N hook calls where N is the number
346
350
of registered plugins."""
@@ -379,13 +383,15 @@ def __init__(
379
383
name : str ,
380
384
hook_execute : _HookExec ,
381
385
specmodule_or_class : _Namespace | None = None ,
382
- spec_opts : HookSpecOpts | None = None ,
386
+ spec_opts : HookspecOpts | None = None ,
383
387
) -> None :
384
388
""":meta private:"""
389
+ #: Name of the hook getting called.
385
390
self .name : Final = name
386
391
self ._hookexec : Final = hook_execute
387
392
self ._hookimpls : Final [list [HookImpl ]] = []
388
393
self ._call_history : _CallHistory | None = None
394
+ # TODO: Document, or make private.
389
395
self .spec : HookSpec | None = None
390
396
if specmodule_or_class is not None :
391
397
assert spec_opts is not None
@@ -399,7 +405,7 @@ def has_spec(self) -> bool:
399
405
def set_specification (
400
406
self ,
401
407
specmodule_or_class : _Namespace ,
402
- spec_opts : HookSpecOpts ,
408
+ spec_opts : HookspecOpts ,
403
409
) -> None :
404
410
if self .spec is not None :
405
411
raise ValueError (
@@ -522,7 +528,7 @@ def call_extra(
522
528
not self .is_historic ()
523
529
), "Cannot directly call a historic hook - use call_historic instead."
524
530
self ._verify_all_args_are_provided (kwargs )
525
- opts : HookImplOpts = {
531
+ opts : HookimplOpts = {
526
532
"wrapper" : False ,
527
533
"hookwrapper" : False ,
528
534
"optionalhook" : False ,
@@ -606,7 +612,10 @@ def __repr__(self) -> str:
606
612
return f"<_SubsetHookCaller { self .name !r} >"
607
613
608
614
615
+ @final
609
616
class HookImpl :
617
+ """A hook implementation in a :class:`HookCaller`."""
618
+
610
619
__slots__ = (
611
620
"function" ,
612
621
"argnames" ,
@@ -626,23 +635,42 @@ def __init__(
626
635
plugin : _Plugin ,
627
636
plugin_name : str ,
628
637
function : _HookImplFunction [object ],
629
- hook_impl_opts : HookImplOpts ,
638
+ hook_impl_opts : HookimplOpts ,
630
639
) -> None :
640
+ """:meta private:"""
641
+ #: The hook implementation function.
631
642
self .function : Final = function
632
- self .argnames , self .kwargnames = varnames (self .function )
633
- self .plugin = plugin
634
- self .opts = hook_impl_opts
635
- self .plugin_name = plugin_name
636
- self .wrapper = hook_impl_opts ["wrapper" ]
637
- self .hookwrapper = hook_impl_opts ["hookwrapper" ]
638
- self .optionalhook = hook_impl_opts ["optionalhook" ]
639
- self .tryfirst = hook_impl_opts ["tryfirst" ]
640
- self .trylast = hook_impl_opts ["trylast" ]
643
+ argnames , kwargnames = varnames (self .function )
644
+ #: The positional parameter names of ``function```.
645
+ self .argnames : Final = argnames
646
+ #: The keyword parameter names of ``function```.
647
+ self .kwargnames : Final = kwargnames
648
+ #: The plugin which defined this hook implementation.
649
+ self .plugin : Final = plugin
650
+ #: The :class:`HookimplOpts` used to configure this hook implementation.
651
+ self .opts : Final = hook_impl_opts
652
+ #: The name of the plugin which defined this hook implementation.
653
+ self .plugin_name : Final = plugin_name
654
+ #: Whether the hook implementation is a :ref:`wrapper <hookwrapper>`.
655
+ self .wrapper : Final = hook_impl_opts ["wrapper" ]
656
+ #: Whether the hook implementation is an :ref:`old-style wrapper
657
+ #: <old_style_hookwrappers>`.
658
+ self .hookwrapper : Final = hook_impl_opts ["hookwrapper" ]
659
+ #: Whether validation against a hook specification is :ref:`optional
660
+ #: <optionalhook>`.
661
+ self .optionalhook : Final = hook_impl_opts ["optionalhook" ]
662
+ #: Whether to try to order this hook implementation :ref:`first
663
+ #: <callorder>`.
664
+ self .tryfirst : Final = hook_impl_opts ["tryfirst" ]
665
+ #: Whether to try to order this hook implementation :ref:`last
666
+ #: <callorder>`.
667
+ self .trylast : Final = hook_impl_opts ["trylast" ]
641
668
642
669
def __repr__ (self ) -> str :
643
670
return f"<HookImpl plugin_name={ self .plugin_name !r} , plugin={ self .plugin !r} >"
644
671
645
672
673
+ @final
646
674
class HookSpec :
647
675
__slots__ = (
648
676
"namespace" ,
@@ -654,7 +682,7 @@ class HookSpec:
654
682
"warn_on_impl" ,
655
683
)
656
684
657
- def __init__ (self , namespace : _Namespace , name : str , opts : HookSpecOpts ) -> None :
685
+ def __init__ (self , namespace : _Namespace , name : str , opts : HookspecOpts ) -> None :
658
686
self .namespace = namespace
659
687
self .function : Callable [..., object ] = getattr (namespace , name )
660
688
self .name = name
0 commit comments