Components¶
The model every kind shares: the base class, its definition, the identity a component is resolved by, and the relations that bind components to one another.
Component
¶
Bases: interloper.serializable.base.Serializable
Fundamental building block: identifiable, composable, serializable.
Every catalog citizen extends Component. On top of
Serializable it provides:
- Identity:
kind(class-level category),id(instance-level, overridable) andidentity, the pair relation matching reads. - Relations: one
relationsmap, name toRelation, collected from the class body and bound per instance. - Definition:
definition()exposes class metadata for API consumers.
A relation written in a class body is a Relation value, so Relation
joins IgnoredDescriptor in
ignored_types: Pydantic never mistakes a declared relation for a field.
Bind the relation kwargs, validate everything else as fields.
A kwarg named after a declared relation binds that relation instead of
reaching Pydantic, which knows nothing about relations: a list or tuple
binds every element, None binds nothing. Each binding is checked
as it is made (see bind); whether every relation that must be
bound is bound is a question for whoever assembles the graph, since
components are wired piecewise (a source's assets read its bindings
through it, reconstruction binds references once the document is whole), so
validate_relations is called at those boundaries, not here.
Unknown kwargs are a loud error rather than pydantic's silent
extra="ignore" drop: a misnamed field would otherwise vanish, and a
stale persisted config key surfaces as drift at load time, consistent
with the fail-closed drift checks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**data
|
Any
|
Field values and relation targets, keyed by field or relation name. |
required |
Raises:
| Type | Description |
|---|---|
TypeError
|
If a kwarg names neither a field nor a declared relation. |
discriminator
¶
This instance's discriminator value, if declared and set.
The value of the config field marked discriminator=True: what
distinguishes instances of the same component class (an ad account
id, a site URL, ...). Drives the derived instance_name and,
for sources, the per-instance asset table names.
icon
¶
str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.
key
¶
str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.
kind
¶
str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.
maturity
¶
How far a component is from being relied on in production.
Informational: it is shown beside the component wherever it is offered
and never changes what the component does. ALPHA is early work whose
behaviour, configuration and output may still change and that has not
been proven against a live service; BETA works and is being proven,
with changes still possible; STABLE, the default, is relied on;
DEPRECATED still works but is being phased out, so new setups should
avoid it.
A composite, such as an asset inside its source, shows the
least mature of its parts, DEPRECATED counting as the least:
a deprecated source deprecates its assets, and a deprecated asset stays
deprecated whatever its source.
model_config
¶
model_config = {'arbitrary_types_allowed': True, 'ignored_types': (<class 'interloper.serializable.base.IgnoredDescriptor'>, <class 'interloper.component.relation.Relation'>)}
dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)
owned
¶
The components this one owns (a source's assets), which travel inside its own spec.
Returns:
| Type | Description |
|---|---|
|
The owned components, in field order; empty for a component that |
|
|
owns none. |
parent
¶
The component that owns this one, None when it stands alone.
A source owns its assets; a connection, a config or a standalone asset
has no owner. Ownership scopes the bare keys a relation declares, so it
is what identity reads.
qualified_key
¶
This component's key, qualified by its owner's key when it has an owner.
relations
¶
dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)
sensitive
¶
bool(x) -> bool
Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.
anchor
¶
anchor() -> type[Component]
The class anchoring this component's kind.
The anchor is the base-most class in the MRO that declares the
kind (Connection for any connection subclass), so any component
class resolves to the single per-kind authority.
Returns:
| Type | Description |
|---|---|
type[Component]
|
The anchoring class. |
bind
¶
bind(name: str, *targets: Component) -> None
Bind components to one of this component's declared relations.
A many relation accumulates, skipping targets it already holds; a
single-valued one replaces what it holds, so repointing it is a second
bind and needs no unbind first.
A target whose kind or key the relation does not accept, this
component itself, and more than one target at once on a single-valued
relation are all refused with a ConfigError from
_replace_binding, which every write path goes through.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The relation name as declared on the class. |
required |
*targets
|
Component
|
The components to bind. Binding nothing is a no-op, so a caller may splat an empty list. |
required |
bound
¶
What is explicitly bound to one of this component's declared relations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The relation name as declared on the class. |
required |
Returns:
| Type | Description |
|---|---|
Component | list[Component] | None
|
The bound components as a list for a |
Component | list[Component] | None
|
nothing is bound), otherwise the single bound component or |
definition
¶
definition() -> ComponentDefinition
Produce a structured definition of this component class.
The one place a class is described. A kind whose definition carries
more (a source's assets, an asset's schema) builds its own model from
this one: SourceDefinition(**dict(super().definition()), assets=...).
Every FetchField provider the class declares is checked against its
relations first, so a misnamed provider fails at catalog-build time
rather than in a form.
Returns:
| Type | Description |
|---|---|
ComponentDefinition
|
A ComponentDefinition with metadata derived from the class. |
discriminator_field
¶
Name of the config field marked discriminator=True, if any.
Returns:
| Type | Description |
|---|---|
str | None
|
The marked field name, or |
event_metadata
¶
event_metadata(
metadata: Mapping[str, Any],
window: PartitionWindow | None = None,
**extra: Any,
) -> dict[str, Any]
Build the metadata of an event about this component.
One shape for every event: the run metadata, the component's identity, the window the
event is scoped to (None when unscoped), the parent's id when the component has one,
and whatever the producer adds (a message, an error, a destination key, an attempt).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
metadata
|
Mapping[str, Any]
|
Run-level metadata (run id, backfill id, anything the caller passed). |
required |
window
|
PartitionWindow | None
|
The window the event is scoped to, or |
None
|
**extra
|
Any
|
Producer-specific keys, written last so they win. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
The event metadata. |
from_init
¶
Build a component from a loaded init, holding its references back for the document to bind.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
init
|
dict[str, Any]
|
Constructor keyword arguments, nested specs already built and
every |
required |
context
|
SerializationContext
|
The document being read: it keeps the held references and the instance, so a later reference finds it. |
required |
Returns:
| Type | Description |
|---|---|
Self
|
The component, its references not yet bound. |
inherited
¶
inherited(child: Component, name: str, own: Any) -> Any
What an owned component reads for one of its inherited settings.
The one seam a cascade goes through: an owned component never holds a
copy of what it inherits, it asks its owner on every read. The base
hands down this component's own effective value; an owner that names
part of its children's location overrides it (see Source.inherited).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
child
|
Component
|
The owned component reading the setting. |
required |
name
|
str
|
The setting's field name. |
required |
own
|
Any
|
The child's stored value, |
required |
Returns:
| Type | Description |
|---|---|
Any
|
own when set, else this component's own value under name when |
Any
|
it declares such a field, else |
instance_name
¶
Display name for this instance: its discriminator value.
The class label is the fallback when no discriminator is declared or set, since the type is already visible alongside the name everywhere the name is shown, so it isn't repeated in it.
A derived default, not an identity: the persistence layer uses it to seed a blank component name, and users may override it freely. It never feeds physical naming.
Returns:
| Type | Description |
|---|---|
str
|
E.g. |
model_post_init
¶
Default id to a generated UUID if not provided.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
context
|
Any
|
The pydantic validation context, unused here. |
required |
public_fields
¶
Names of the config fields marked x-public.
A public field may be shown wherever the component is, even when the rest of a sensitive kind's config may not.
Returns:
| Type | Description |
|---|---|
frozenset[str]
|
The marked field names. |
resolve
¶
What one of this component's declared relations actually resolves to.
Unlike bound, this reads through the owner (see _targets) and then
falls back to what the relation can fill itself with, so a relation
with a fallback (a config whose every field is defaulted, say) works
without a binding.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The relation name as declared on the class. |
required |
Returns:
| Type | Description |
|---|---|
Any
|
What the relation holds or reads through its owner, otherwise the |
Any
|
relation's fallback for a single-valued relation and an empty list |
Any
|
for a |
resolve_key
¶
resolve_key(
key: str, catalog: Catalog | None = None
) -> type[Self]
Resolve a catalog key to a component class of this (sub)class.
The key is looked up in catalog (or, when none is given, the settings-configured catalog, built lazily), and the class it names is imported.
Called on a subclass, the resolved class must be of that subclass
(Source.resolve_key("facebook_ads")); anything else raises
TypeError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
The catalog key naming the component class. |
required |
catalog
|
Catalog | None
|
The catalog to look the key up in. Defaults to |
None
|
Returns:
| Type | Description |
|---|---|
type[Self]
|
The resolved class. |
Raises:
| Type | Description |
|---|---|
CatalogKeyError
|
If the key is not in the catalog. |
to_spec
¶
to_spec(
*, context: SerializationContext | None = None
) -> Spec
Serialize this instance to a reconstructible spec, relations and owned components included.
What a relation holds sits in init under the relation's name, a
list for a many relation and a single value otherwise, each target
written as SerializationContext.emit decides; a relation with
nothing bound is left out. The components this one owns (see
owned) travel inside this spec, under the field that holds
them, as a map of key to init carrying the child's id: an owned
component never has a spec of its own.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
context
|
SerializationContext | None
|
The state shared with the other roots of one document.
|
None
|
Returns:
| Type | Description |
|---|---|
Spec
|
A Spec capturing this instance's state, identity and bindings. |
unbind
¶
unbind(name: str, *targets: Component) -> None
Detach components from one of this component's declared relations.
Detaching nothing the relation holds is a no-op; otherwise what remains
goes through the same write path as bind, so the same checks
apply (a non-optional relation cannot be emptied, ConfigError).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The relation name as declared on the class. |
required |
*targets
|
Component
|
The components to detach; ones the relation does not hold are ignored. |
required |
validate_relations
¶
validate_relations(
nodes: Mapping[str, Component] | None = None,
) -> None
Check that every relation this component holds is sound.
Three checks per relation: it is bound, unless it is optional or
has a fallback; a single-valued relation holds at most one target; every
bound target is one the relation accepts. When
nodes is given, a bound non-optional asset-kind target must also
be one of nodes.
The check runs at the boundaries where a graph is whole: the DAG runs
it with its nodes once resolution is done, and reconstruction runs it
without nodes on every root of a document once its references are
bound. Without nodes an unbound asset-kind relation only the
graph can fill is left alone: one reaching outside the owner's own
source (local), or any one on an owner that
has no source to fill it from. Nothing before the graph can fill such
a relation, so nothing before the graph can call it unfilled either.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nodes
|
Mapping[str, Component] | None
|
Every node materializing in the same run, keyed by id. When
|
None
|
Raises:
| Type | Description |
|---|---|
ConfigError
|
If any relation is unbound and non-optional, holds several targets while single-valued, holds a target it does not accept, or (when nodes is given) points a non-optional relation at an asset absent from nodes. |
ComponentDefinition
¶
Bases: pydantic.main.BaseModel
Read-only view of a Component class's metadata.
Returned by Component.definition(). Not a separate architectural
entity, just a structured projection of the class for API consumers.
Every kind is self-describing: config_schema is the JSON Schema of
its user-configurable fields, relations the links it declares toward
other components, maturity how far it is from being relied on,
group where the app shows it: its own key, unless the class declares
another, as a star schema does its platform's key. A group is a display
fact, any name; when it is a catalog key, that definition labels it.
model_config
¶
dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)
ComponentIdentity
¶
Bases: builtins.tuple
What a component is, for relation matching: its owning source key and its own key.
source_key is None for a component with no owning source (a
connection, a config, a standalone asset); assets owned by a source
carry that source's key.
of
¶
of(component: Component) -> ComponentIdentity
Build the identity of an already-constructed component.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
component
|
Component
|
The component to identify. |
required |
Returns:
| Type | Description |
|---|---|
ComponentIdentity
|
The component's identity, its parent's key as |
ComponentIdentity
|
it has a parent, |
resolve
¶
resolve(
declared_key: str, *, own_source_key: str | None
) -> ComponentIdentity
The identity a declared relation key expects.
A bare key is scoped to the declaring component's own source, a
qualified key (source.key) names the source explicitly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
declared_key
|
str
|
The relation key as written, bare ( |
required |
own_source_key
|
str | None
|
Key of the source declaring the relation, used to
scope a bare key. |
required |
Returns:
| Type | Description |
|---|---|
ComponentIdentity
|
The expected identity; |
ComponentIdentity
|
bare key, or the part before the dot for a qualified key. |
satisfies
¶
Whether this identity is an acceptable match for a declared key.
A bare key expects a component of the declaring source, a qualified
key a component of the named source, and *.key a component of
that key owned by some source, whichever it is; an identity with no
source never satisfies a wildcard.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
declared_key
|
str
|
The relation key as written on the declaring component. |
required |
own_source_key
|
str | None
|
Key of the source declaring the relation, used to
scope a bare key. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True when the key matches and the source constraint holds. |
Relation
¶
Bases: pydantic.main.BaseModel
One declared link from an owner component to the components that may fill it.
kind and key name the acceptable targets: kind names one or
several component kinds, key (when non-empty) narrows to specific
keys within those kinds, matched through ComponentIdentity.satisfies.
many marks a relation that binds several components at once;
optional marks one that may stay unbound or be left empty, and says
nothing else: on_delete alone decides what deleting a bound target
does, block refusing the deletion while this relation holds the
target and detach letting it through and dropping the binding.
default and has_fallback together describe a relation that can be
resolved without an explicit binding.
A relation is also its own descriptor: Component._collect installs
the stamped copy under the relation's name, so the class attribute reads
as the declaration and the instance attribute as what is bound to it, and
assignment rebinds it.
The declaration form the framework writes pairs the relation with the
annotation of what fills it
(destinations: list[Destination] = Relation("destination", many=True)).
The TYPE_CHECKING __new__ is what makes that form check: the type
checker reads a Pydantic field of the annotated type, so the constructor
kwarg and the instance attribute are both typed, while the runtime sees a
Relation (Pydantic ignores it, and Component._collect drops the
annotation before fields are collected).
Two attributes are not declared but derived. name is stamped from the
attribute the relation is declared under, and target is the class the
Relation(cls) shorthand was written with, the class a fallback is
built from; neither is a constructor argument. default (intended type
Callable[[], Component] | None) and target (intended type
type[Component] | None) are typed Any for the type checker, since
Component is only imported under TYPE_CHECKING; both stay out of
dumps.
Build a relation from either a component class or explicit kind/key values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kind_or_class
|
str | list[str] | type
|
A component class (its |
''
|
key
|
str | list[str]
|
The relation's |
''
|
**data
|
Any
|
Remaining field values ( |
required |
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
has_fallback
¶
Whether this relation can be resolved without an explicit binding.
Three cases, all of them single-valued but for the first: a default
factory is set; the target is a settings class, whose required
fields come from the environment, so a resource the user never bound
is still constructible where it is read; or every field of the
target (besides id) is optional, so the class constructs bare.
Returns:
| Type | Description |
|---|---|
|
True when |
keys
¶
Normalise key to a list.
Returns:
| Type | Description |
|---|---|
|
|
|
|
kinds is accepted), whether declared as a single string or a list. |
kinds
¶
Normalise kind to a list.
Returns:
| Type | Description |
|---|---|
|
|
local
¶
Whether every key this relation declares names a component of the owner's own source.
A bare key ("orders") is scoped to the declaring component's own
source, so that source is the authority on what fills it; a qualified
or wildcard key ("shop.orders", "*.orders") reaches outside it,
and only the graph of a run can say what fills it.
Returns:
| Type | Description |
|---|---|
|
True when the relation declares at least one key and none of them |
|
|
is qualified; False for a relation declaring no key at all, which |
|
|
accepts any key of its kinds wherever it comes from. |
model_config
¶
dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)
target
¶
The component class this relation was declared from, if it was declared from one.
Returns:
| Type | Description |
|---|---|
|
The class given to |
accepts
¶
accepts(
kind: str,
identity: ComponentIdentity,
*,
owner: ComponentIdentity,
) -> bool
Whether a candidate component may fill this relation.
A bare key is scoped to the owner's source only when the candidate
is an asset: an asset is the one kind whose key is source-local.
Every other candidate kind is keyed globally by its catalog key, so a
bare key there names that class wherever it comes from. Scoping by
the relation's declared kinds instead of the candidate's own would
wrongly scope a source or destination candidate to the owner's source
the moment the relation also accepts assets (a job's targets,
say).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kind
|
str
|
The candidate component's kind. |
required |
identity
|
ComponentIdentity
|
The candidate component's identity. |
required |
owner
|
ComponentIdentity
|
The identity of the component declaring this relation, used to scope bare keys. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True when |
bool
|
non-empty, |
fallback
¶
Produce the value this relation resolves to when left unbound.
A settings target is constructed here and not at build time, which is what keeps a connection whose credentials live in the environment usable: the validation error of a credential that is neither bound nor in the environment propagates from the read that needed it.
Returns:
| Type | Description |
|---|---|
Any | None
|
A fresh |
Any | None
|
target constructs on its own, or |
Any | None
|
no fallback. |
from_annotation
¶
from_annotation(
hint: Any, namespace: dict[str, Any]
) -> Relation | None
Build the relation an annotation declares, when it declares one.
Recognised shapes are a component class (connection: PostgresConnection),
a forward reference to one, and the optional forms X | None and
Optional[X]. Anything else is not a relation and stays an ordinary
field: a scalar, a container, and Component itself, which names no
kind and so cannot say what would fill the relation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
hint
|
Any
|
The annotation as written, already evaluated or still the
forward-reference string |
required |
namespace
|
dict[str, Any]
|
The namespace a forward reference resolves against, normally the declaring class's module globals. |
required |
Returns:
| Type | Description |
|---|---|
Relation | None
|
A relation targeting the annotated class, |
Relation | None
|
annotation admits |
Relation | None
|
declares no relation. |
Maturity
¶
Bases: builtins.str, enum.Enum
How far a component is from being relied on in production.
Informational: it is shown beside the component wherever it is offered
and never changes what the component does. ALPHA is early work whose
behaviour, configuration and output may still change and that has not
been proven against a live service; BETA works and is being proven,
with changes still possible; STABLE, the default, is relied on;
DEPRECATED still works but is being phased out, so new setups should
avoid it.
A composite, such as an asset inside its source, shows the
least mature of its parts, DEPRECATED counting as the least:
a deprecated source deprecates its assets, and a deprecated asset stays
deprecated whatever its source.
ALPHA
¶
How far a component is from being relied on in production.
Informational: it is shown beside the component wherever it is offered
and never changes what the component does. ALPHA is early work whose
behaviour, configuration and output may still change and that has not
been proven against a live service; BETA works and is being proven,
with changes still possible; STABLE, the default, is relied on;
DEPRECATED still works but is being phased out, so new setups should
avoid it.
A composite, such as an asset inside its source, shows the
least mature of its parts, DEPRECATED counting as the least:
a deprecated source deprecates its assets, and a deprecated asset stays
deprecated whatever its source.
BETA
¶
How far a component is from being relied on in production.
Informational: it is shown beside the component wherever it is offered
and never changes what the component does. ALPHA is early work whose
behaviour, configuration and output may still change and that has not
been proven against a live service; BETA works and is being proven,
with changes still possible; STABLE, the default, is relied on;
DEPRECATED still works but is being phased out, so new setups should
avoid it.
A composite, such as an asset inside its source, shows the
least mature of its parts, DEPRECATED counting as the least:
a deprecated source deprecates its assets, and a deprecated asset stays
deprecated whatever its source.
DEPRECATED
¶
How far a component is from being relied on in production.
Informational: it is shown beside the component wherever it is offered
and never changes what the component does. ALPHA is early work whose
behaviour, configuration and output may still change and that has not
been proven against a live service; BETA works and is being proven,
with changes still possible; STABLE, the default, is relied on;
DEPRECATED still works but is being phased out, so new setups should
avoid it.
A composite, such as an asset inside its source, shows the
least mature of its parts, DEPRECATED counting as the least:
a deprecated source deprecates its assets, and a deprecated asset stays
deprecated whatever its source.
STABLE
¶
How far a component is from being relied on in production.
Informational: it is shown beside the component wherever it is offered
and never changes what the component does. ALPHA is early work whose
behaviour, configuration and output may still change and that has not
been proven against a live service; BETA works and is being proven,
with changes still possible; STABLE, the default, is relied on;
DEPRECATED still works but is being phased out, so new setups should
avoid it.
A composite, such as an asset inside its source, shows the
least mature of its parts, DEPRECATED counting as the least:
a deprecated source deprecates its assets, and a deprecated asset stays
deprecated whatever its source.
KINDS
¶
Name → object registry, optionally fed by an entry-point group.
Entries register explicitly via register, or are loaded lazily
from group on first lookup. Registration is first-wins and idempotent.
adopt transforms a loaded entry into its (name, object) pair —
the default keeps the entry name and object as declared.
One installed package never takes the others down: an entry point that fails to load or adopt is skipped with a warning naming it. Without adopt, an entry's name is its key, so a lookup by name loads only the entry points declared under that name; a listing loads them all.
Registry
¶
Bases: typing.Generic
Name → object registry, optionally fed by an entry-point group.
Entries register explicitly via register, or are loaded lazily
from group on first lookup. Registration is first-wins and idempotent.
adopt transforms a loaded entry into its (name, object) pair —
the default keeps the entry name and object as declared.
One installed package never takes the others down: an entry point that fails to load or adopt is skipped with a warning naming it. Without adopt, an entry's name is its key, so a lookup by name loads only the entry points declared under that name; a listing loads them all.
Initialize the registry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group
|
str | None
|
Entry-point group to load lazily; |
None
|
adopt
|
Callable[[str, Any], tuple[str, T]] | None
|
Optional transform from a loaded entry to its
|
None
|
get
¶
Look up an entry by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The registry key. |
required |
Returns:
| Type | Description |
|---|---|
T | None
|
The registered object, or |
items
¶
All registered entries.
Returns:
| Type | Description |
|---|---|
tuple[tuple[str, T], ...]
|
|
keys
¶
All registered names.
Returns:
| Type | Description |
|---|---|
tuple[str, ...]
|
The names, sorted. |
register
¶
Register entry under name (first-wins, idempotent).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The registry key. |
required |
entry
|
T
|
The object to register; ignored when the name is taken. |
required |
values
¶
All registered objects.
Returns:
| Type | Description |
|---|---|
tuple[T, ...]
|
The objects, ordered by name. |