|
4 | 4 | The five minute elevator pitch
|
5 | 5 | ******************************
|
6 | 6 |
|
7 |
| -``pluggy`` gives `users` the possibility to extend or modify the behaviour of a program like e.g. `pytest`_, `tox`_ or `devpi`_ by installing a `plugin` for that program. The plugin code will run as part of normal program execution changing or enhancing certain aspects of it. |
| 7 | +``pluggy`` gives `users` the possibility to extend or modify the behaviour of |
| 8 | +a program like e.g. `pytest`_, `tox`_ or `devpi`_ by installing a `plugin` for |
| 9 | +that program. The plugin code will run as part of normal program execution |
| 10 | +changing or enhancing certain aspects of it. |
8 | 11 |
|
9 | 12 | There are three roles in which people might interact with ``pluggy``.
|
10 | 13 |
|
11 | 14 | Publisher
|
12 | 15 | +++++++++
|
13 | 16 |
|
14 |
| -The `publisher` wants to enable an arbitrary number of `subscribers` to extend or modify some aspects of their programs execution. They write hook specifications, register them with a :py:class:`pluggy.PluginManager` and instantiate a marker object for the `subscriber` - a :py:class:`~pluggy.HookimplMarker` - used to `decorate <https://www.python.org/dev/peps/pep-0318/#current-syntax>` hook implementation functions. This marker is usually called `hookimpl` and importable from the root package of the `publisher` project. They then add calls to their specified hooks in appropriate phases of program execution. ``pluggy`` will then do all the magic. |
15 |
| - |
16 |
| -**FIXME not sure what is the right advice here. Do I need to vendor in pluggy as a publisher to avoid versioning conflicts? Should I just depend on pluggy without version and hope all is good?** To avoid compatibility issues they should always pin their ``pluggy`` version to the minor version used at implementation time (at the time of writing (spring 2018) ``pluggy`` is not at 1.0 yet, so breaking changes should be expected with any minor release). |
17 |
| - |
18 |
| -They need to learn about ``pluggy`` and its capabilities and should at least loosely follow the development of the ``pluggy`` project. |
| 17 | +The `publisher` wants to enable an arbitrary number of `subscribers` to extend |
| 18 | +or modify some aspects of their programs execution. They write hook specifications, |
| 19 | +register them with a :py:class:`pluggy.PluginManager` and instantiate a marker |
| 20 | +object for the `subscriber` - a :py:class:`~pluggy.HookimplMarker` - used |
| 21 | +to `decorate <https://www.python.org/dev/peps/pep-0318/#current-syntax>` hook |
| 22 | +implementation functions. This marker is usually called `hookimpl` and |
| 23 | +importable from the root package of the `publisher` project. They then add |
| 24 | +calls to their specified hooks in appropriate phases of program execution. |
| 25 | +``pluggy`` will then do all the magic. |
| 26 | + |
| 27 | +**FIXME not sure what is the right advice here. Do I need to vendor in pluggy as a publisher to avoid versioning conflicts? Should I just depend on pluggy without version and hope all is good?** |
| 28 | +To avoid compatibility issues they should always pin their ``pluggy`` version |
| 29 | +to the minor version used at implementation time (at the time of writing |
| 30 | +(spring 2018) ``pluggy`` is not at 1.0 yet, so breaking changes should be |
| 31 | +expected with any minor release). |
| 32 | + |
| 33 | +They need to learn about ``pluggy`` and its capabilities and should at least |
| 34 | +loosely follow the development of the ``pluggy`` project. |
19 | 35 |
|
20 | 36 | Subscriber
|
21 | 37 | ++++++++++
|
22 | 38 |
|
23 |
| -The `subscriber` wants to modify or extend the program execution of a `publisher` project. They install the project and import it wherever they want to use the `hookimpl` marker. They create one or more hook implementation functions matching the exact name of the `publisher` `hookspec` functions and decorate them with `@<publisher>.<hookimpl>`. They only need to declare the subset of parameters they actually use in their hook implementation. To make their plugin discoverable by the `publisher` they define an `entry point <https://packaging.python.org/specifications/entry-points/>`_ in their `setup.py <https://docs.python.org/3.6/distutils/setupscript.html>`_ (defined by the publisher (e.g. `pytest11`, `tox` or `devpi_server`). The result of this is called a plugin for a certain project. The plugin project naming rule is `<publisher>-<subscriber>` (e.g. `pytest-sugar`, `tox-conda` or `devpi-ldap`). |
24 |
| - |
25 |
| -Depending on how involved the modifications are, they need to learn about how the `publisher` project works and about the parameters the hook functions provide. They also might have to learn a bit more about how ``pluggy`` executes hooks regarding ordering and other behavioral details. |
| 39 | +The `subscriber` wants to modify or extend the program execution of a |
| 40 | +`publisher` project. They install the project and import it wherever they want |
| 41 | +to use the `hookimpl` marker. They create one or more hook implementation functions |
| 42 | +matching the exact name of the `publisher` `hookspec` functions and decorate |
| 43 | +them with `@<publisher>.<hookimpl>`. They only need to declare the subset of |
| 44 | +parameters they actually use in their hook implementation. To make their plugin |
| 45 | +discoverable by the `publisher` they define an |
| 46 | +`entry point <https://packaging.python.org/specifications/entry-points/>`_ in |
| 47 | +their `setup.py <https://docs.python.org/3.6/distutils/setupscript.html>`_ |
| 48 | +(defined by the publisher (e.g. `pytest11`, `tox` or `devpi_server`). The result |
| 49 | +of this is called a plugin for a certain project. The plugin project naming rule |
| 50 | +is `<publisher>-<subscriber>` (e.g. `pytest-sugar`, `tox-conda` or `devpi-ldap`). |
| 51 | + |
| 52 | +Depending on how involved the modifications are, they need to learn about how |
| 53 | +the `publisher` project works and about the parameters the hook functions provide. |
| 54 | +They also might have to learn a bit more about how ``pluggy`` executes hooks |
| 55 | +regarding ordering and other behavioral details. |
26 | 56 |
|
27 | 57 | User
|
28 | 58 | ++++
|
29 | 59 |
|
30 |
| -The `user` wants to use new or changed features made available by `subscribers` as so-called `plugins` for a `publisher` project. They install the `publisher` project and the `plugin` they want to use. Through the magic of entry points the `publisher` will discover the `plugin` hooks and start calling them as part of their normal program execution. |
| 60 | +The `user` wants to use new or changed features made available by `subscribers` |
| 61 | +as so-called `plugins` for a `publisher` project. They install the `publisher` |
| 62 | +project and the `plugin` they want to use. Through the magic of entry points |
| 63 | +the `publisher` will discover the `plugin` hooks and start calling them as part |
| 64 | +of their normal program execution. |
31 | 65 |
|
32 |
| -If a `user` doesn't need the changed behaviour of a `plugin` anymore, they uninstall it and all is back to normal. |
| 66 | +If a `user` doesn't need the changed behaviour of a `plugin` anymore, they |
| 67 | +uninstall it and all is back to normal. |
33 | 68 |
|
34 | 69 | `Users` don't need to know that the mechanism making this possible is provided by ``pluggy``.
|
35 | 70 |
|
|
0 commit comments