Pydantic
Pydantic's validation core, on typed refinements
Released —
v0.1.0(validation core).goforge.dev/gpydanticis a Go+ reimplementation ofpydantic/pydantic’s v2 validation core, built as the second consumer ofstd/validate. Field constraints compile to typed refinement rules; failures project back into pydantic’s error shape (type/loc/msg/ctx). Install withgo get goforge.dev/gpydantic@v0.1.0.
GoForge Pydantic targets pydantic v2’s constraint and model surface. A model is a
named set of field rules over a Go struct; validating a value returns either
nothing or a *ValidationError whose entries reproduce pydantic’s documented
type codes and message templates exactly.
What it proves
gpydantic is the second consumer of std/validate — the refinement core
first shipped for Validator. Standing up a genuinely different
consumer is what forced the core to grow: pydantic’s Optional[T] and Union
have no expression in a validation algebra that only knows conjunction, so
std/validate gained a disjunction axis to admit them.
Optional[T]→Nullable, a nil-biased disjunction: a present-but-invalid field reports only its inner constraint, never a spurious “should be absent”.- constrained
Union→AnyOfover the symmetric disjunctionOr: a value satisfying no arm reports every arm it failed, matching pydantic’s union error.
Both connectives carry an erased dependent index kept collision-free from conjunction over the same operands, so an optional or union proof can never be mistaken for a required one.
Constraint mapping
Gt, Ge, Lt, Le, MultipleOf, MinLength, MaxLength, and Pattern
compile to std/validate atoms carrying pydantic’s exact type
(greater_than, string_too_short, string_pattern_mismatch, …) and ctx
keys (gt, min_length, …). Models compose via And/At; Validate collects
every field failure in declaration order, as pydantic does. Message templates —
including 1 character / N characters pluralization — are pinned by
differential tests against pydantic v2.
Scope
This release is the validation core, not full pydantic parity, and the page says
so plainly. In scope: numeric and string constraints, optional/nullable fields,
constrained unions, model composition, and the pydantic-shaped aggregate
ValidationError. Tracked out of scope (not faked): input coercion / parsing
from untyped data, JSON-Schema generation, serialization, custom
field_validators, the input/url fields on error entries, and pydantic-v1
compatibility.
Go+ authorship
The refinement layer — constraints, optionality, model composition, and error
projection — is authored in *.gp and reproducibly generates version-marked Go;
goplus gen -check is clean against released std/v0.207.0. The one variadic
union fold lives in plain Go against the index-erased runtime, because a
dependent index is a fixed-arity fact: fixed-arity indexed composition is
authored in Go+, variadic composition over the erased surface is not.
Notes
Faithful to pinned upstream MIT provenance (© pydantic contributors). This is an independent Go+ implementation reproducing pydantic v2’s documented error surface, not vendored pydantic source.