wend.pydantic¶
Pydantic integration (optional dependency: pip install 'wend[pydantic]').
Two kinds of field metadata, for typing.Annotated:
-
PathOf(expr): the field holds a path ofexpr's layout. A path given as input must matchexpr; bindings given as input (a mapping, or an object such as another model) are rendered through it, which resolves the path at validation time, as Pydantic'sImportStringimports. Either way,expr's preconditions (requires) are then checked against the filesystem::class Job(BaseModel): shard: Annotated[Path, PathOf(shard.requires(File, Exists))] last: Annotated[Match, PathOf(shard)] # the path and its bindings
-
wend's conditions themselves (
File,Dir,Exists,Absent,Readable,Writable,Creatable,Listable, andUnderwith a static base) validate a path field:Annotated[Path, File, Exists]is Pydantic'sFilePath. They work without importing this module, which they load when Pydantic asks for their schema.
The field's type decides the validated value: Path (or another
PurePath class), str, or Match for the path with its bindings. In
JSON, every one of them is the path string.
Checks touch the filesystem when the model is validated, and describe it at that moment (docs/SEMANTICS.md ยง10): validation is an effect here.
PathOf
¶
PathOf(expr: Any)
Field metadata: the value is a path of expr (an expression, a
union, or anything P takes).
- A path (
str,os.PathLikeorMatch) must have exactly one reading byexpr; no reading and several readings are validation errors. - Anything else is bindings (see
wend.bindings), rendered throughexpr. Defaults apply as they do inrender.
Then expr's preconditions are checked with the bindings
(PathExpr.check); a Match result carries those bindings.
expr
instance-attribute
¶
expr: PathExpr | PathUnion = (
expr if isinstance(expr, PathUnion) else _coerce(expr, at_head=True)
)