typing_validation.diagnosis
Explaining a failure, after the fact.
The validators fail hard and say only that they failed. Everything a user reads
about why is produced here, by a slower second traversal of the same
(val, t). This is the single most valuable consequence of the architecture:
because diagnostics are produced in exactly one place, there is exactly one
implementation of them — so the conformance obligation between mechanisms reduces
to “do they agree on the boolean”, which is a far smaller thing to police than
“do they agree on the message”.
And because this runs only on a failure, which is by definition exceptional, it may be as slow, allocating and thorough as it likes — where its costs stop mattering and its quality is the entire point.
The second traversal is sound only because validation is pure: the value handed here is the value the validator saw, undisturbed.
Detail
- final class Detail(*values)[source]
Bases:
EnumWhy one node of a failure tree failed.
- IN_COMPONENT = 'a component failed'
This node is fine in itself; something inside it is not. The causes say what, and their locations say where.
- MISSING_KEY = 'missing required key'
A
TypedDictrequired key that is absent.
- NON_STRING_KEY = 'key is not a string'
A
TypedDictkey that is not a string.
- NOT_AN_INSTANCE = 'not an instance'
The value is not an instance of the type, or of the type’s origin.
- NOT_A_CLASS = 'not a class'
Type[T]was given something that is not a class.
- NOT_A_NAMED_TUPLE = 'not a named tuple'
Bare
typing.NamedTuplewas given something that is not one.
- NOT_A_SUBCLASS = 'not a subclass'
Type[T]was given a class that does not derive fromT.
- NOT_NONE = 'not None'
The type is
Noneand the value is not.
- NO_LITERAL = 'no matching literal'
The value equals none of the literals, at its own type.
- NO_UNION_MEMBER = 'no member matched'
Every member of a union failed. The causes say how each one did.
- PLUGIN_REJECTED = 'rejected by plugin'
A plugin’s own check said no, and offered no further detail.
- WRONG_LENGTH = 'wrong length'
A fixed-length tuple of the wrong size.
DiagnosisFailure
- final class DiagnosisFailure[source]
Bases:
RuntimeErrorRaised when a validator reports a failure that diagnosis cannot reproduce.
This is a library bug — a mechanism has drifted from the catalogue — and it is reported as one. Diagnosis must never answer a reported failure with an implicit “actually, it’s fine”: the failure is not swallowed, and no validation error is quietly downgraded to success.
Location
Place
- final class Place(*values)[source]
Bases:
EnumWhat kind of position a failure occupies within its parent value.
- FIELD = 'field'
A named field of a
TypedDictor named tuple.
- INDEX = 'index'
A position in an ordered collection, which is addressable.
- KEY = 'key'
A mapping key that is itself invalid.
- MEMBER = 'union member'
One alternative of a union, all of which failed.
- POSITION = 'position'
A position in an unordered collection.
Iteration order is not stable across runs, so this is a witness that something failed, not an address the user can go to. It must be reported as such rather than implying a location.
- VALUE_AT = 'value at key'
The value stored under a mapping key.
- WRAPPED = 'wrapped type'
What an alias,
Annotated,NewTypeor type variable resolves to.The wrapper is not transparent: it reports as itself and the cause reports what it stands for.
ValidationFailure
- final class ValidationFailure(val, t, detail, location=None, causes=())[source]
Bases:
objectOne node of a failure tree: a value, the type it failed against, why, and what failed inside it.
Nothing here recurses over
causes, and that is not fastidiousness. A failure tree is as deep as the value, so the generated__repr__and__eq__would raiseRecursionErroron exactly the deeply nested values the rest of this library goes out of its way to handle — turning an ordinary failure into a stack overflow at the moment someone tries to look at it. So they are turned off and replaced with iterative equivalents.- causes
The failures inside this one.
- Return type:
- detail
Why it failed.
- Return type:
- t
The type it failed against.
- Return type:
- val
The value that failed.
- Return type:
diagnose
- diagnose(val, t, /)[source]
Explain why a value is not valid for a type.
- Raises:
DiagnosisFailure – if the value turns out to be valid after all, which means a mechanism has drifted from the specification.
- Parameters:
- Return type: