Skip to content

Commit 550f4b2

Browse files
author
Tyler Goodlet
committed
Remove spec_opts from muli-callers
Multi-call loop(s) should not care about spec opts - only whether or not the first result should be returned. Fix issue where a collected but unmarked hook not having `_HookCaller.spec_opts` defined results in an attr error. Resolves #99
1 parent f335bb5 commit 550f4b2

File tree

2 files changed

+14
-14
lines changed

2 files changed

+14
-14
lines changed

pluggy/__init__.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ def __init__(self, project_name, implprefix=None):
212212
self._implprefix = implprefix
213213
self._inner_hookexec = lambda hook, methods, kwargs: \
214214
hook.multicall(
215-
methods, kwargs, specopts=hook.spec_opts, hook=hook
215+
methods, kwargs,
216+
firstresult=hook.spec_opts.get('firstresult'),
216217
)
217218

218219
def _hookexec(self, hook, methods, kwargs):
@@ -528,20 +529,22 @@ def __init__(self, trace):
528529

529530

530531
class _HookCaller(object):
531-
def __init__(self, name, hook_execute, specmodule_or_class=None, spec_opts=None):
532+
def __init__(self, name, hook_execute, specmodule_or_class=None,
533+
spec_opts=None):
532534
self.name = name
533535
self._wrappers = []
534536
self._nonwrappers = []
535537
self._hookexec = hook_execute
538+
self._specmodule_or_class = None
536539
self.argnames = None
537540
self.kwargnames = None
538541
self.multicall = _multicall
542+
self.spec_opts = spec_opts or {}
539543
if specmodule_or_class is not None:
540-
assert spec_opts is not None
541544
self.set_specification(specmodule_or_class, spec_opts)
542545

543546
def has_spec(self):
544-
return hasattr(self, "_specmodule_or_class")
547+
return self._specmodule_or_class is not None
545548

546549
def set_specification(self, specmodule_or_class, spec_opts):
547550
assert not self.has_spec()
@@ -550,7 +553,7 @@ def set_specification(self, specmodule_or_class, spec_opts):
550553
# get spec arg signature
551554
argnames, self.kwargnames = varnames(specfunc)
552555
self.argnames = ["__multicall__"] + list(argnames)
553-
self.spec_opts = spec_opts
556+
self.spec_opts.update(spec_opts)
554557
if spec_opts.get("historic"):
555558
self._call_history = []
556559

pluggy/callers.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -105,17 +105,16 @@ class _LegacyMultiCall(object):
105105
# so we can remove it soon, allowing to avoid the below recursion
106106
# in execute() and simplify/speed up the execute loop.
107107

108-
def __init__(self, hook_impls, kwargs, specopts={}, hook=None):
109-
self.hook = hook
108+
def __init__(self, hook_impls, kwargs, firstresult=False):
110109
self.hook_impls = hook_impls
111110
self.caller_kwargs = kwargs # come from _HookCaller.__call__()
112111
self.caller_kwargs["__multicall__"] = self
113-
self.specopts = hook.spec_opts if hook else specopts
112+
self.firstresult = firstresult
114113

115114
def execute(self):
116115
caller_kwargs = self.caller_kwargs
117116
self.results = results = []
118-
firstresult = self.specopts.get("firstresult")
117+
firstresult = self.firstresult
119118

120119
while self.hook_impls:
121120
hook_impl = self.hook_impls.pop()
@@ -144,21 +143,19 @@ def __repr__(self):
144143
return "<_MultiCall %s, kwargs=%r>" % (status, self.caller_kwargs)
145144

146145

147-
def _legacymulticall(hook_impls, caller_kwargs, specopts={}, hook=None):
146+
def _legacymulticall(hook_impls, caller_kwargs, firstresult=False):
148147
return _LegacyMultiCall(
149-
hook_impls, caller_kwargs, specopts=specopts, hook=hook).execute()
148+
hook_impls, caller_kwargs, firstresult=firstresult).execute()
150149

151150

152-
def _multicall(hook_impls, caller_kwargs, specopts={}, hook=None):
151+
def _multicall(hook_impls, caller_kwargs, firstresult=False):
153152
"""Execute a call into multiple python functions/methods and return the
154153
result(s).
155154
156155
``caller_kwargs`` comes from _HookCaller.__call__().
157156
"""
158157
__tracebackhide__ = True
159-
specopts = hook.spec_opts if hook else specopts
160158
results = []
161-
firstresult = specopts.get("firstresult")
162159
excinfo = None
163160
try: # run impl and wrapper setup functions in a loop
164161
teardowns = []

0 commit comments

Comments
 (0)