Skip to main content

pyrixos-espalier

Data models validated from type annotations, in Python with no compiled code and no dependencies. Espalier implements the part of the pydantic 2 API that typed configuration files and wire formats use, so code written against that part runs with from espalier import ... in place of from pydantic import ....

PyrixOS uses it in Lattice, Cloche and Trellis, so that its build tools install without Rust or C extensions.

pip install pyrixos-espalier
from typing import Annotated, Literal

from espalier import BaseModel, ConfigDict, Field, ValidationError


class Mount(BaseModel):
    model_config = ConfigDict(frozen=True, extra="forbid", strict=True)

    source: str = Field(min_length=1)
    target: str
    mode: Literal["ro", "rw"] = "ro"
    size: Annotated[int, Field(ge=0)] = 0


mount = Mount.model_validate_json('{"source": "/a", "target": "/b"}')
print(mount.model_dump_json())  # {"source":"/a","target":"/b","mode":"ro","size":0}

try:
    Mount(source="", target="/b", size=-1)
except ValidationError as error:
    print(error)

What it supports

  • BaseModel with model_validate, model_validate_json, model_dump, model_dump_json, model_copy, model_construct, model_rebuild, model_fields, model_fields_set, model_extra and model_computed_fields. Models compare equal by class and fields, frozen models hash, and models copy and pickle.
  • ConfigDict keys frozen, extra (ignore, forbid, allow), strict, alias_generator, populate_by_name, validate_by_name, validate_by_alias, serialize_by_alias, arbitrary_types_allowed and title. A subclass's config is merged over its bases'.
  • Field with defaults, default factories, aliases, exclude, repr, strict, discriminator and the constraints gt, ge, lt, le, multiple_of, min_length, max_length and pattern, as a default or inside Annotated.
  • field_validator (before, after, plain), model_validator (before, after, wrap), BeforeValidator, AfterValidator, PlainValidator, PlainSerializer and computed_field. Validators may take a ValidationInfo with mode, field_name and data.
  • TypeAdapter for any supported type, with validate_python, validate_json, dump_python and dump_json.
  • The types int, float, str, bool, bytes, None, Any, enums, Literal, unions, Optional, discriminated unions, datetime.datetime, datetime.date, pathlib paths, list, tuple (fixed and variable length), set, frozenset, dict, Mapping, type[...], NewType, type aliases, nested and recursive models and forward references. Other classes are checked with isinstance.
  • Strict and lax modes with pydantic's conversion rules, including JSON input in strict mode giving lists for tuples and sets, and strings for enums and datetimes. strict= on a validate call replaces the strict of the model's config and of the models in it.
  • ValidationError, a ValueError, with pydantic's error types, locations and messages and the same text layout.

Differences from pydantic

  • No JSON Schema generation, no BaseSettings, no dataclass support, no generic models, and no context passed to validators.
  • The error for invalid JSON quotes Python's json module, and other parse errors (datetime, date) quote the standard library's message.
  • Error text has no documentation link lines.
  • A UTC datetime read from JSON has datetime.timezone.utc as tzinfo.
  • An instance given where a model is expected is used as it is, not revalidated, as with pydantic's default revalidate_instances.
  • Validation runs in Python. Validating or dumping a model is about 5 to 7 times slower than with pydantic-core; for configuration files and protocol messages this is well under a millisecond each.

Migrating from pydantic

Replace pydantic with espalier in imports, and pydantic.alias_generators with espalier.alias_generators. Code that sets __pydantic_*__ attributes or calls pydantic-core directly needs changes; Espalier never calls a nested model's __init__, so a model that overrides __init__ is validated by its outer model without it.

Development

pip install --group dev
pip install -e .
pybootstrap check

The tests record the types and messages pydantic gives for the same input.

License

GPL-2.0-only. See LICENSE.

Metadata

Release files for pyrixos-espalier 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyrixos-espalier 1.0.0
File Size Uploaded Provenance Actions
pyrixos_espalier-1.0.0.tar.gz 35.7 kB With provenance Details for pyrixos_espalier-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pyrixos-espalier 1.0.0
File Interpreter ABI Platform Actions
pyrixos_espalier-1.0.0-py3-none-any.whl Python 3 none any Details for pyrixos_espalier-1.0.0-py3-none-any.whl

Total release size: 68.2 kB

Release files / pyrixos_espalier-1.0.0.tar.gz

Download URL pyrixos_espalier-1.0.0.tar.gz
Size 35.7 kB
Tags Source
SHA-256 checksum
How to use checksums
ff96c89422d430acd44991890f32a7a4e78de00c3b82420d0fbbbb536e1e1425
BLAKE2b-256 checksum
How to use checksums
a887821108c7b5b27a62918946cbfc4e35ce9c45c2b621d44d6799dbb0f6f9a3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Release files / pyrixos_espalier-1.0.0-py3-none-any.whl

Download URL pyrixos_espalier-1.0.0-py3-none-any.whl
Size 32.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c0e638eb1d0a7368a2c0843e9b3552a548bc0d5ca878483823ea446849518b90
BLAKE2b-256 checksum
How to use checksums
70b7a7877749b1545f4a08a41d7b133c67ebc45db1c19b2f58df6b1bcc94bff9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Security for pyrixos-espalier 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pyrixos_espalier-1.0.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page