Skip to content

Commit aeb1f67

Browse files
author
goodboy
authored
Merge pull request #143 from tgoodlet/deprecate_proc_arg
Deprecate `proc` kwarg to call_historic()
2 parents 88fe9b9 + 0faf6cb commit aeb1f67

File tree

3 files changed

+56
-14
lines changed

3 files changed

+56
-14
lines changed

docs/index.rst

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -749,20 +749,33 @@ using the :py:meth:`pluggy._HookCaller.call_historic()` method:
749749

750750
.. code-block:: python
751751
752+
def callback(result):
753+
print("historic call result is {result}".format(result=result))
754+
752755
# call with history; no results returned
753-
pm.hook.myhook.call_historic(config=config, args=sys.argv)
756+
pm.hook.myhook.call_historic(
757+
config=config, args=sys.argv,
758+
result_callback=callback
759+
)
754760
755761
# ... more of our program ...
756762
757763
# late loading of some plugin
758764
import mylateplugin
759765
760-
# historic call back is done here
766+
# historic callback is invoked here
761767
pm.register(mylateplugin)
762768
763769
Note that if you ``call_historic()`` the ``_HookCaller`` (and thus your
764770
calling code) can not receive results back from the underlying *hookimpl*
765-
functions.
771+
functions. Instead you can provide a *callback* for processing results
772+
(like the ``callback`` function above) which will be called as each
773+
new plugin is registered.
774+
775+
.. note::
776+
*historic* calls are incompatible with :ref:`firstresult` marked
777+
hooks since only the first registered plugin's hook(s) would
778+
ever be called.
766779

767780
Calling with extras
768781
-------------------

pluggy/hooks.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -257,20 +257,32 @@ def __call__(self, *args, **kwargs):
257257
)
258258
return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
259259

260-
def call_historic(self, proc=None, kwargs=None):
261-
""" call the hook with given ``kwargs`` for all registered plugins and
260+
def call_historic(self, result_callback=None, kwargs=None, proc=None):
261+
"""Call the hook with given ``kwargs`` for all registered plugins and
262262
for all plugins which will be registered afterwards.
263263
264-
If ``proc`` is not None it will be called for for each non-None result
265-
obtained from a hook implementation.
264+
If ``result_callback`` is not ``None`` it will be called for for each
265+
non-None result obtained from a hook implementation.
266+
267+
.. note::
268+
The ``proc`` argument is now deprecated.
266269
"""
267-
self._call_history.append((kwargs or {}, proc))
270+
if proc is not None:
271+
warnings.warn(
272+
"Support for `proc` argument is now deprecated and will be"
273+
"removed in an upcoming release.",
274+
DeprecationWarning
275+
)
276+
result_callback = proc
277+
278+
self._call_history.append((kwargs or {}, result_callback))
268279
# historizing hooks don't return results
269280
res = self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
270-
if proc is None:
281+
if result_callback is None:
271282
return
283+
# XXX: remember firstresult isn't compat with historic
272284
for x in res or []:
273-
proc(x)
285+
result_callback(x)
274286

275287
def call_extra(self, methods, kwargs):
276288
""" Call the hook with some additional temporarily participating
@@ -289,10 +301,10 @@ def _maybe_apply_history(self, method):
289301
"""Apply call history to a new hookimpl if it is marked as historic.
290302
"""
291303
if self.is_historic():
292-
for kwargs, proc in self._call_history:
304+
for kwargs, result_callback in self._call_history:
293305
res = self._hookexec(self, [method], kwargs)
294-
if res and proc is not None:
295-
proc(res[0])
306+
if res and result_callback is not None:
307+
result_callback(res[0])
296308

297309

298310
class HookImpl(object):

testing/test_pluginmanager.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ def he_method1(self, arg):
217217
pm.register(Plugin1())
218218

219219
he_method1 = pm.hook.he_method1
220-
he_method1.call_historic(proc=callback, kwargs=dict(arg=1))
220+
he_method1.call_historic(result_callback=callback, kwargs=dict(arg=1))
221221

222222
class Plugin2(object):
223223
@hookimpl
@@ -399,3 +399,20 @@ def example_hook():
399399
assert getattr(pm.hook, 'example_hook', None) # conftest.example_hook should be collected
400400
assert pm.parse_hookimpl_opts(conftest, 'example_blah') is None
401401
assert pm.parse_hookimpl_opts(conftest, 'example_hook') == {}
402+
403+
404+
def test_callhistoric_proc_deprecated(pm):
405+
"""``proc`` kwarg to `PluginMananger.call_historic()` is now officially
406+
deprecated.
407+
"""
408+
class P1(object):
409+
@hookspec(historic=True)
410+
@hookimpl
411+
def m(self, x):
412+
pass
413+
414+
p1 = P1()
415+
pm.add_hookspecs(p1)
416+
pm.register(p1)
417+
with pytest.deprecated_call():
418+
pm.hook.m.call_historic(kwargs=dict(x=10), proc=lambda res: res)

0 commit comments

Comments
 (0)