summaryrefslogtreecommitdiff
path: root/README.rst
blob: 3496617e1e8796b256cdfbf16e0e68b5d4d22a77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
====================================================
pluggy - A minimalist production ready plugin system
====================================================

|pypi| |conda-forge| |versions| |github-actions| |gitter| |black| |codecov|

This is the core framework used by the `pytest`_, `tox`_, and `devpi`_ projects.

Please `read the docs`_ to learn more!

A definitive example
====================
.. code-block:: python

    import pluggy

    hookspec = pluggy.HookspecMarker("myproject")
    hookimpl = pluggy.HookimplMarker("myproject")


    class MySpec:
        """A hook specification namespace."""

        @hookspec
        def myhook(self, arg1, arg2):
            """My special little hook that you can customize."""


    class Plugin_1:
        """A hook implementation namespace."""

        @hookimpl
        def myhook(self, arg1, arg2):
            print("inside Plugin_1.myhook()")
            return arg1 + arg2


    class Plugin_2:
        """A 2nd hook implementation namespace."""

        @hookimpl
        def myhook(self, arg1, arg2):
            print("inside Plugin_2.myhook()")
            return arg1 - arg2


    # create a manager and add the spec
    pm = pluggy.PluginManager("myproject")
    pm.add_hookspecs(MySpec)

    # register plugins
    pm.register(Plugin_1())
    pm.register(Plugin_2())

    # call our ``myhook`` hook
    results = pm.hook.myhook(arg1=1, arg2=2)
    print(results)


Running this directly gets us::

    $ python docs/examples/toy-example.py
    inside Plugin_2.myhook()
    inside Plugin_1.myhook()
    [-1, 3]


.. badges

.. |pypi| image:: https://img.shields.io/pypi/v/pluggy.svg
    :target: https://pypi.org/pypi/pluggy

.. |versions| image:: https://img.shields.io/pypi/pyversions/pluggy.svg
    :target: https://pypi.org/pypi/pluggy

.. |github-actions| image:: https://github.com/pytest-dev/pluggy/workflows/main/badge.svg
    :target: https://github.com/pytest-dev/pluggy/actions

.. |conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pluggy.svg
    :target: https://anaconda.org/conda-forge/pytest

.. |gitter| image:: https://badges.gitter.im/pytest-dev/pluggy.svg
    :alt: Join the chat at https://gitter.im/pytest-dev/pluggy
    :target: https://gitter.im/pytest-dev/pluggy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge

.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg
    :target: https://github.com/ambv/black

.. |codecov| image:: https://codecov.io/gh/pytest-dev/pluggy/branch/master/graph/badge.svg
    :target: https://codecov.io/gh/pytest-dev/pluggy
    :alt: Code coverage Status

.. links
.. _pytest:
    http://pytest.org
.. _tox:
    https://tox.readthedocs.org
.. _devpi:
    http://doc.devpi.net
.. _read the docs:
   https://pluggy.readthedocs.io/en/latest/