Core API¶
grappler
¶
The grappler
module contains everything you need to get
started using grappler. The main entry point is the
Hook
class.
Package
¶
Bases: NamedTuple
A logical collection of plugins
name: str
class-attribute
¶
A name for the package which may be displayed to a human.
version: str
class-attribute
¶
A version number for the package.
id: str
class-attribute
¶
A unique identifier for the package.
platform: Optional[str]
class-attribute
¶
The package platform (sys.platform compatible value, if any)
Hook(topic: str, *, grappler: Optional[Grappler] = None) -> None
¶
Bases: Generic[T]
An abstraction for loading plugins providing a specific behavior.
Hooks provide an iterable interface for loaded plugin values. This allows to define a hook with a topic to load plugins for, and then iterate over the hook in order to access the externally loaded objects. Furthermore, the iterated objects can be further restricted by providing a type argument to the hook; when this is done, any externally loaded object that is not an instance of the given type is skipped.
Type arguments to Hook must be usable in isinstance
check
The type argument given to the hook class should be
usable as the second argument to Python's isinstance
.
Failing this constraint will result in a type error upon
iteration (notable exception: Any
may be used). This means that
some types which are otherwise valid are not usable in this context
(e.g. None
or Callable[...]
).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
topic |
str
|
An arbitrary string identifier for the behavior that your hook will load plugins for. The hook will then only load plugins that advertise the topic given here. |
required |
grappler |
Optional[Grappler]
|
When given, it should be a
|
None
|
Usage:
# iterate the hook to load all plugins from the topic.
from grappler import Hook
objs = list(Hook("topic.counter-functions"))
# use a type argument to restrict the objects that are returned.
from typing import Any, Protocol, runtime_checkable
from grappler import Hook
@runtime_checkable
class CounterFunction(Protocol):
def __call__(self, items: Any) -> int: ...
counter_functions = list(Hook[CounterFunction]("topic.counter-functions"))
# (note: argument specs are not checked for callable Protocol
# instance checks; the mere presence of a `__call__` method will satisfy
# the hook's filter. This is due to how `isinstance` works in Python.)
Source code in grappler/_hook.py
__iter__() -> Iterator[T]
¶
Return an iterator to loaded plugin objects from the hook's topic.
If the hook was instantiated with a type argument, then only objects
which pass isinstance(obj, T)
are included in the iterator.
Source code in grappler/_hook.py
loaded_plugins() -> Collection[Plugin]
property
¶
Plugin
dataclass
¶
An external, loadable Python object
grappler_id: str
class-attribute
¶
The id of the grappler that the plugin came from.
plugin_id: str
class-attribute
¶
A unique identifier for the plugin.
package: Package
class-attribute
¶
A struct containing more information about the package containing the plugin
name: Optional[str]
class-attribute
¶
A name for the plugin which may be displayed to a human.
Grappler
¶
Bases: Protocol
General protocol for an object that can find and load plugins.
id() -> str
property
¶
find(topic: Optional[str] = None) -> ContextManager[Iterator[Plugin]]
¶
Return a context managed iterator of plugins that this grappler can load.
Implementors of this protocol only need to make sure that the plugins can be loaded when the returned context manager is still open; once the context closes, then it is not required for the returned plugins to still be loadable.
Source code in grappler/_types.py
load(plugin: Plugin) -> Any
¶
Load an object out of an plugin.
May raise an UnknownPluginError if the plugin type is not recognised by the grappler. (This may happen even when supplied a plugin which originated in the grappler, but it's find context is already closed.)
Source code in grappler/_types.py
UnknownPluginError(plugin: Plugin, grappler: Grappler) -> None
¶
Bases: LookupError
Raised when a grappler is asked to load an plugin it doesn't know how to.