GoForge — Build | Test | Ship | Collaborate GoForge — Build | Test | Ship | Collaborate
v0.1.0

Pydantic

Pydantic's validation core, on typed refinements

$ go get goforge.dev/gpydantic@v0.1.0

Released — v0.1.0 (validation core). goforge.dev/gpydantic is a Go+ reimplementation of pydantic/pydantic’s v2 validation core, built as the second consumer of std/validate. Field constraints compile to typed refinement rules; failures project back into pydantic’s error shape (type/loc/msg/ctx). Install with go 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 → AnyOf over the symmetric disjunction Or: 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.