Hello community, here is the log from the commit of package python-pluggy for openSUSE:Factory checked in at 2020-01-16 18:13:24 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pluggy (Old) and /work/SRC/openSUSE:Factory/.python-pluggy.new.26092 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pluggy" Thu Jan 16 18:13:24 2020 rev:15 rq:761138 version:0.13.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pluggy/python-pluggy.changes 2019-12-16 17:26:20.975960615 +0100 +++ /work/SRC/openSUSE:Factory/.python-pluggy.new.26092/python-pluggy.changes 2020-01-16 18:13:28.836711434 +0100 @@ -1,0 +2,6 @@ +Mon Jan 6 12:52:03 UTC 2020 - Tomáš Chvátal <[email protected]> + +- Update to 0.13.1: + * Improved documentation, especially with regard to references. + +------------------------------------------------------------------- Old: ---- pluggy-0.13.0.tar.gz New: ---- pluggy-0.13.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pluggy.spec ++++++ --- /var/tmp/diff_new_pack.8UP0rs/_old 2020-01-16 18:13:29.552711839 +0100 +++ /var/tmp/diff_new_pack.8UP0rs/_new 2020-01-16 18:13:29.556711842 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-pluggy # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -26,11 +26,10 @@ %bcond_with test %endif Name: python-pluggy%{psuffix} -Version: 0.13.0 +Version: 0.13.1 Release: 0 Summary: Plugin registration and hook calling mechanisms for Python License: MIT -Group: Development/Languages/Python URL: https://github.com/pytest-dev/pluggy Source: https://files.pythonhosted.org/packages/source/p/pluggy/pluggy-%{version}.tar.gz BuildRequires: %{python_module setuptools_scm} ++++++ pluggy-0.13.0.tar.gz -> pluggy-0.13.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pluggy-0.13.0/CHANGELOG.rst new/pluggy-0.13.1/CHANGELOG.rst --- old/pluggy-0.13.0/CHANGELOG.rst 2019-09-10 22:14:28.000000000 +0200 +++ new/pluggy-0.13.1/CHANGELOG.rst 2019-11-21 21:41:58.000000000 +0100 @@ -4,6 +4,15 @@ .. towncrier release notes start +pluggy 0.13.1 (2019-11-21) +========================== + +Trivial/Internal Changes +------------------------ + +- `#236 <https://github.com/pytest-dev/pluggy/pull/236>`_: Improved documentation, especially with regard to references. + + pluggy 0.13.0 (2019-09-10) ========================== @@ -315,7 +324,7 @@ .. contributors .. _@hpk42: https://github.com/hpk42 -.. _@tgoodlet: https://github.com/tgoodlet +.. _@tgoodlet: https://github.com/goodboy .. _@MichalTHEDUDE: https://github.com/MichalTHEDUDE .. _@vodik: https://github.com/vodik .. _@RonnyPfannschmidt: https://github.com/RonnyPfannschmidt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pluggy-0.13.0/PKG-INFO new/pluggy-0.13.1/PKG-INFO --- old/pluggy-0.13.0/PKG-INFO 2019-09-10 22:14:47.000000000 +0200 +++ new/pluggy-0.13.1/PKG-INFO 2019-11-21 21:42:34.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pluggy -Version: 0.13.0 +Version: 0.13.1 Summary: plugin and hook calling mechanisms for python Home-page: https://github.com/pytest-dev/pluggy Author: Holger Krekel @@ -69,6 +69,14 @@ 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 @@ -114,6 +122,15 @@ .. towncrier release notes start + pluggy 0.13.1 (2019-11-21) + ========================== + + Trivial/Internal Changes + ------------------------ + + - `#236 <https://github.com/pytest-dev/pluggy/pull/236>`_: Improved documentation, especially with regard to references. + + pluggy 0.13.0 (2019-09-10) ========================== @@ -425,7 +442,7 @@ .. contributors .. _@hpk42: https://github.com/hpk42 - .. _@tgoodlet: https://github.com/tgoodlet + .. _@tgoodlet: https://github.com/goodboy .. _@MichalTHEDUDE: https://github.com/MichalTHEDUDE .. _@vodik: https://github.com/vodik .. _@RonnyPfannschmidt: https://github.com/RonnyPfannschmidt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pluggy-0.13.0/README.rst new/pluggy-0.13.1/README.rst --- old/pluggy-0.13.0/README.rst 2019-09-10 22:14:28.000000000 +0200 +++ new/pluggy-0.13.1/README.rst 2019-11-21 21:41:58.000000000 +0100 @@ -61,6 +61,14 @@ 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pluggy-0.13.0/docs/api_reference.rst new/pluggy-0.13.1/docs/api_reference.rst --- old/pluggy-0.13.0/docs/api_reference.rst 2019-09-10 22:14:28.000000000 +0200 +++ new/pluggy-0.13.1/docs/api_reference.rst 2019-11-21 21:41:58.000000000 +0100 @@ -8,9 +8,12 @@ :undoc-members: :show-inheritance: - +.. autoclass:: pluggy.callers._Result .. automethod:: pluggy.callers._Result.get_result - .. automethod:: pluggy.callers._Result.force_result +.. autoclass:: pluggy.hooks._HookCaller .. automethod:: pluggy.hooks._HookCaller.call_extra +.. automethod:: pluggy.hooks._HookCaller.call_historic + +.. autoclass:: pluggy.hooks._HookRelay diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pluggy-0.13.0/docs/conf.py new/pluggy-0.13.1/docs/conf.py --- old/pluggy-0.13.0/docs/conf.py 2019-09-10 22:14:28.000000000 +0200 +++ new/pluggy-0.13.1/docs/conf.py 2019-11-21 21:41:58.000000000 +0100 @@ -80,4 +80,10 @@ ] # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {"https://docs.python.org/": None} +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "pytest": ("https://docs.pytest.org/en/latest", None), + "setuptools": ("https://setuptools.readthedocs.io/en/latest", None), + "tox": ("https://tox.readthedocs.io/en/latest", None), + "devpi": ("https://devpi.net/docs/devpi/devpi/stable/+doc/", None), +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pluggy-0.13.0/docs/index.rst new/pluggy-0.13.1/docs/index.rst --- old/pluggy-0.13.0/docs/index.rst 2019-09-10 22:14:28.000000000 +0200 +++ new/pluggy-0.13.1/docs/index.rst 2019-11-21 21:41:58.000000000 +0100 @@ -4,11 +4,11 @@ What is it? *********** -``pluggy`` is the crystallized core of `plugin management and hook -calling`_ for `pytest`_. It enables `500+ plugins`_ to extend and customize -``pytest``'s default behaviour. Even ``pytest`` itself is composed -as a set of ``pluggy`` plugins which are invoked in sequence according to a -well defined set of protocols. +``pluggy`` is the crystallized core of :ref:`plugin management and hook +calling <pytest:writing-plugins>` for :std:doc:`pytest <pytest:index>`. +It enables `500+ plugins`_ to extend and customize ``pytest``'s default +behaviour. Even ``pytest`` itself is composed as a set of ``pluggy`` plugins +which are invoked in sequence according to a well defined set of protocols. It gives users the ability to extend or modify the behaviour of a ``host program`` by installing a ``plugin`` for that program. @@ -25,7 +25,7 @@ `method overriding <https://en.wikipedia.org/wiki/Method_overriding>`_ (e.g. Jinja2) or `monkey patching <https://en.wikipedia.org/wiki/Monkey_patch>`_ (e.g. gevent -or for `writing tests <https://docs.pytest.org/en/latest/monkeypatch.html>`_). +or for :std:doc:`writing tests <pytest:monkeypatch>`). These strategies become problematic though when several parties want to participate in the modification of the same program. Therefore ``pluggy`` does not rely on these mechanisms to enable a more structured approach and @@ -159,9 +159,9 @@ To see how ``pluggy`` is used in the real world, have a look at these projects documentation and source code: -* `pytest <https://docs.pytest.org/en/latest/writing_plugins.html>`__ -* `tox <https://tox.readthedocs.io/en/latest/plugins.html>`__ -* `devpi <https://devpi.net/docs/devpi/devpi/stable/+d/devguide/index.html>`__ +* :ref:`pytest <pytest:writing-plugins>` +* :std:doc:`tox <tox:plugins>` +* :std:doc:`devpi <devpi:devguide/index>` For more details and advanced usage please read on. @@ -169,14 +169,14 @@ Define and collect hooks ************************ -A *plugin* is a namespace type (currently one of a ``class`` or module) -which defines a set of *hook* functions. +A *plugin* is a :ref:`namespace <python:tut-scopes>` type (currently one of a +``class`` or module) which defines a set of *hook* functions. As mentioned in :ref:`manage`, all *plugins* which specify *hooks* are managed by an instance of a :py:class:`pluggy.PluginManager` which defines the primary ``pluggy`` API. -In order for a ``PluginManager`` to detect functions in a namespace +In order for a :py:class:`~pluggy.PluginManager` to detect functions in a namespace intended to be *hooks*, they must be decorated using special ``pluggy`` *marks*. .. _marking_hooks: @@ -184,7 +184,8 @@ Marking hooks ------------- The :py:class:`~pluggy.HookspecMarker` and :py:class:`~pluggy.HookimplMarker` -decorators are used to *mark* functions for detection by a ``PluginManager``: +decorators are used to *mark* functions for detection by a +:py:class:`~pluggy.PluginManager`: .. code-block:: python @@ -196,12 +197,12 @@ Each decorator type takes a single ``project_name`` string as its lone argument the value of which is used to mark hooks for detection by -a similarly configured ``PluginManager`` instance. +a similarly configured :py:class:`~pluggy.PluginManager` instance. That is, a *mark* type called with ``project_name`` returns an object which can be used to decorate functions which will then be detected by a -``PluginManager`` which was instantiated with the same ``project_name`` -value. +:py:class:`~pluggy.PluginManager` which was instantiated with the same +``project_name`` value. Furthermore, each *hookimpl* or *hookspec* decorator can configure the underlying call-time behavior of each *hook* object by providing special @@ -210,8 +211,8 @@ .. note:: The following sections correspond to similar documentation in - ``pytest`` for `Writing hook functions`_ and can be used - as a supplementary resource. + ``pytest`` for :ref:`pytest:writinghooks` and can be used as + a supplementary resource. .. _impls: @@ -331,7 +332,7 @@ calls. A *hookwrapper* can thus execute some code ahead and after the execution of all corresponding non-wrappper *hookimpls*. -Much in the same way as a `@contextlib.contextmanager`_, *hookwrappers* must +Much in the same way as a :py:func:`@contextlib.contextmanager <python:contextlib.contextmanager>`, *hookwrappers* must be implemented as generator function with a single ``yield`` in its body: @@ -360,7 +361,7 @@ if config.use_defaults: outcome.force_result(defaults) -The generator is `sent`_ a :py:class:`pluggy.callers._Result` object which can +The generator is :py:meth:`sent <python:generator.send>` a :py:class:`pluggy.callers._Result` object which can be assigned in the ``yield`` expression and used to override or inspect the final result(s) returned back to the caller using the :py:meth:`~pluggy.callers._Result.force_result` or @@ -467,8 +468,8 @@ .. note:: The one exception to this rule (that a *hookspec* must have as least as - many arguments as its *hookimpls*) is the conventional `self`_ arg; this - is always ignored when *hookimpls* are defined as `methods`_. + many arguments as its *hookimpls*) is the conventional :ref:`self <python:tut-remarks>` arg; this + is always ignored when *hookimpls* are defined as :ref:`methods <python:tut-methodobjects>`. .. _firstresult: @@ -489,14 +490,14 @@ `pytest_cmdline_main`_ central routine of ``pytest``. Note that all ``hookwrappers`` are still invoked with the first result. -Also see the `first result`_ section in the ``pytest`` docs. +Also see the :ref:`pytest:firstresult` section in the ``pytest`` docs. .. _historic: Historic hooks ^^^^^^^^^^^^^^ You can mark a *hookspec* as being *historic* meaning that the hook -can be called with :py:meth:`~pluggy.PluginManager.call_historic()` **before** +can be called with :py:meth:`~pluggy.hooks._HookCaller.call_historic()` **before** having been registered: .. code-block:: python @@ -506,7 +507,7 @@ pass The implication is that late registered *hookimpls* will be called back -immediately at register time and **can not** return a result to the caller.** +immediately at register time and **can not** return a result to the caller. This turns out to be particularly useful when dealing with lazy or dynamically loaded plugins. @@ -537,7 +538,7 @@ ``pluggy`` manages plugins using instances of the :py:class:`pluggy.PluginManager`. -A ``PluginManager`` is instantiated with a single +A :py:class:`~pluggy.PluginManager` is instantiated with a single ``str`` argument, the ``project_name``: .. code-block:: python @@ -547,15 +548,15 @@ pm = pluggy.PluginManager("my_project_name") -The ``project_name`` value is used when a ``PluginManager`` scans for *hook* -functions :ref:`defined on a plugin <define>`. -This allows for multiple -plugin managers from multiple projects to define hooks alongside each other. +The ``project_name`` value is used when a :py:class:`~pluggy.PluginManager` +scans for *hook* functions :ref:`defined on a plugin <define>`. +This allows for multiple plugin managers from multiple projects +to define hooks alongside each other. Registration ------------ -Each ``PluginManager`` maintains a *plugin* registry where each *plugin* +Each :py:class:`~pluggy.PluginManager` maintains a *plugin* registry where each *plugin* contains a set of *hookimpl* definitions. Loading *hookimpl* and *hookspec* definitions to populate the registry is described in detail in the section on :ref:`define`. @@ -572,11 +573,12 @@ Loading ``setuptools`` entry points ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -You can automatically load plugins registered through `setuptools entry points`_ +You can automatically load plugins registered through +:ref:`setuptools entry points <setuptools:entry points>` with the :py:meth:`~pluggy.PluginManager.load_setuptools_entrypoints()` method. -An example use of this is the `pytest entry point`_. +An example use of this is the :ref:`pytest entry point <pytest:pip-installable plugins>`. Blocking @@ -607,12 +609,6 @@ :py:meth:`~pluggy.PluginManager.parse_hookspec_opts()` and :py:meth:`~pluggy.PluginManager.parse_hookimpl_opts()` respectively. -.. links -.. _setuptools entry points: - http://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins -.. _pytest entry point: - http://doc.pytest.org/en/latest/writing_plugins.html#setuptools-entry-points - .. _calling: @@ -622,13 +618,13 @@ to override function calls made at certain points throughout a program. A particular *hook* is invoked by calling an instance of -a :py:class:`pluggy._HookCaller` which in turn *loops* through the +a :py:class:`pluggy.hooks._HookCaller` which in turn *loops* through the ``1:N`` registered *hookimpls* and calls them in sequence. -Every :py:class:`pluggy.PluginManager` has a ``hook`` attribute -which is an instance of this :py:class:`pluggy._HookRelay`. -The ``_HookRelay`` itself contains references (by hook name) to each -registered *hookimpl*'s ``_HookCaller`` instance. +Every :py:class:`~pluggy.PluginManager` has a ``hook`` attribute +which is an instance of this :py:class:`pluggy.hooks._HookRelay`. +The :py:class:`~pluggy.hooks._HookRelay` itself contains references +(by hook name) to each registered *hookimpl*'s :py:class:`~pluggy.hooks._HookCaller` instance. More practically you call a *hook* like so: @@ -647,7 +643,7 @@ # we invoke the _HookCaller and thus all underlying hookimpls result_list = pm.hook.myhook(config=config, args=sys.argv) -Note that you **must** call hooks using keyword `arguments`_ syntax! +Note that you **must** call hooks using keyword :std:term:`python:argument` syntax! Hook implementations are called in LIFO registered order: *the last registered plugin's hooks are called first*. As an example, the below @@ -699,8 +695,8 @@ appended to a :py:class:`list` which is returned by the call. The only exception to this behaviour is if the hook has been marked to return -its :ref:`firstresult` in which case only the first single value (which is not -``None``) will be returned. +its :ref:`first result only <firstresult>` in which case only the first +single value (which is not ``None``) will be returned. .. _call_historic: @@ -708,8 +704,8 @@ ------------------ If any *hookimpl* errors with an exception no further callbacks are invoked and the exception is packaged up and delivered to -any :ref:`hookwrappers` before being re-raised at the hook invocation -point: +any :ref:`wrappers <hookwrappers>` before being re-raised at the +hook invocation point: .. code-block:: python @@ -768,7 +764,7 @@ hook is initially invoked. Historic hooks must be :ref:`specially marked <historic>` and called -using the :py:meth:`pluggy._HookCaller.call_historic()` method: +using the :py:meth:`~pluggy.hooks._HookCaller.call_historic()` method: .. code-block:: python @@ -789,11 +785,12 @@ # historic callback is invoked here pm.register(mylateplugin) -Note that if you ``call_historic()`` the ``_HookCaller`` (and thus your -calling code) can not receive results back from the underlying *hookimpl* -functions. Instead you can provide a *callback* for processing results -(like the ``callback`` function above) which will be called as each -new plugin is registered. +Note that if you :py:meth:`~pluggy.hooks._HookCaller.call_historic()` +the :py:class:`~pluggy.hooks._HookCaller` (and thus your calling code) +can not receive results back from the underlying *hookimpl* functions. +Instead you can provide a *callback* for processing results (like the +``callback`` function above) which will be called as each new plugin +is registered. .. note:: *historic* calls are incompatible with :ref:`firstresult` marked @@ -804,23 +801,19 @@ ------------------- You can call a hook with temporarily participating *implementation* functions (that aren't in the registry) using the -:py:meth:`pluggy._HookCaller.call_extra()` method. +:py:meth:`pluggy.hooks._HookCaller.call_extra()` method. Calling with a subset of registered plugins ------------------------------------------- You can make a call using a subset of plugins by asking the -``PluginManager`` first for a ``_HookCaller`` with those plugins removed +:py:class:`~pluggy.PluginManager` first for a +:py:class:`~pluggy.hooks._HookCaller` with those plugins removed using the :py:meth:`pluggy.PluginManager.subset_hook_caller()` method. -You then can use that ``_HookCaller`` to make normal, ``call_historic()``, -or ``call_extra()`` calls as necessary. - - -.. links -.. _arguments: - https://docs.python.org/3/glossary.html#term-argument - +You then can use that :py:class:`_HookCaller <pluggy.hooks._HookCaller>` +to make normal, :py:meth:`~pluggy.hooks._HookCaller.call_historic`, or +:py:meth:`~pluggy.hooks._HookCaller.call_extra` calls as necessary. Built-in tracing **************** @@ -877,7 +870,7 @@ $ source .env/bin/activate $ pip install -e .[dev] -To make sure you follow the code style used in the project, install ``pre-commit`` which +To make sure you follow the code style used in the project, install pre-commit_ which will run style checks before each commit:: $ pre-commit install @@ -903,50 +896,32 @@ .. hyperlinks -.. [email protected]: - https://docs.python.org/3.6/library/contextlib.html#contextlib.contextmanager .. _pytest_cmdline_main: - https://github.com/pytest-dev/pytest/blob/master/_pytest/hookspec.py#L80 + https://docs.pytest.org/en/latest/_modules/_pytest/hookspec.html#pytest_cmdline_main .. _hookspec module: - https://github.com/pytest-dev/pytest/blob/master/_pytest/hookspec.py -.. _Writing hook functions: - http://doc.pytest.org/en/latest/writing_plugins.html#writing-hook-functions + https://docs.pytest.org/en/latest/_modules/_pytest/hookspec.html .. _hookwrapper: http://doc.pytest.org/en/latest/writing_plugins.html#hookwrapper-executing-around-other-hooks .. _hook function ordering: http://doc.pytest.org/en/latest/writing_plugins.html#hook-function-ordering-call-example -.. _first result: - http://doc.pytest.org/en/latest/writing_plugins.html#firstresult-stop-at-first-non-none-result -.. _sent: - https://docs.python.org/3/reference/expressions.html#generator.send -.. _pytest: - https://pytest.org .. _request-response pattern: https://en.wikipedia.org/wiki/Request%E2%80%93response .. _publish-subscribe: https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern .. _hooking: https://en.wikipedia.org/wiki/Hooking -.. _plugin management and hook calling: - http://doc.pytest.org/en/latest/writing_plugins.html -.. _namespace: - https://docs.python.org/3.6/tutorial/classes.html#python-scopes-and-namespaces .. _callbacks: https://en.wikipedia.org/wiki/Callback_(computer_programming) .. _tox test suite: https://github.com/pytest-dev/pluggy/blob/master/tox.ini .. _Semantic Versioning: - http://semver.org/ -.. _tight coupling: - https://en.wikipedia.org/wiki/Coupling_%28computer_programming%29#Types_of_coupling + https://semver.org/ .. _Python interpreters: https://github.com/pytest-dev/pluggy/blob/master/tox.ini#L2 .. _500+ plugins: http://plugincompat.herokuapp.com/ -.. _self: - https://docs.python.org/3.6/tutorial/classes.html#random-remarks -.. _methods: - https://docs.python.org/3.6/tutorial/classes.html#method-objects +.. _pre-commit: + https://pre-commit.com/ .. Indices and tables diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pluggy-0.13.0/src/pluggy/_version.py new/pluggy-0.13.1/src/pluggy/_version.py --- old/pluggy-0.13.0/src/pluggy/_version.py 2019-09-10 22:14:46.000000000 +0200 +++ new/pluggy-0.13.1/src/pluggy/_version.py 2019-11-21 21:42:33.000000000 +0100 @@ -1,4 +1,4 @@ # coding: utf-8 # file generated by setuptools_scm # don't change, don't track in version control -version = '0.13.0' +version = '0.13.1' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pluggy-0.13.0/src/pluggy/hooks.py new/pluggy-0.13.1/src/pluggy/hooks.py --- old/pluggy-0.13.0/src/pluggy/hooks.py 2019-09-10 22:14:28.000000000 +0200 +++ new/pluggy-0.13.1/src/pluggy/hooks.py 2019-11-21 21:41:58.000000000 +0100 @@ -11,8 +11,8 @@ """ Decorator helper class for marking functions as hook specifications. You can instantiate it with a project_name to get a decorator. - Calling PluginManager.add_hookspecs later will discover all marked functions - if the PluginManager uses the same project_name. + Calling :py:meth:`.PluginManager.add_hookspecs` later will discover all marked functions + if the :py:class:`.PluginManager` uses the same project_name. """ def __init__(self, project_name): @@ -22,15 +22,15 @@ self, function=None, firstresult=False, historic=False, warn_on_impl=None ): """ if passed a function, directly sets attributes on the function - which will make it discoverable to add_hookspecs(). If passed no - function, returns a decorator which can be applied to a function + which will make it discoverable to :py:meth:`.PluginManager.add_hookspecs`. + If passed no function, returns a decorator which can be applied to a function later using the attributes supplied. - If firstresult is True the 1:N hook call (N being the number of registered + If ``firstresult`` is ``True`` the 1:N hook call (N being the number of registered hook implementation functions) will stop at I<=N when the I'th function - returns a non-None result. + returns a non-``None`` result. - If historic is True calls to a hook will be memorized and replayed + If ``historic`` is ``True`` calls to a hook will be memorized and replayed on later registered plugins. """ @@ -58,9 +58,9 @@ class HookimplMarker(object): """ Decorator helper class for marking functions as hook implementations. - You can instantiate with a project_name to get a decorator. - Calling PluginManager.register later will discover all marked functions - if the PluginManager uses the same project_name. + You can instantiate with a ``project_name`` to get a decorator. + Calling :py:meth:`.PluginManager.register` later will discover all marked functions + if the :py:class:`.PluginManager` uses the same project_name. """ def __init__(self, project_name): @@ -76,25 +76,25 @@ ): """ if passed a function, directly sets attributes on the function - which will make it discoverable to register(). If passed no function, - returns a decorator which can be applied to a function later using - the attributes supplied. + which will make it discoverable to :py:meth:`.PluginManager.register`. + If passed no function, returns a decorator which can be applied to a + function later using the attributes supplied. - If optionalhook is True a missing matching hook specification will not result + If ``optionalhook`` is ``True`` a missing matching hook specification will not result in an error (by default it is an error if no matching spec is found). - If tryfirst is True this hook implementation will run as early as possible + If ``tryfirst`` is ``True`` this hook implementation will run as early as possible in the chain of N hook implementations for a specification. - If trylast is True this hook implementation will run as late as possible + If ``trylast`` is ``True`` this hook implementation will run as late as possible in the chain of N hook implementations. - If hookwrapper is True the hook implementations needs to execute exactly - one "yield". The code before the yield is run early before any non-hookwrapper - function is run. The code after the yield is run after all non-hookwrapper - function have run. The yield receives a ``_Result`` object representing - the exception or result outcome of the inner calls (including other hookwrapper - calls). + If ``hookwrapper`` is ``True`` the hook implementations needs to execute exactly + one ``yield``. The code before the ``yield`` is run early before any non-hookwrapper + function is run. The code after the ``yield`` is run after all non-hookwrapper + function have run. The ``yield`` receives a :py:class:`.callers._Result` object + representing the exception or result outcome of the inner calls (including other + hookwrapper calls). """ @@ -290,7 +290,7 @@ for all plugins which will be registered afterwards. If ``result_callback`` is not ``None`` it will be called for for each - non-None result obtained from a hook implementation. + non-``None`` result obtained from a hook implementation. .. note:: The ``proc`` argument is now deprecated. @@ -314,7 +314,7 @@ def call_extra(self, methods, kwargs): """ Call the hook with some additional temporarily participating - methods using the specified kwargs as call parameters. """ + methods using the specified ``kwargs`` as call parameters. """ old = list(self._nonwrappers), list(self._wrappers) for method in methods: opts = dict(hookwrapper=False, trylast=False, tryfirst=False) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pluggy-0.13.0/src/pluggy/manager.py new/pluggy-0.13.1/src/pluggy/manager.py --- old/pluggy-0.13.0/src/pluggy/manager.py 2019-09-10 22:14:28.000000000 +0200 +++ new/pluggy-0.13.1/src/pluggy/manager.py 2019-11-21 21:41:58.000000000 +0100 @@ -50,22 +50,23 @@ class PluginManager(object): - """ Core Pluginmanager class which manages registration + """ Core :py:class:`.PluginManager` class which manages registration of plugin objects and 1:N hook calling. - You can register new hooks by calling ``add_hookspecs(module_or_class)``. + You can register new hooks by calling :py:meth:`add_hookspecs(module_or_class) + <.PluginManager.add_hookspecs>`. You can register plugin objects (which contain hooks) by calling - ``register(plugin)``. The Pluginmanager is initialized with a - prefix that is searched for in the names of the dict of registered - plugin objects. + :py:meth:`register(plugin) <.PluginManager.register>`. The :py:class:`.PluginManager` + is initialized with a prefix that is searched for in the names of the dict + of registered plugin objects. - For debugging purposes you can call ``enable_tracing()`` + For debugging purposes you can call :py:meth:`.PluginManager.enable_tracing` which will subsequently send debug information to the trace helper. """ def __init__(self, project_name, implprefix=None): """If ``implprefix`` is given implementation functions - will be recognized if their name matches the implprefix. """ + will be recognized if their name matches the ``implprefix``. """ self.project_name = project_name self._name2plugin = {} self._plugin2hookcallers = {} @@ -92,9 +93,9 @@ return self._inner_hookexec(hook, methods, kwargs) def register(self, plugin, name=None): - """ Register a plugin and return its canonical name or None if the name - is blocked from registering. Raise a ValueError if the plugin is already - registered. """ + """ Register a plugin and return its canonical name or ``None`` if the name + is blocked from registering. Raise a :py:class:`ValueError` if the plugin + is already registered. """ plugin_name = name or self.get_canonical_name(plugin) if plugin_name in self._name2plugin or plugin in self._plugin2hookcallers: @@ -176,11 +177,11 @@ self._name2plugin[name] = None def is_blocked(self, name): - """ return True if the given plugin name is blocked. """ + """ return ``True`` if the given plugin name is blocked. """ return name in self._name2plugin and self._name2plugin[name] is None def add_hookspecs(self, module_or_class): - """ add new hook specifications defined in the given module_or_class. + """ add new hook specifications defined in the given ``module_or_class``. Functions are recognized if they have been decorated accordingly. """ names = [] for name in dir(module_or_class): @@ -211,26 +212,27 @@ return set(self._plugin2hookcallers) def is_registered(self, plugin): - """ Return True if the plugin is already registered. """ + """ Return ``True`` if the plugin is already registered. """ return plugin in self._plugin2hookcallers def get_canonical_name(self, plugin): """ Return canonical name for a plugin object. Note that a plugin may be registered under a different name which was specified - by the caller of register(plugin, name). To obtain the name - of an registered plugin use ``get_name(plugin)`` instead.""" + by the caller of :py:meth:`register(plugin, name) <.PluginManager.register>`. + To obtain the name of an registered plugin use :py:meth:`get_name(plugin) + <.PluginManager.get_name>` instead.""" return getattr(plugin, "__name__", None) or str(id(plugin)) def get_plugin(self, name): - """ Return a plugin or None for the given name. """ + """ Return a plugin or ``None`` for the given name. """ return self._name2plugin.get(name) def has_plugin(self, name): - """ Return True if a plugin with the given name is registered. """ + """ Return ``True`` if a plugin with the given name is registered. """ return self.get_plugin(name) is not None def get_name(self, plugin): - """ Return name for registered plugin or None if not registered. """ + """ Return name for registered plugin or ``None`` if not registered. """ for name, val in self._name2plugin.items(): if plugin == val: return name @@ -262,7 +264,7 @@ def check_pending(self): """ Verify that all hooks which have not been verified against - a hook specification are optional, otherwise raise PluginValidationError""" + a hook specification are optional, otherwise raise :py:class:`.PluginValidationError`.""" for name in self.hook.__dict__: if name[0] != "_": hook = getattr(self.hook, name) @@ -323,7 +325,7 @@ of HookImpl instances and the keyword arguments for the hook call. ``after(outcome, hook_name, hook_impls, kwargs)`` receives the - same arguments as ``before`` but also a :py:class:`_Result`` object + same arguments as ``before`` but also a :py:class:`pluggy.callers._Result` object which represents the result of the overall hook call. """ oldcall = self._inner_hookexec @@ -357,7 +359,7 @@ return self.add_hookcall_monitoring(before, after) def subset_hook_caller(self, name, remove_plugins): - """ Return a new _HookCaller instance for the named method + """ Return a new :py:class:`.hooks._HookCaller` instance for the named method which manages calls to all registered plugins except the ones from remove_plugins. """ orig = getattr(self.hook, name) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pluggy-0.13.0/src/pluggy.egg-info/PKG-INFO new/pluggy-0.13.1/src/pluggy.egg-info/PKG-INFO --- old/pluggy-0.13.0/src/pluggy.egg-info/PKG-INFO 2019-09-10 22:14:46.000000000 +0200 +++ new/pluggy-0.13.1/src/pluggy.egg-info/PKG-INFO 2019-11-21 21:42:33.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pluggy -Version: 0.13.0 +Version: 0.13.1 Summary: plugin and hook calling mechanisms for python Home-page: https://github.com/pytest-dev/pluggy Author: Holger Krekel @@ -69,6 +69,14 @@ 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 @@ -114,6 +122,15 @@ .. towncrier release notes start + pluggy 0.13.1 (2019-11-21) + ========================== + + Trivial/Internal Changes + ------------------------ + + - `#236 <https://github.com/pytest-dev/pluggy/pull/236>`_: Improved documentation, especially with regard to references. + + pluggy 0.13.0 (2019-09-10) ========================== @@ -425,7 +442,7 @@ .. contributors .. _@hpk42: https://github.com/hpk42 - .. _@tgoodlet: https://github.com/tgoodlet + .. _@tgoodlet: https://github.com/goodboy .. _@MichalTHEDUDE: https://github.com/MichalTHEDUDE .. _@vodik: https://github.com/vodik .. _@RonnyPfannschmidt: https://github.com/RonnyPfannschmidt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pluggy-0.13.0/tox.ini new/pluggy-0.13.1/tox.ini --- old/pluggy-0.13.0/tox.ini 2019-09-10 22:14:28.000000000 +0200 +++ new/pluggy-0.13.1/tox.ini 2019-11-21 21:41:58.000000000 +0100 @@ -47,7 +47,7 @@ [testenv:release] decription = do a release, required posarg of the version number -basepython = python3.6 +basepython = python3 skipsdist = True usedevelop = True passenv = *
