Skip to content

Commit 93a68cd

Browse files
committed
doc(plugin_hooks): Improve documentation for writing plugin hooks.
1 parent 3c9b46f commit 93a68cd

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

changelog/5517.doc.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve "Declaring new hooks" section in chapter "Writing Plugins"

doc/en/writing_plugins.rst

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,12 +621,60 @@ the new plugin:
621621

622622
Hooks are usually declared as do-nothing functions that contain only
623623
documentation describing when the hook will be called and what return values
624-
are expected.
624+
are expected. The names of the functions must start with `pytest_` otherwise pytest won't recognize them.
625625

626-
For an example, see `newhooks.py`_ from `xdist <https://github.com/pytest-dev/pytest-xdist>`_.
626+
Here's an example. Let's assume this code is in the ``hooks.py`` module.
627+
628+
.. code-block:: python
629+
630+
def pytest_my_hook(config):
631+
"""
632+
Receives the pytest config and does things with it
633+
"""
634+
635+
To register the hooks with pytest they need to be structured in their own module or class. This
636+
class or module can then be passed to the ``pluginmanager`` using the ``pytest_addhooks`` function
637+
(which itself is a hook exposed by pytest).
638+
639+
.. code-block:: python
640+
641+
def pytest_addhooks(pluginmanager):
642+
""" This example assumes the hooks are grouped in the 'hooks' module. """
643+
from my_app.tests import hooks
644+
pluginmanager.add_hookspecs(hooks)
645+
646+
For a real world example, see `newhooks.py`_ from `xdist <https://github.com/pytest-dev/pytest-xdist>`_.
627647

628648
.. _`newhooks.py`: https://github.com/pytest-dev/pytest-xdist/blob/974bd566c599dc6a9ea291838c6f226197208b46/xdist/newhooks.py
629649

650+
Hooks may be called both from fixtures or from other hooks. In both cases, hooks are called
651+
through the ``hook`` object, available in the ``config`` object. Most hooks receive a
652+
``config`` object directly, while fixtures may use the ``pytestconfig`` fixture which provides the same object.
653+
654+
.. code-block:: python
655+
656+
@pytest.fixture()
657+
def my_fixture(pytestconfig):
658+
# call the hook called "pytest_my_hook"
659+
# `result` will be a list of return values from all registered functions.
660+
result = pytestconfig.hook.pytest_my_hook(config=pytestconfig)
661+
662+
.. note::
663+
Hooks receive parameters using only keyword arguments.
664+
665+
Now your hook is ready to be used. To register a function at the hook, other plugins or users must
666+
now simply define the function ``pytest_my_hook`` with the correct signature in their ``conftest.py``.
667+
668+
Example:
669+
670+
.. code-block:: python
671+
672+
def pytest_my_hook(config):
673+
"""
674+
Print all active hooks to the screen.
675+
"""
676+
print(config.hook)
677+
630678
631679
Optionally using hooks from 3rd party plugins
632680
---------------------------------------------

0 commit comments

Comments
 (0)