|
1 | 1 | import inspect
|
2 | 2 | import warnings
|
3 |
| -from .callers import _multicall, HookCallError, _Result, _legacymulticall |
| 3 | +from .callers import ( |
| 4 | + _multicall, _itercall, HookCallError, _Result, _legacymulticall) |
4 | 5 |
|
5 | 6 | __version__ = '0.5.3.dev'
|
6 | 7 |
|
@@ -209,6 +210,8 @@ def __init__(self, project_name, implprefix=None):
|
209 | 210 | self._plugin_distinfo = []
|
210 | 211 | self.trace = _TagTracer().get("pluginmanage")
|
211 | 212 | self.hook = _HookRelay(self.trace.root.get("hook"))
|
| 213 | + # alternative set of lazily executed hook calls |
| 214 | + self.ihook = _HookRelay(self.trace.root.get("hook")) |
212 | 215 | self._implprefix = implprefix
|
213 | 216 | self._inner_hookexec = lambda hook, methods, kwargs: \
|
214 | 217 | hook.multicall(
|
@@ -246,14 +249,25 @@ def register(self, plugin, name=None):
|
246 | 249 | method = getattr(plugin, name)
|
247 | 250 | hookimpl = HookImpl(plugin, plugin_name, method, hookimpl_opts)
|
248 | 251 | hook = getattr(self.hook, name, None)
|
| 252 | + ihook = getattr(self.ihook, name, None) |
| 253 | + |
249 | 254 | if hook is None:
|
250 | 255 | hook = _HookCaller(name, self._hookexec)
|
| 256 | + ihook = _HookCaller(name, self._hookexec, iterate=True) |
251 | 257 | setattr(self.hook, name, hook)
|
| 258 | + setattr(self.ihook, name, ihook) |
| 259 | + |
252 | 260 | elif hook.has_spec():
|
253 | 261 | self._verify_hook(hook, hookimpl)
|
254 | 262 | hook._maybe_apply_history(hookimpl)
|
| 263 | + |
| 264 | + self._verify_hook(ihook, hookimpl) |
| 265 | + ihook._maybe_apply_history(hookimpl) |
| 266 | + |
255 | 267 | hook._add_hookimpl(hookimpl)
|
| 268 | + ihook._add_hookimpl(hookimpl) |
256 | 269 | hookcallers.append(hook)
|
| 270 | + hookcallers.append(ihook) |
257 | 271 | return plugin_name
|
258 | 272 |
|
259 | 273 | def parse_hookimpl_opts(self, plugin, name):
|
@@ -307,14 +321,19 @@ def add_hookspecs(self, module_or_class):
|
307 | 321 | spec_opts = self.parse_hookspec_opts(module_or_class, name)
|
308 | 322 | if spec_opts is not None:
|
309 | 323 | hc = getattr(self.hook, name, None)
|
| 324 | + hi = getattr(self.ihook, name, None) |
310 | 325 | if hc is None:
|
311 | 326 | hc = _HookCaller(name, self._hookexec, module_or_class, spec_opts)
|
312 | 327 | setattr(self.hook, name, hc)
|
| 328 | + hi = _HookCaller(name, self._hookexec, module_or_class, |
| 329 | + spec_opts, iterate=True) |
| 330 | + setattr(self.ihook, name, hi) |
313 | 331 | else:
|
314 | 332 | # plugins registered this hook without knowing the spec
|
315 |
| - hc.set_specification(module_or_class, spec_opts) |
316 |
| - for hookfunction in (hc._wrappers + hc._nonwrappers): |
317 |
| - self._verify_hook(hc, hookfunction) |
| 333 | + for h in [hc, hi]: |
| 334 | + h.set_specification(module_or_class, spec_opts) |
| 335 | + for hookfunction in (h._wrappers + h._nonwrappers): |
| 336 | + self._verify_hook(h, hookfunction) |
318 | 337 | names.append(name)
|
319 | 338 |
|
320 | 339 | if not names:
|
@@ -529,16 +548,16 @@ def __init__(self, trace):
|
529 | 548 |
|
530 | 549 |
|
531 | 550 | class _HookCaller(object):
|
532 |
| - def __init__(self, name, hook_execute, specmodule_or_class=None, |
533 |
| - spec_opts=None): |
| 551 | + def __init__(self, name, hook_execute, specmodule_or_class=None, spec_opts=None, |
| 552 | + iterate=False): |
534 | 553 | self.name = name
|
535 | 554 | self._wrappers = []
|
536 | 555 | self._nonwrappers = []
|
537 | 556 | self._hookexec = hook_execute
|
538 | 557 | self._specmodule_or_class = None
|
539 | 558 | self.argnames = None
|
540 | 559 | self.kwargnames = None
|
541 |
| - self.multicall = _multicall |
| 560 | + self.multicall = _multicall if not iterate else _itercall |
542 | 561 | self.spec_opts = spec_opts or {}
|
543 | 562 | if specmodule_or_class is not None:
|
544 | 563 | self.set_specification(specmodule_or_class, spec_opts)
|
|
0 commit comments