Versions follow Semantic Versioning (<major>.<minor>.<patch>
).
.. only:: changelog_towncrier_draft .. The 'changelog_towncrier_draft' tag is included by our 'tox -e docs', but not on readthedocs. .. include:: _changelog_towncrier_draft.rst
#178: Add support for deprecating specific hook parameters, or more generally, for issuing a warning whenever a hook implementation requests certain parameters.
See :ref:`warn_on_impl` for details.
- #481:
PluginManager.get_plugins()
no longer returnsNone
for blocked plugins.
- #463: A warning :class:`~pluggy.PluggyTeardownRaisedWarning` is now issued when an old-style hookwrapper raises an exception during teardown. See the warning documentation for more details.
- #471: Add :func:`PluginManager.unblock <pluggy.PluginManager.unblock>` method to unblock a plugin by plugin name.
- #441: Fix :func:`~pluggy.HookCaller.call_extra()` extra methods getting ordered before everything else in some circumstances. Regressed in pluggy 1.1.0.
- #438: Fix plugins registering other plugins in a hook when the other plugins implement the same hook itself. Regressed in pluggy 1.1.0.
- #426: Python 3.7 is no longer supported.
#428: Pluggy now exposes its typings to static type checkers.
As part of this, the following changes are made:
- Renamed
_Result
toResult
, and exported as :class:`pluggy.Result`. - Renamed
_HookRelay
toHookRelay
, and exported as :class:`pluggy.HookRelay`. - Renamed
_HookCaller
toHookCaller
, and exported as :class:`pluggy.HookCaller`. - Exported
HookImpl
as :class:`pluggy.HookImpl`. - Renamed
_HookImplOpts
toHookimplOpts
, and exported as :class:`pluggy.HookimplOpts`. - Renamed
_HookSpecOpts
toHookspecOpts
, and exported as :class:`pluggy.HookspecOpts`. - Some fields and classes are marked
Final
and@final
. - The :ref:`api-reference` is updated to clearly delineate pluggy's public API.
Compatibility aliases are put in place for the renamed types. We do not plan to remove the aliases, but we strongly recommend to only import from
pluggy.*
to ensure future compatibility.Please note that pluggy is currently unable to provide strong typing for hook calls, e.g.
pm.hook.my_hook(...)
, nor to statically check that a hook implementation matches the hook specification's type.- Renamed
- #405: The new-style hook wrappers, added in the yanked 1.1.0 release, now require an explicit
wrapper=True
designation in the@hookimpl()
decorator.
Note
This release was yanked because unfortunately the implicit new-style hook wrappers broke some downstream projects. See #403 for more information. This was rectified in the 1.2.0 release.
- #364: Python 3.6 is no longer supported.
#260: Added "new-style" hook wrappers, a simpler but equally powerful alternative to the existing
hookwrapper=True
wrappers.New-style wrappers are generator functions, similarly to
hookwrapper
, but do away with the :class:`result <pluggy.Result>` object. Instead, the return value is sent directly to theyield
statement, or, if inner calls raised an exception, it is raised from theyield
. The wrapper is expected to return a value or raise an exception, which will become the result of the hook call.New-style wrappers are fully interoperable with old-style wrappers. We encourage users to use the new style, however we do not intend to deprecate the old style any time soon.
See :ref:`hookwrappers` for the full documentation.
#364: Python 3.11 and 3.12 are now officially supported.
#394: Added the :meth:`~pluggy.Result.force_exception` method to
_Result
.force_exception
allows (old-style) hookwrappers to force an exception or override/adjust an existing exception of a hook invocation, in a properly behaving manner. Usingforce_exception
is preferred over raising an exception from the hookwrapper, because raising an exception causes other hookwrappers to be skipped.
- #116: Remove deprecated
implprefix
support. Decorate hook implementations using an instance of HookimplMarker instead. The deprecation was announced in release0.7.0
. - #120: Remove the deprecated
proc
argument tocall_historic
. Useresult_callback
instead, which has the same behavior. The deprecation was announced in release0.7.0
. - #265: Remove the
_Result.result
property. Use_Result.get_result()
instead. Note that unlikeresult
,get_result()
raises the exception if the hook raised. The deprecation was announced in release0.6.0
. - #267: Remove official support for Python 3.4.
- #272: Dropped support for Python 2. Continue to use pluggy 0.13.x for Python 2 support.
- #308: Remove official support for Python 3.5.
- #313: The internal
pluggy.callers
,pluggy.manager
andpluggy.hooks
are now explicitly marked private by a_
prefix (e.g.pluggy._callers
). Only API exported by the top-levelpluggy
module is considered public. - #59: Remove legacy
__multicall__
recursive hook calling system. The deprecation was announced in release0.5.0
.
#282: When registering a hookimpl which is declared as
hookwrapper=True
but whose function is not a generator function, a :class:`~pluggy.PluginValidationError` exception is now raised.Previously this problem would cause an error only later, when calling the hook.
In the unlikely case that you have a hookwrapper that returns a generator instead of yielding directly, for example:
def my_hook_implementation(arg): print("before") yield print("after") @hookimpl(hookwrapper=True) def my_hook(arg): return my_hook_implementation(arg)
change it to use
yield from
instead:@hookimpl(hookwrapper=True) def my_hook(arg): yield from my_hook_implementation(arg)
#309: Add official support for Python 3.9.
#251: Add
specname
option to@hookimpl
. Ifspecname
is provided, it will be used instead of the function name when matching this hook implementation to a hook specification during registration (allowing a plugin to register a hook implementation that was not named the same thing as the corresponding@hookspec
).
- #236: Improved documentation, especially with regard to references.
- #222: Replace
importlib_metadata
backport withimportlib.metadata
from the standard library on Python 3.8+.
- #215: Switch from
pkg_resources
toimportlib-metadata
for entrypoint detection for improved performance and import time. This time with.egg
support.
- #205: Revert changes made in 0.10.0 release breaking
.egg
installs.
- #199: Switch from
pkg_resources
toimportlib-metadata
for entrypoint detection for improved performance and import time.
#189:
PluginManager.load_setuptools_entrypoints
now accepts aname
parameter that when given will load only entry points with that name.PluginManager.load_setuptools_entrypoints
also now returns the number of plugins loaded by the call, as opposed to the number of all plugins loaded by all calls to this method.
- #187: Fix internal
varnames
function for PyPy3.
- #166: Add
stacklevel=2
to implprefix warning so that the reported location of warning is the caller of PluginManager.
- #177: Add
get_hookimpls()
method to hook callers.
- #165: Add changelog in long package description and documentation.
- #172: Add a test exemplifying the opt-in nature of spec defined args.
- #57: Encapsulate hook specifications in a type for easier introspection.
- #116: Deprecate the
implprefix
kwarg toPluginManager
and instead expect users to start using explicitHookimplMarker
everywhere.
- #122: Add
.plugin
member toPluginValidationError
to access failing plugin during post-mortem. - #138: Add per implementation warnings support for hookspecs allowing for both deprecation and future warnings of legacy and (future) experimental hooks respectively.
- #110: Fix a bug where
_HookCaller.call_historic()
would call theproc
arg even when the default isNone
resulting in aTypeError
. - #160: Fix problem when handling
VersionConflict
errors when loading setuptools plugins.
- #123: Document how exceptions are handled and how the hook call loop terminates immediately on the first error which is then delivered to any surrounding wrappers.
- #136: Docs rework including a much better introduction and comprehensive example set for new users. A big thanks goes out to @obestwalter for the great work!
- #117: Break up the main monolithic package modules into separate modules by concern
- #131: Automate
setuptools
wheels building and PyPi upload using TravisCI. - #153: Reorganize tests more appropriately by modules relating to each internal component/feature. This is in an effort to avoid (future) duplication and better separation of concerns in the test set.
- #156: Add
HookImpl.__repr__()
for better debugging. - #66: Start using
towncrier
and a customtox
environment to prepare releases!
- #160: We discovered a deployment issue so this version was never released to PyPI, only the tag exists.
- Add CI testing for the features, release, and master
branches of
pytest
(PR #79). - Document public API for
_Result
objects passed to wrappers (PR #85). - Document and test hook LIFO ordering (PR #85).
- Turn warnings into errors in test suite (PR #89).
- Deprecate
_Result.result
(PR #88). - Convert
_Multicall
to a simple function distinguishing it from the legacy version (PR #90). - Resolve E741 errors (PR #96).
- Test and bug fix for unmarked hook collection (PRs #97 and #102).
- Drop support for EOL Python 2.6 and 3.3 (PR #103).
- Fix
inspect
based arg introspection on py3.6 (PR #94).
- fix bug where
firstresult
wrappers were being sent an incorrectly configured_Result
(a list was set instead of a single value). Add tests to check for this as well as_Result.force_result()
behaviour. Thanks to @tgoodlet for the PR #72. - fix incorrect
getattr
ofDeprecationWarning
from thewarnings
module. Thanks to @nicoddemus for the PR #77. - hide
pytest
tracebacks in certain core routines. Thanks to @nicoddemus for the PR #80.
- fix a bug and add tests for case where
firstresult
hooks returnNone
results. Thanks to @RonnyPfannschmidt and @tgoodlet for the issue (#68) and PR (#69) respectively.
- fix bug where callbacks for historic hooks would not be called for already registered plugins. Thanks @vodik for the PR and @hpk42 for further fixes.
- fix #17 by considering only actual functions for hooks this removes the ability to register arbitrary callable objects which at first glance is a reasonable simplification, thanks @RonnyPfannschmidt for report and pr.
- fix #19: allow registering hookspecs from instances. The PR from @tgoodlet also modernized the varnames implementation.
- resolve #32: split up the test set into multiple modules. Thanks to @RonnyPfannschmidt for the PR and @tgoodlet for the initial request.
- resolve #14: add full sphinx docs. Thanks to @tgoodlet for PR #39.
- add hook call mismatch warnings. Thanks to @tgoodlet for the PR #42.
- resolve #44: move to new-style classes. Thanks to @MichalTHEDUDE for PR #46.
- add baseline benchmarking/speed tests using
pytest-benchmark
in PR #54. Thanks to @tgoodlet. - update the README to showcase the API. Thanks to @tgoodlet for the issue and PR #55.
- deprecate
__multicall__
and add a faster call loop implementation. Thanks to @tgoodlet for PR #58. - raise a comprehensible error when a
hookimpl
is called with positional args. Thanks to @RonnyPfannschmidt for the issue and @tgoodlet for PR #60. - fix the
firstresult
test making it more complete and remove a duplicate of that test. Thanks to @tgoodlet for PR #62.
- add
has_plugin(name)
method to pluginmanager. thanks @nicoddemus. - fix #11: make plugin parsing more resilient against exceptions
from
__getattr__
functions. Thanks @nicoddemus. - fix issue #4: specific
HookCallError
exception for when a hook call provides not enough arguments. - better error message when loading setuptools entrypoints fails
due to a
VersionConflict
. Thanks @blueyed.
- avoid using deprecated-in-python3.5 getargspec method. Thanks @mdboom.
initial release