1- import sys
21import inspect
32import warnings
3+ from .callers import _MultiCall , HookCallError , _raise_wrapfail , _Result
44
55__version__ = '0.5.0'
66
77__all__ = ["PluginManager" , "PluginValidationError" , "HookCallError" ,
88 "HookspecMarker" , "HookimplMarker" ]
99
10- _py3 = sys .version_info > (3 , 0 )
11-
1210
1311class PluginValidationError (Exception ):
1412 """ plugin failed validation. """
1513
1614
17- class HookCallError (Exception ):
18- """ Hook was called wrongly. """
19-
20-
2115class HookspecMarker (object ):
2216 """ Decorator helper class for marking functions as hook specifications.
2317
@@ -86,7 +80,7 @@ def __call__(self, function=None, hookwrapper=False, optionalhook=False,
8680 If hookwrapper is True the hook implementations needs to execute exactly
8781 one "yield". The code before the yield is run early before any non-hookwrapper
8882 function is run. The code after the yield is run after all non-hookwrapper
89- function have run. The yield receives an ``_CallOutcome `` object representing
83+ function have run. The yield receives a ``_Result `` object representing
9084 the exception or result outcome of the inner calls (including other hookwrapper
9185 calls).
9286
@@ -172,23 +166,17 @@ def get(self, name):
172166 return self .__class__ (self .root , self .tags + (name ,))
173167
174168
175- def _raise_wrapfail (wrap_controller , msg ):
176- co = wrap_controller .gi_code
177- raise RuntimeError ("wrap_controller at %r %s:%d %s" %
178- (co .co_name , co .co_filename , co .co_firstlineno , msg ))
179-
180-
181169def _wrapped_call (wrap_controller , func ):
182170 """ Wrap calling to a function with a generator which needs to yield
183171 exactly once. The yield point will trigger calling the wrapped function
184- and return its _CallOutcome to the yield point. The generator then needs
172+ and return its ``_Result`` to the yield point. The generator then needs
185173 to finish (raise StopIteration) in order for the wrapped call to complete.
186174 """
187175 try :
188176 next (wrap_controller ) # first yield
189177 except StopIteration :
190178 _raise_wrapfail (wrap_controller , "did not yield" )
191- call_outcome = _CallOutcome (func )
179+ call_outcome = _Result . from_call (func )
192180 try :
193181 wrap_controller .send (call_outcome )
194182 _raise_wrapfail (wrap_controller , "has second yield" )
@@ -197,39 +185,6 @@ def _wrapped_call(wrap_controller, func):
197185 return call_outcome .get_result ()
198186
199187
200- class _CallOutcome (object ):
201- """ Outcome of a function call, either an exception or a proper result.
202- Calling the ``get_result`` method will return the result or reraise
203- the exception raised when the function was called. """
204- excinfo = None
205-
206- def __init__ (self , func ):
207- try :
208- self .result = func ()
209- except BaseException :
210- self .excinfo = sys .exc_info ()
211-
212- def force_result (self , result ):
213- self .result = result
214- self .excinfo = None
215-
216- def get_result (self ):
217- if self .excinfo is None :
218- return self .result
219- else :
220- ex = self .excinfo
221- if _py3 :
222- raise ex [1 ].with_traceback (ex [2 ])
223- _reraise (* ex ) # noqa
224-
225-
226- if not _py3 :
227- exec ("""
228- def _reraise(cls, val, tb):
229- raise cls, val, tb
230- """ )
231-
232-
233188class _TracedHookExecution (object ):
234189 def __init__ (self , pluginmanager , before , after ):
235190 self .pluginmanager = pluginmanager
@@ -241,7 +196,7 @@ def __init__(self, pluginmanager, before, after):
241196
242197 def __call__ (self , hook , hook_impls , kwargs ):
243198 self .before (hook .name , hook_impls , kwargs )
244- outcome = _CallOutcome (lambda : self .oldcall (hook , hook_impls , kwargs ))
199+ outcome = _Result . from_call (lambda : self .oldcall (hook , hook_impls , kwargs ))
245200 self .after (outcome , hook .name , hook_impls , kwargs )
246201 return outcome .get_result ()
247202
@@ -275,7 +230,7 @@ def __init__(self, project_name, implprefix=None):
275230 self .hook = _HookRelay (self .trace .root .get ("hook" ))
276231 self ._implprefix = implprefix
277232 self ._inner_hookexec = lambda hook , methods , kwargs : \
278- _MultiCall (
233+ hook . multicall (
279234 methods , kwargs , specopts = hook .spec_opts , hook = hook
280235 ).execute ()
281236
@@ -490,7 +445,7 @@ def add_hookcall_monitoring(self, before, after):
490445 of HookImpl instances and the keyword arguments for the hook call.
491446
492447 ``after(outcome, hook_name, hook_impls, kwargs)`` receives the
493- same arguments as ``before`` but also a :py:class:`_CallOutcome `` object
448+ same arguments as ``before`` but also a :py:class:`_Result `` object
494449 which represents the result of the overall hook call.
495450 """
496451 return _TracedHookExecution (self , before , after ).undo
@@ -530,7 +485,7 @@ def subset_hook_caller(self, name, remove_plugins):
530485 return orig
531486
532487
533- class _MultiCall (object ):
488+ class _LegacyMultiCall (object ):
534489 """ execute a call into multiple python functions/methods. """
535490
536491 # XXX note that the __multicall__ argument is supported only
@@ -647,6 +602,7 @@ def __init__(self, name, hook_execute, specmodule_or_class=None, spec_opts=None)
647602 self ._hookexec = hook_execute
648603 self .argnames = None
649604 self .kwargnames = None
605+ self .multicall = _MultiCall
650606 if specmodule_or_class is not None :
651607 assert spec_opts is not None
652608 self .set_specification (specmodule_or_class , spec_opts )
@@ -697,6 +653,14 @@ def _add_hookimpl(self, hookimpl):
697653 i -= 1
698654 methods .insert (i + 1 , hookimpl )
699655
656+ if '__multicall__' in hookimpl .argnames :
657+ warnings .warn (
658+ "Support for __multicall__ is now deprecated and will be"
659+ "removed in an upcoming release." ,
660+ warnings .DeprecationWarning
661+ )
662+ self .multicall = _LegacyMultiCall
663+
700664 def __repr__ (self ):
701665 return "<_HookCaller %r>" % (self .name ,)
702666
0 commit comments