99from collections .abc import Sequence
1010from typing import cast
1111from typing import NoReturn
12+ from typing import TYPE_CHECKING
1213from typing import TypeAlias
1314import warnings
1415
@@ -29,8 +30,10 @@ def run_old_style_hookwrapper(
2930 """
3031 backward compatibility wrapper to run a old style hookwrapper as a wrapper
3132 """
32-
33- teardown : Teardown = cast (Teardown , hook_impl .function (* args ))
33+ if TYPE_CHECKING :
34+ teardown = cast (Teardown , hook_impl .function (* args ))
35+ else :
36+ teardown = hook_impl .function (* args )
3437 try :
3538 next (teardown )
3639 except StopIteration :
@@ -90,44 +93,43 @@ def _multicall(
9093 __tracebackhide__ = True
9194 results : list [object ] = []
9295 exception = None
96+ teardowns : list [Teardown ] = []
9397 try : # run impl and wrapper setup functions in a loop
94- teardowns : list [Teardown ] = []
95- try :
96- for hook_impl in reversed (hook_impls ):
98+ for hook_impl in reversed (hook_impls ):
99+ try :
100+ args = [caller_kwargs [argname ] for argname in hook_impl .argnames ]
101+ except KeyError as e :
102+ raise HookCallError (
103+ f"hook call must provide argument { e .args [0 ]!r} "
104+ ) from e
105+
106+ if hook_impl .hookwrapper :
107+ function_gen = run_old_style_hookwrapper (hook_impl , hook_name , args )
108+
109+ next (function_gen ) # first yield
110+ teardowns .append (function_gen )
111+
112+ elif hook_impl .wrapper :
113+ res = hook_impl .function (* args )
114+ # If this cast is not valid, a type error is raised below,
115+ # which is the desired response.
116+ if TYPE_CHECKING :
117+ function_gen = cast (Generator [None , object , object ], res )
118+ else :
119+ function_gen = res
97120 try :
98- args = [caller_kwargs [argname ] for argname in hook_impl .argnames ]
99- except KeyError as e :
100- # coverage bug - this is tested
101- for argname in hook_impl .argnames : # pragma: no cover
102- if argname not in caller_kwargs :
103- raise HookCallError (
104- f"hook call must provide argument { argname !r} "
105- ) from e
106-
107- if hook_impl .hookwrapper :
108- function_gen = run_old_style_hookwrapper (hook_impl , hook_name , args )
109-
110121 next (function_gen ) # first yield
111- teardowns .append (function_gen )
112-
113- elif hook_impl .wrapper :
114- try :
115- # If this cast is not valid, a type error is raised below,
116- # which is the desired response.
117- res = hook_impl .function (* args )
118- function_gen = cast (Generator [None , object , object ], res )
119- next (function_gen ) # first yield
120- teardowns .append (function_gen )
121- except StopIteration :
122- _raise_wrapfail (function_gen , "did not yield" )
123- else :
124- res = hook_impl .function (* args )
125- if res is not None :
126- results .append (res )
127- if firstresult : # halt further impl calls
128- break
129- except BaseException as exc :
130- exception = exc
122+ except StopIteration :
123+ _raise_wrapfail (function_gen , "did not yield" )
124+ teardowns .append (function_gen )
125+ else :
126+ res = hook_impl .function (* args )
127+ if res is not None :
128+ results .append (res )
129+ if firstresult : # halt further impl calls
130+ break
131+ except BaseException as exc :
132+ exception = exc
131133 finally :
132134 if firstresult : # first result hooks return a single value
133135 result = results [0 ] if results else None
0 commit comments