1
- import sys
2
1
import inspect
3
2
import warnings
3
+ from .callers import _MultiCall , HookCallError , _raise_wrapfail , _Result
4
4
5
5
__version__ = '0.5.0'
6
6
7
7
__all__ = ["PluginManager" , "PluginValidationError" , "HookCallError" ,
8
8
"HookspecMarker" , "HookimplMarker" ]
9
9
10
- _py3 = sys .version_info > (3 , 0 )
11
-
12
10
13
11
class PluginValidationError (Exception ):
14
12
""" plugin failed validation. """
15
13
16
14
17
- class HookCallError (Exception ):
18
- """ Hook was called wrongly. """
19
-
20
-
21
15
class HookspecMarker (object ):
22
16
""" Decorator helper class for marking functions as hook specifications.
23
17
@@ -86,7 +80,7 @@ def __call__(self, function=None, hookwrapper=False, optionalhook=False,
86
80
If hookwrapper is True the hook implementations needs to execute exactly
87
81
one "yield". The code before the yield is run early before any non-hookwrapper
88
82
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
90
84
the exception or result outcome of the inner calls (including other hookwrapper
91
85
calls).
92
86
@@ -172,23 +166,17 @@ def get(self, name):
172
166
return self .__class__ (self .root , self .tags + (name ,))
173
167
174
168
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
-
181
169
def _wrapped_call (wrap_controller , func ):
182
170
""" Wrap calling to a function with a generator which needs to yield
183
171
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
185
173
to finish (raise StopIteration) in order for the wrapped call to complete.
186
174
"""
187
175
try :
188
176
next (wrap_controller ) # first yield
189
177
except StopIteration :
190
178
_raise_wrapfail (wrap_controller , "did not yield" )
191
- call_outcome = _CallOutcome (func )
179
+ call_outcome = _Result . from_call (func )
192
180
try :
193
181
wrap_controller .send (call_outcome )
194
182
_raise_wrapfail (wrap_controller , "has second yield" )
@@ -197,39 +185,6 @@ def _wrapped_call(wrap_controller, func):
197
185
return call_outcome .get_result ()
198
186
199
187
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
-
233
188
class _TracedHookExecution (object ):
234
189
def __init__ (self , pluginmanager , before , after ):
235
190
self .pluginmanager = pluginmanager
@@ -241,7 +196,7 @@ def __init__(self, pluginmanager, before, after):
241
196
242
197
def __call__ (self , hook , hook_impls , kwargs ):
243
198
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 ))
245
200
self .after (outcome , hook .name , hook_impls , kwargs )
246
201
return outcome .get_result ()
247
202
@@ -275,7 +230,7 @@ def __init__(self, project_name, implprefix=None):
275
230
self .hook = _HookRelay (self .trace .root .get ("hook" ))
276
231
self ._implprefix = implprefix
277
232
self ._inner_hookexec = lambda hook , methods , kwargs : \
278
- _MultiCall (
233
+ hook . multicall (
279
234
methods , kwargs , specopts = hook .spec_opts , hook = hook
280
235
).execute ()
281
236
@@ -490,7 +445,7 @@ def add_hookcall_monitoring(self, before, after):
490
445
of HookImpl instances and the keyword arguments for the hook call.
491
446
492
447
``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
494
449
which represents the result of the overall hook call.
495
450
"""
496
451
return _TracedHookExecution (self , before , after ).undo
@@ -530,7 +485,7 @@ def subset_hook_caller(self, name, remove_plugins):
530
485
return orig
531
486
532
487
533
- class _MultiCall (object ):
488
+ class _LegacyMultiCall (object ):
534
489
""" execute a call into multiple python functions/methods. """
535
490
536
491
# 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)
647
602
self ._hookexec = hook_execute
648
603
self .argnames = None
649
604
self .kwargnames = None
605
+ self .multicall = _MultiCall
650
606
if specmodule_or_class is not None :
651
607
assert spec_opts is not None
652
608
self .set_specification (specmodule_or_class , spec_opts )
@@ -697,6 +653,14 @@ def _add_hookimpl(self, hookimpl):
697
653
i -= 1
698
654
methods .insert (i + 1 , hookimpl )
699
655
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
+
700
664
def __repr__ (self ):
701
665
return "<_HookCaller %r>" % (self .name ,)
702
666
0 commit comments