@@ -74,6 +74,94 @@ class HookimplOpts(TypedDict):
74
74
specname : str | None
75
75
76
76
77
+ @final
78
+ class HookimplConfiguration :
79
+ """Configuration class for hook implementations.
80
+
81
+ This class is intended to replace HookimplOpts in future versions.
82
+ It provides a more structured and extensible way to configure hook implementations.
83
+ """
84
+
85
+ __slots__ = (
86
+ "wrapper" ,
87
+ "hookwrapper" ,
88
+ "optionalhook" ,
89
+ "tryfirst" ,
90
+ "trylast" ,
91
+ "specname" ,
92
+ )
93
+
94
+ def __init__ (
95
+ self ,
96
+ wrapper : bool = False ,
97
+ hookwrapper : bool = False ,
98
+ optionalhook : bool = False ,
99
+ tryfirst : bool = False ,
100
+ trylast : bool = False ,
101
+ specname : str | None = None ,
102
+ ) -> None :
103
+ """Initialize hook implementation configuration.
104
+
105
+ :param wrapper:
106
+ Whether the hook implementation is a :ref:`wrapper <hookwrapper>`.
107
+ :param hookwrapper:
108
+ Whether the hook implementation is an :ref:`old-style wrapper
109
+ <old_style_hookwrappers>`.
110
+ :param optionalhook:
111
+ Whether validation against a hook specification is :ref:`optional
112
+ <optionalhook>`.
113
+ :param tryfirst:
114
+ Whether to try to order this hook implementation :ref:`first
115
+ <callorder>`.
116
+ :param trylast:
117
+ Whether to try to order this hook implementation :ref:`last
118
+ <callorder>`.
119
+ :param specname:
120
+ The name of the hook specification to match, see :ref:`specname`.
121
+ """
122
+ #: Whether the hook implementation is a :ref:`wrapper <hookwrapper>`.
123
+ self .wrapper : Final = wrapper
124
+ #: Whether the hook implementation is an :ref:`old-style wrapper
125
+ #: <old_style_hookwrappers>`.
126
+ self .hookwrapper : Final = hookwrapper
127
+ #: Whether validation against a hook specification is :ref:`optional
128
+ #: <optionalhook>`.
129
+ self .optionalhook : Final = optionalhook
130
+ #: Whether to try to order this hook implementation :ref:`first
131
+ #: <callorder>`.
132
+ self .tryfirst : Final = tryfirst
133
+ #: Whether to try to order this hook implementation :ref:`last
134
+ #: <callorder>`.
135
+ self .trylast : Final = trylast
136
+ #: The name of the hook specification to match, see :ref:`specname`.
137
+ self .specname : Final = specname
138
+
139
+ def to_opts (self ) -> HookimplOpts :
140
+ """Convert to HookimplOpts for backward compatibility."""
141
+ return {
142
+ "wrapper" : self .wrapper ,
143
+ "hookwrapper" : self .hookwrapper ,
144
+ "optionalhook" : self .optionalhook ,
145
+ "tryfirst" : self .tryfirst ,
146
+ "trylast" : self .trylast ,
147
+ "specname" : self .specname ,
148
+ }
149
+
150
+ @classmethod
151
+ def from_opts (cls , opts : HookimplOpts ) -> HookimplConfiguration :
152
+ """Create from HookimplOpts for backward compatibility."""
153
+ return cls (** opts )
154
+
155
+ def __repr__ (self ) -> str :
156
+ attrs = []
157
+ for slot in self .__slots__ :
158
+ value = getattr (self , slot )
159
+ if value :
160
+ attrs .append (f"{ slot } ={ value !r} " )
161
+ attrs_str = ", " .join (attrs )
162
+ return f"HookimplConfiguration({ attrs_str } )"
163
+
164
+
77
165
@final
78
166
class HookspecMarker :
79
167
"""Decorator for marking functions as hook specifications.
@@ -548,17 +636,10 @@ def call_extra(
548
636
"Cannot directly call a historic hook - use call_historic instead."
549
637
)
550
638
self ._verify_all_args_are_provided (kwargs )
551
- opts : HookimplOpts = {
552
- "wrapper" : False ,
553
- "hookwrapper" : False ,
554
- "optionalhook" : False ,
555
- "trylast" : False ,
556
- "tryfirst" : False ,
557
- "specname" : None ,
558
- }
639
+ config = HookimplConfiguration ()
559
640
hookimpls = self ._hookimpls .copy ()
560
641
for method in methods :
561
- hookimpl = HookImpl (None , "<temp>" , method , opts )
642
+ hookimpl = HookImpl (None , "<temp>" , method , config )
562
643
# Find last non-tryfirst nonwrapper method.
563
644
i = len (hookimpls ) - 1
564
645
while i >= 0 and (
@@ -649,14 +730,15 @@ class HookImpl:
649
730
"optionalhook" ,
650
731
"tryfirst" ,
651
732
"trylast" ,
733
+ "hookimpl_config" ,
652
734
)
653
735
654
736
def __init__ (
655
737
self ,
656
738
plugin : _Plugin ,
657
739
plugin_name : str ,
658
740
function : _HookImplFunction [object ],
659
- hook_impl_opts : HookimplOpts ,
741
+ hook_impl_config : HookimplConfiguration ,
660
742
) -> None :
661
743
""":meta private:"""
662
744
#: The hook implementation function.
@@ -668,24 +750,28 @@ def __init__(
668
750
self .kwargnames : Final = kwargnames
669
751
#: The plugin which defined this hook implementation.
670
752
self .plugin : Final = plugin
671
- #: The :class:`HookimplOpts` used to configure this hook implementation.
672
- self .opts : Final = hook_impl_opts
753
+ #: The :class:`HookimplConfiguration` used to configure this hook
754
+ #: implementation.
755
+ self .hookimpl_config : Final = hook_impl_config
756
+ #: The :class:`HookimplOpts` used to configure this hook implementation
757
+ #: (deprecated).
758
+ self .opts : Final = hook_impl_config .to_opts ()
673
759
#: The name of the plugin which defined this hook implementation.
674
760
self .plugin_name : Final = plugin_name
675
761
#: Whether the hook implementation is a :ref:`wrapper <hookwrapper>`.
676
- self .wrapper : Final = hook_impl_opts [ " wrapper" ]
762
+ self .wrapper : Final = hook_impl_config . wrapper
677
763
#: Whether the hook implementation is an :ref:`old-style wrapper
678
764
#: <old_style_hookwrappers>`.
679
- self .hookwrapper : Final = hook_impl_opts [ " hookwrapper" ]
765
+ self .hookwrapper : Final = hook_impl_config . hookwrapper
680
766
#: Whether validation against a hook specification is :ref:`optional
681
767
#: <optionalhook>`.
682
- self .optionalhook : Final = hook_impl_opts [ " optionalhook" ]
768
+ self .optionalhook : Final = hook_impl_config . optionalhook
683
769
#: Whether to try to order this hook implementation :ref:`first
684
770
#: <callorder>`.
685
- self .tryfirst : Final = hook_impl_opts [ " tryfirst" ]
771
+ self .tryfirst : Final = hook_impl_config . tryfirst
686
772
#: Whether to try to order this hook implementation :ref:`last
687
773
#: <callorder>`.
688
- self .trylast : Final = hook_impl_opts [ " trylast" ]
774
+ self .trylast : Final = hook_impl_config . trylast
689
775
690
776
def __repr__ (self ) -> str :
691
777
return f"<HookImpl plugin_name={ self .plugin_name !r} , plugin={ self .plugin !r} >"
0 commit comments