error module#
Errors#
Everything this package raises. All of it is reported against user code rather than as an internal runtime fault, and the ones a design author can act on carry a hint naming the remedy. PartsError is the base, so catching it catches all of them.
Writing a provider, one of these is yours to raise: StalePayload, from rehydrate, when a lock entry predates a change you cannot honour. It never reaches the user – the resolver records it and re-resolves the query from the chain. Nothing else here is a provider’s to raise; ProviderContractError is what the core raises about a provider.
Reading a failure, the split worth knowing is whose fault it names. A fault in the design comes with the remedy in its hint: PartNotFound, PartDenied, PolarityMismatch. A fault in configuration means nothing has been asked yet or the lock cannot be used at all: NoChainConfigured, LockStale. A fault in a provider is not the design author’s to fix: ProviderContractError, ProviderUnavailable, and NestedDeferral where a provider’s materialize is what deferred. Only the first group should ever be the first thing a design author reads.
UnresolvedPart and ResolverLostQuery sit apart from all three: they are raised by a read rather than by resolution, when something touches a field on a component whose query never produced a part. They are the only two that are also AttributeError, because they come out of __getattr__ and a probe there has to be able to catch them. Which of the two you get says where to look: UnresolvedPart means the run reported the failure and parts_verdict() explains it, ResolverLostQuery means it did not, which is a bug here.
DimensionMismatch sits across that split on purpose. A query in the wrong unit and a provider reporting one are equally likely, so it names the attribute and both dimensionalities instead of picking a culprit.
QueryUnlocked is the odd one: a verdict category that has an exception class so a driver can turn a failing verdict into a raise.
- exception PartsError(message, hint=None)[source]#
Bases:
UserCodeExceptionBase for every error this package raises.
- exception PartNotFound(description, reasons)[source]#
Bases:
PartsErrorNo provider in the chain matched the query.
Carries each provider’s own reason, in chain order, because “no match” from a four-member chain is four different facts.
- exception PartDenied(provider, reason, description)[source]#
Bases:
PartsErrorA provider vetoed the query, so the chain stopped rather than falling through.
A veto is not an absence: something in the chain has an opinion about this query being asked at all, and a later provider answering it would defeat the point.
- exception DimensionMismatch(key, a, b)[source]#
Bases:
PartsErrorA predicate and a value have different dimensionality.
A bug rather than a non-match, and deliberately does not presume whose: a design querying the wrong unit and a provider reporting one are equally likely, so the message names the attribute and both dimensions.
- exception StalePayload(message, hint=None)[source]#
Bases:
PartsErrorA provider cannot rehydrate a payload it wrote earlier.
Raise this from rehydrate when a lock entry predates a change the provider cannot honour. The resolver re-resolves the query from the chain and records the event; it never reaches the user as an exception.
Bases:
PartsErrorA lock entry names a provider that cannot be reached.
Not a missing chain member: chain membership is in the key, so an unresolvable chain fails before any entry is looked up. What reaches here is a delegating provider whose inner routing names something absent, or a hand-edited entry.
Disposition is StalePayload’s when it arises during replay: it happens at the same point in the same operation, so it is recorded as a replay failure and the query re-resolves.
Also raised, and not caught, when a chain names a provider string that no installed package supplies. That one is not a replay failure and there is nothing to fall back to: the chain cannot be built at all.
- exception ProviderContractError(message, hint=None)[source]#
Bases:
PartsErrorA provider returned something that violates the protocol.
A part missing its category’s value_key, a materialize that replaced ports, a config() that is not canonical JSON, an attribute in the wrong unit. Names the provider, not the user.
- exception NestedDeferral(message, hint=None)[source]#
Bases:
PartsErrorA part was deferred while parts were binding.
Raised when a provider’s materialize, or any PartsResolved handler, constructs a component that itself resolves through a chain. Build such a part in the owning circuit and hand it to materialize, or give the provider concrete geometry.
- exception PolarityMismatch(mpn, provider)[source]#
Bases:
PartsErrorA plain Capacitor resolved to a part marked polarized.
Named against the user rather than the provider: the provider answered the query it was given, and the query was the wrong shape. The message offers the two remedies that exist: PolarizedCapacitor, or polarized=Exactly(False) where the catalogue marks polarity on every row.
- exception LockStale(found, expected)[source]#
Bases:
PartsErrorThe lock predates the current digest_version, so nothing in it matches.
Tells the reader to regenerate rather than implying the design changed. Not raised for an unrecognized chain: that is a stale-chain group, recorded and reported at the end of the run.
- exception NoChainConfigured(root=None)[source]#
Bases:
PartsErrorNo provider chain is configured, at any precedence level.
Not an empty chain and not a guess: discovery is opt-in, so this is the error a project gets when it has said nothing.
- Parameters:
root (object)
- exception UnresolvedPart(component, name, description, reason, origin)[source]#
Bases:
PartsError,AttributeErrorA component’s part never resolved, and something read a field off it.
Raised by the reading attribute access, not by the resolver: an unresolvable query is recorded and the run continues to its summary, so the raise happens wherever the design first touches the part that was never bound. The message carries the query, the chain’s own reason, and where the component was constructed, because none of that is recoverable from the read site.
Both PartsError and AttributeError on purpose. It comes out of __getattr__, where anything that is not an AttributeError breaks hasattr, getattr(obj, name, default), copy, pickle and every structural probe that expects a missing name to be answerable rather than fatal. Being a PartsError too is what lets a driver tell this apart from a typo, which a bare AttributeError never could.
- exception ResolverLostQuery(component, name, description, origin)[source]#
Bases:
PartsError,AttributeErrorA query reached no code path at all: a bug in this package, not the design.
Distinguished from UnresolvedPart because the remedies have nothing in common. An unresolvable query was handled and failed, and the verdict explains it. A query that was dropped produces no event of any kind, so the run’s own report cannot see the hole and reports success while a component sits unbound. That has happened once already – the adoption sweep keyed one state per question and silently discarded duplicates – and it surfaced as a missing attribute far from its cause. Naming it makes the next one announce itself.
An AttributeError for the same reason UnresolvedPart is: it is raised from __getattr__, and a probe there must not be handed something it cannot catch.
- exception QueryUnlocked(description='')[source]#
Bases:
PartsErrorA pinned mode met a query the lock cannot answer.
Under a pinned mode the miss is recorded and the run continues; the failure arrives through parts_verdict()’s exit status. Raise this from a driver that wants a failing verdict to become an exception.
- Parameters:
description (str)