elasticai.creator.plugin#

Provides ways to use and extend the elasticai.creator plugin system.

The plugin systems evolves around the

For convenience many functions convert the dicts loaded from the meta.toml file into PluginSpec objects. The meta.toml file needs to define the value of each field of the PluginSpec class. The function read_plugin_dicts_from_package will read all plugins from the plugins key in the meta.toml file of a package.

Example of a minimal meta.toml file

[[plugins]]
name = "minimal_plugin"
target_platform = "elastic-node-v5"
target_runtime = "vhdl"
version = "0.1"
api_version = "0.1"

The few minimal fields that a plugin is required to define shall allow plugin loaders to decide how to treat the plugin this could mean to

  • ignore the plugin

  • forward it to another software component

  • check if the plugin is not compatible with the current setup

The following table lists these required fields:

Field name

Type

Description

name

str

The name of the plugin, used to identify the plugin

target platform

str

A string describing the target platform for the plugin, ie. the lowering pass it should be loaded into. Currently there is no strict definition of the semantics of this string.

target runtime

str

A string the runtime context for the plugin. Currently there is no strict definition of the semantics of this string.

version

str

A version string in the form major.minor.[patch]. Specifies the version of the plugin, ie. if you introduce a new feature or fix a bug, you should usually increase the minor version.

api_version

str

The version of the plugin API (plugin system) that this plugin was developed against. This is used to check if the plugin is compatible with the current system.

Warning

The set of required fields and their semantics is experimental and likely to change in the future.

The PluginLoader will read that description from the meta.toml file in a given package and use a user provided function to decide which symbols to load from which module. Assuming that each of these symbols implements the PluginSymbol protocol, it will then call load_into on each of these symbols with a plugin_receiver. The plugin_receiver is provided by the user as well.

Most other classes defined in this module are supposed to increase usability and expressiveness.

Module Contents#

Classes#

PluginSpec

The specification of a plugin.

PluginLoader

Get a set of plugins from a package, use extract_fn to resolve the symbols and load them into the plugin_receiver.

PluginSymbol

A symbol that the PluginLoader can load into a receiver object.

SymbolFetcher

Fetches PluginSymbols for the PluginLoader.

SymbolFetcherBuilder

Build a SymbolFetcher from simpler functions.

PluginSymbolFn

A PluginSymbol that is also a function/callable.

Functions#

import_symbols

import names from a module and yield the resulting objects.

make_plugin_symbol

Turn two functions into a loadable and callable plugin symbol.

build_plugin_spec

inspect spec_type and build an instance of it from the dictionary d.

read_plugin_dicts_from_package

read the meta.toml file from the package returning the list of plugin dictionaries.

Data#

API#

class elasticai.creator.plugin.PluginSpec[source]#

The specification of a plugin.

Typically built by reading a dictionary from a toml file and building the spec using <<build_plugin_spec, build_plugin_spec()>>. The dataclass is only used to provide convenient access to the fields, support type checking and improve code readability.

You can achieve your goals just as well with the PluginDict dictionary. That is defined as an alias for dict[str, str | tuple[str, ...]].

name: str#

None

target_platform: str#

None

target_runtime: str#

None

version: str#

None

api_version: str#

None

package: str#

None

elasticai.creator.plugin.PluginDict: TypeAlias#

None

elasticai.creator.plugin.PluginSpecT#

‘TypeVar(…)’

elasticai.creator.plugin.P#

‘ParamSpec(…)’

class elasticai.creator.plugin.PluginLoader(fetch: elasticai.creator.plugin.SymbolFetcher, plugin_receiver: elasticai.creator.plugin._PlRecT)[source]#

Bases: typing.Generic[elasticai.creator.plugin._PlRecT]

Get a set of plugins from a package, use extract_fn to resolve the symbols and load them into the plugin_receiver.

.Args

  • fetch: A function that extracts PluginSymbols from plugin dictionaries. Use this to decide, based on the plugin specs, which symbols to load from which modules. Use the SymbolFetcherBuilder to easily compose new fetch functions.

  • plugin_receiver: The object that will receive the loaded symbols. Receive in this context means that the loader will call symbol.load_into(plugin_receiver) for each of these symbols. That allows symbols defined in the plugin to run code in the context of the plugin receiver. E.g., it could register a lowering function in a LoweringPass if that lowering pass is given as the receiver.

Initialization

load_from_package(package: str) None[source]#

load all plugins defined by the meta.toml file found in the package.

