|
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(
|
@@ -245,14 +248,25 @@ def register(self, plugin, name=None):
|
245 | 248 | method = getattr(plugin, name)
|
246 | 249 | hookimpl = HookImpl(plugin, plugin_name, method, hookimpl_opts)
|
247 | 250 | hook = getattr(self.hook, name, None)
|
| 251 | + ihook = getattr(self.ihook, name, None) |
| 252 | + |
248 | 253 | if hook is None:
|
249 | 254 | hook = _HookCaller(name, self._hookexec)
|
| 255 | + ihook = _HookCaller(name, self._hookexec, iterate=True) |
250 | 256 | setattr(self.hook, name, hook)
|
| 257 | + setattr(self.ihook, name, ihook) |
| 258 | + |
251 | 259 | elif hook.has_spec():
|
252 | 260 | self._verify_hook(hook, hookimpl)
|
253 | 261 | hook._maybe_apply_history(hookimpl)
|
| 262 | + |
| 263 | + self._verify_hook(ihook, hookimpl) |
| 264 | + ihook._maybe_apply_history(hookimpl) |
| 265 | + |
254 | 266 | hook._add_hookimpl(hookimpl)
|
| 267 | + ihook._add_hookimpl(hookimpl) |
255 | 268 | hookcallers.append(hook)
|
| 269 | + hookcallers.append(ihook) |
256 | 270 | return plugin_name
|
257 | 271 |
|
258 | 272 | def parse_hookimpl_opts(self, plugin, name):
|
@@ -306,14 +320,19 @@ def add_hookspecs(self, module_or_class):
|
306 | 320 | spec_opts = self.parse_hookspec_opts(module_or_class, name)
|
307 | 321 | if spec_opts is not None:
|
308 | 322 | hc = getattr(self.hook, name, None)
|
| 323 | + hi = getattr(self.ihook, name, None) |
309 | 324 | if hc is None:
|
310 | 325 | hc = _HookCaller(name, self._hookexec, module_or_class, spec_opts)
|
311 | 326 | setattr(self.hook, name, hc)
|
| 327 | + hi = _HookCaller(name, self._hookexec, module_or_class, |
| 328 | + spec_opts, iterate=True) |
| 329 | + setattr(self.ihook, name, hi) |
312 | 330 | else:
|
313 | 331 | # plugins registered this hook without knowing the spec
|
314 |
| - hc.set_specification(module_or_class, spec_opts) |
315 |
| - for hookfunction in (hc._wrappers + hc._nonwrappers): |
316 |
| - self._verify_hook(hc, hookfunction) |
| 332 | + for h in [hc, hi]: |
| 333 | + h.set_specification(module_or_class, spec_opts) |
| 334 | + for hookfunction in (h._wrappers + h._nonwrappers): |
| 335 | + self._verify_hook(h, hookfunction) |
317 | 336 | names.append(name)
|
318 | 337 |
|
319 | 338 | if not names:
|
@@ -528,14 +547,15 @@ def __init__(self, trace):
|
528 | 547 |
|
529 | 548 |
|
530 | 549 | class _HookCaller(object):
|
531 |
| - def __init__(self, name, hook_execute, specmodule_or_class=None, spec_opts=None): |
| 550 | + def __init__(self, name, hook_execute, specmodule_or_class=None, spec_opts=None, |
| 551 | + iterate=False): |
532 | 552 | self.name = name
|
533 | 553 | self._wrappers = []
|
534 | 554 | self._nonwrappers = []
|
535 | 555 | self._hookexec = hook_execute
|
536 | 556 | self.argnames = None
|
537 | 557 | self.kwargnames = None
|
538 |
| - self.multicall = _multicall |
| 558 | + self.multicall = _multicall if not iterate else _itercall |
539 | 559 | if specmodule_or_class is not None:
|
540 | 560 | assert spec_opts is not None
|
541 | 561 | self.set_specification(specmodule_or_class, spec_opts)
|
|
0 commit comments