@@ -212,7 +212,10 @@ def __init__(self, project_name, implprefix=None):
212
212
self ._implprefix = implprefix
213
213
self ._inner_hookexec = lambda hook , methods , kwargs : \
214
214
hook .multicall (
215
- methods , kwargs , specopts = hook .spec_opts , hook = hook
215
+ methods ,
216
+ kwargs ,
217
+ specopts = hook .spec .opts ['firstresult' ] if hook .spec else False ,
218
+ hook = hook
216
219
)
217
220
218
221
def _hookexec (self , hook , methods , kwargs ):
@@ -360,7 +363,7 @@ def _verify_hook(self, hook, hookimpl):
360
363
(hookimpl .plugin_name , hook .name ))
361
364
362
365
# positional arg checking
363
- notinspec = set (hookimpl .argnames ) - set (hook .argnames )
366
+ notinspec = set (hookimpl .argnames ) - set (hook .spec . argnames )
364
367
if notinspec :
365
368
raise PluginValidationError (
366
369
"Plugin %r for hook %r\n hookimpl definition: %s\n "
@@ -453,8 +456,8 @@ def subset_hook_caller(self, name, remove_plugins):
453
456
orig = getattr (self .hook , name )
454
457
plugins_to_remove = [plug for plug in remove_plugins if hasattr (plug , name )]
455
458
if plugins_to_remove :
456
- hc = _HookCaller (orig .name , orig ._hookexec , orig ._specmodule_or_class ,
457
- orig .spec_opts )
459
+ hc = _HookCaller (orig .name , orig ._hookexec , orig .spec . namespace ,
460
+ orig .spec . opts )
458
461
for hookimpl in (orig ._wrappers + orig ._nonwrappers ):
459
462
plugin = hookimpl .plugin
460
463
if plugin not in plugins_to_remove :
@@ -536,26 +539,23 @@ def __init__(self, name, hook_execute, specmodule_or_class=None, spec_opts=None)
536
539
self .argnames = None
537
540
self .kwargnames = None
538
541
self .multicall = _multicall
542
+ self .spec = None
543
+ self ._call_history = None
539
544
if specmodule_or_class is not None :
540
545
assert spec_opts is not None
541
546
self .set_specification (specmodule_or_class , spec_opts )
542
547
543
548
def has_spec (self ):
544
- return hasattr ( self , "_specmodule_or_class" )
549
+ return self . spec is not None
545
550
546
551
def set_specification (self , specmodule_or_class , spec_opts ):
547
552
assert not self .has_spec ()
548
- self ._specmodule_or_class = specmodule_or_class
549
- specfunc = getattr (specmodule_or_class , self .name )
550
- # get spec arg signature
551
- argnames , self .kwargnames = varnames (specfunc )
552
- self .argnames = ["__multicall__" ] + list (argnames )
553
- self .spec_opts = spec_opts
553
+ self .spec = HookSpec (specmodule_or_class , self .name , spec_opts )
554
554
if spec_opts .get ("historic" ):
555
555
self ._call_history = []
556
556
557
557
def is_historic (self ):
558
- return hasattr ( self , " _call_history" )
558
+ return self . _call_history is not None
559
559
560
560
def _remove_plugin (self , plugin ):
561
561
def remove (wrappers ):
@@ -601,8 +601,8 @@ def __call__(self, *args, **kwargs):
601
601
if args :
602
602
raise TypeError ("hook calling supports only keyword arguments" )
603
603
assert not self .is_historic ()
604
- if self .argnames :
605
- notincall = set (self .argnames ) - set (['__multicall__' ]) - set (
604
+ if self .spec :
605
+ notincall = set (self .spec . argnames ) - set (['__multicall__' ]) - set (
606
606
kwargs .keys ())
607
607
if notincall :
608
608
warnings .warn (
@@ -649,6 +649,16 @@ def _maybe_apply_history(self, method):
649
649
proc (res [0 ])
650
650
651
651
652
+ class HookSpec (object ):
653
+ def __init__ (self , namespace , name , opts ):
654
+ self .namespace = namespace
655
+ self .function = function = getattr (namespace , name )
656
+ self .name = name
657
+ self .argnames , self .kwargnames = varnames (function )
658
+ self .opts = opts
659
+ self .argnames = ["__multicall__" ] + list (self .argnames )
660
+
661
+
652
662
class HookImpl (object ):
653
663
def __init__ (self , plugin , plugin_name , function , hook_impl_opts ):
654
664
self .function = function
0 commit comments