class elasticai.creator.plugin.PluginSymbol[source]#

Bases: typing.Protocol[elasticai.creator.plugin._PlRecT]

A symbol that the PluginLoader can load into a receiver object.

The receiver can be any object.

abstract load_into(/, receiver) None[source]#
class elasticai.creator.plugin.SymbolFetcher[source]#

Bases: typing.Protocol[elasticai.creator.plugin._PlRecT]

Fetches PluginSymbols for the PluginLoader.

abstract __call__(data: collections.abc.Iterable[elasticai.creator.plugin.PluginDict]) collections.abc.Iterator[elasticai.creator.plugin.PluginSymbol[elasticai.creator.plugin._PlRecT]][source]#
class elasticai.creator.plugin.SymbolFetcherBuilder(spec_type: type[elasticai.creator.plugin.PluginSpecT])[source]#

Bases: typing.Generic[elasticai.creator.plugin.PluginSpecT, elasticai.creator.plugin._PlRecT]

Build a SymbolFetcher from simpler functions.

The SymbolFetcherBuilder composes simpler functions into a SymbolFetcher.

.Args

  • spec_type: The type of the plugin spec that the SymbolFetcher will build from the plugin dictionaries.

Initialization

add_fn_over_iter(fn: collections.abc.Callable[[collections.abc.Iterable[elasticai.creator.plugin.PluginSpecT]], collections.abc.Iterator[elasticai.creator.plugin.PluginSymbol[elasticai.creator.plugin._PlRecT]]]) elasticai.creator.plugin._SymbolFetcherBuilderT[source]#

Add a function that will be called for each plugin spec.

add_fn(fn: collections.abc.Callable[[elasticai.creator.plugin.PluginSpecT], collections.abc.Iterator[elasticai.creator.plugin.PluginSymbol[elasticai.creator.plugin._PlRecT]]]) elasticai.creator.plugin._SymbolFetcherBuilderT[source]#

Add a function that will be called once for all plugin specs.

build() elasticai.creator.plugin.SymbolFetcher[elasticai.creator.plugin._PlRecT][source]#
class elasticai.creator.plugin.PluginSymbolFn[source]#

Bases: elasticai.creator.plugin.PluginSymbol[elasticai.creator.plugin._PlRecT], typing.Generic[elasticai.creator.plugin._PlRecT, elasticai.creator.plugin.P, elasticai.creator.plugin._ReturnT], typing.Protocol

A PluginSymbol that is also a function/callable.

abstract __call__(*args: elasticai.creator.plugin.P, **kwargs: elasticai.creator.plugin.P) elasticai.creator.plugin._ReturnT[source]#
elasticai.creator.plugin.import_symbols(module: str, names: collections.abc.Iterable[str]) collections.abc.Iterator[elasticai.creator.plugin.PluginSymbol][source]#

import names from a module and yield the resulting objects.

elasticai.creator.plugin.make_plugin_symbol(load_into: collections.abc.Callable[[elasticai.creator.plugin._PlRecT], None], fn: collections.abc.Callable[elasticai.creator.plugin.P, elasticai.creator.plugin._T]) elasticai.creator.plugin.PluginSymbolFn[elasticai.creator.plugin._PlRecT, elasticai.creator.plugin.P, elasticai.creator.plugin._T][source]#

Turn two functions into a loadable and callable plugin symbol.

.Args

  • load_into: executed when PluginLoader calls load_into on the Symbol

  • fn: wrapped function. Executed when the created PluginSymbolFn is called.

An important use case for plugin symbols is to provide callable functions, e.g., for lowering passes. make_plugin_symbol eases creating plugin symbols for these functions.

For an example look at the implementation of the type_handler decorators in xref::api:ir2vhdl.adoc[ir2vhdl].


elasticai.creator.plugin.build_plugin_spec(d: elasticai.creator.plugin.PluginDict, spec_type: type[elasticai.creator.plugin.PluginSpecT]) elasticai.creator.plugin.PluginSpecT[source]#

inspect spec_type and build an instance of it from the dictionary d.

Missing field raise an error while extra fields will be ignored.

elasticai.creator.plugin.read_plugin_dicts_from_package(package: str) collections.abc.Iterable[elasticai.creator.plugin.PluginDict][source]#

read the meta.toml file from the package returning the list of plugin dictionaries.

exception elasticai.creator.plugin.MissingFieldError(field_names: set[str], plugin_type: type[elasticai.creator.plugin.PluginSpecT])[source]#

Bases: Exception