First look at pluggyΒΆ

[1]:
    import pluggy, pytest
import pluggy, pytest
[2]:
    specification, implementation = pluggy.HookspecMarker('example') ,pluggy.HookimplMarker('example')
specification, implementation = pluggy.HookspecMarker('example') ,pluggy.HookimplMarker('example')
[3]:
    class Spec:

Define specifications as function with the name of the hook and reusable function signature.

        @specification
        def function(object):

A specification needs to exist before an implementation.
class Spec:

Define specifications as function with the name of the hook and reusable function signature.

@specification
def function(object):

A specification needs to exist before an implementation.

[4]:
    @implementation
    def function(object):

An implementation of the function specification.

        return type(object)
@implementation
def function(object):

An implementation of the function specification.

return type(object)
[5]:
    class Another:
        @implementation(trylast=True)
        def function(object):

Another implementation of the function spec.

            return str(object)
class Another:
    @implementation(trylast=True)
    def function(object):

Another implementation of the function spec.

return str(object)
[13]:
The manager connects specifications and implementations with a manager.

    manager = pluggy.PluginManager('example')

Specifications need to be registered, but no implementations exist to the manager.

    manager.add_hookspecs(Spec)

    >>> with pytest.raises(TypeError): manager.hook.function(int)

The hook only accepts keyword arguments with names that validate.

    >>> manager.hook.function(object=int)
    []

The manager connects specifications and implementations with a manager.

manager = pluggy.PluginManager('example')

Specifications need to be registered, but no implementations exist to the manager.

manager.add_hookspecs(Spec)

>>> with pytest.raises(TypeError): manager.hook.function(int)

The hook only accepts keyword arguments with names that validate.

>>> manager.hook.function(object=int)
[]
[14]:
Include an implementation.

    manager.register(__import__(__name__))

    >>> manager.hook.function(object=int)
    [<class 'type'>]

We cannot register the same object twice.

    >>> with pytest.raises(ValueError): manager.register(__import__(__name__))

Include an implementation.

manager.register(__import__(__name__))

>>> manager.hook.function(object=int)
[<class 'type'>]

We cannot register the same object twice.

>>> with pytest.raises(ValueError): manager.register(__import__(__name__))
[15]:
Adding another hook returns more results when the hook is triggered.

    manager.register(Another)

    >>> manager.hook.function(object=int)
    [<class 'type'>, "<class 'int'>"]

Adding another hook returns more results when the hook is triggered.

manager.register(Another)

>>> manager.hook.function(object=int)
[<class 'type'>, "<class 'int'>"]
[16]:
Implementations can be unregistered.

    manager.unregister(__import__(__name__))
    >>> [x.function for x in manager.hook.function.get_hookimpls()]
    [<function Another.function at ...>]

    manager.register(__import__(__name__))

    >>> [x.function for x in manager.hook.function.get_hookimpls()]
    [<function Another.function at ...>, <function function at ...>]

Implementations can be unregistered.

manager.unregister(__import__(__name__))
>>> [x.function for x in manager.hook.function.get_hookimpls()]
[<function Another.function at ...>]

manager.register(__import__(__name__))

>>> [x.function for x in manager.hook.function.get_hookimpls()]
[<function Another.function at ...>, <function function at ...>]