Skip to content

Commit e98b20c

Browse files
author
Tyler Goodlet
committed
Initial docs draft
Covers everything in the original pluggy.py module's doc string in much more detail with links to external resources as seemed fit. Resolves #14
1 parent 5182582 commit e98b20c

File tree

6 files changed

+659
-17
lines changed

6 files changed

+659
-17
lines changed

docs/api_reference.rst

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
2-
31
Api Reference
42
=============
53

64
.. automodule:: pluggy
75
:members:
86
:undoc-members:
97
:show-inheritance:
10-
11-

docs/calling.rst

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
Calling Hooks
2+
=============
3+
The core functionality of ``pluggy`` enables an extension provider
4+
to override function calls made at certain points throughout a program.
5+
6+
A particular *hook* is invoked by calling an instance of
7+
a :py:class:`pluggy._HookCaller` which in turn *loops* through the
8+
``1:N`` registered *hookimpls* and calls them in sequence.
9+
10+
Every :py:class:`pluggy.PluginManager` has a ``hook`` attribute
11+
which is an instance of a :py:class:`pluggy._HookRelay`.
12+
The ``_HookRelay`` itself contains references (by hook name) to each
13+
registered *hookimpl*'s ``_HookCaller`` instance.
14+
15+
More practically you call a *hook* like so:
16+
17+
.. code-block:: python
18+
19+
import sys
20+
import pluggy
21+
import mypluginspec
22+
import myplugin
23+
from configuration import config
24+
25+
pm = pluggy.PluginManager("myproject")
26+
pm.add_hookspecs(mypluginspec)
27+
pm.register(myplugin)
28+
29+
# we invoke the _HookCaller and thus all underlying hookimpls
30+
result_list = pm.hook.myhook(config=config, args=sys.argv)
31+
32+
Note that you **must** call hooks using keyword `arguments`_ syntax!
33+
34+
35+
Collecting results
36+
------------------
37+
By default calling a hook results in all underlying :ref:`hookimpls
38+
<impls>` functions to be invoked in sequence via a loop. Any function
39+
which returns a value other then a ``None`` result will have that result
40+
appended to a :py:class:`list` which is returned by the call.
41+
42+
The only exception to this behaviour is if the hook has been marked to return
43+
its :ref:`firstresult` in which case only the first single value (which is not
44+
``None``) will be returned.
45+
46+
.. _call_historic:
47+
48+
Historic calls
49+
--------------
50+
A *historic call* allows for all newly registered functions to receive all hook
51+
calls that happened before their registration. The implication is that this is
52+
only useful if you expect that some *hookimpls* may be registered **after** the
53+
hook is initially invoked.
54+
55+
Historic hooks must be :ref:`specially marked <historic>` and called
56+
using the :py:meth:`pluggy._HookCaller.call_historic()` method:
57+
58+
.. code-block:: python
59+
60+
# call with history; no results returned
61+
pm.hook.myhook.call_historic(config=config, args=sys.argv)
62+
63+
# ... more of our program ...
64+
65+
# late loading of some plugin
66+
import mylateplugin
67+
68+
# historic call back is done here
69+
pm.register(mylateplugin)
70+
71+
Note that if you ``call_historic()`` the ``_HookCaller`` (and thus your
72+
calling code) can not receive results back from the underlying *hookimpl*
73+
functions.
74+
75+
Calling with extras
76+
-------------------
77+
You can call a hook with temporarily participating *implementation* functions
78+
(that aren't in the registry) using the
79+
:py:meth:`pluggy._HookCaller.call_extra()` method.
80+
81+
82+
Calling with a subset of registered plugins
83+
-------------------------------------------
84+
You can make a call using a subset of plugins by asking the
85+
``PluginManager`` first for a ``_HookCaller`` with those plugins removed
86+
using the :py:meth:`pluggy.PluginManger.subset_hook_caller()` method.
87+
88+
You then can use that ``_HookCaller`` to make normal, ``call_historic()``,
89+
or ``call_extra()`` calls as necessary.
90+
91+
92+
.. links
93+
.. _arguments:
94+
https://docs.python.org/3/glossary.html#term-argument

0 commit comments

Comments
 (0)