Code generation¶
The lairs._codegen package drives vendored lexicon JSON through
panproto parsing, a schema-to-spec mapping, and module emission, writing
one committed module per pub.layers.* namespace into
lairs.records._generated. The generated modules are never hand-edited.
Edit this pipeline instead. See generated models
for the rationale.
Pipeline¶
The top-level driver. generate writes the modules and check powers
the lairs gen --check drift gate.
lairs._codegen.pipeline ¶
Top-level codegen pipeline.
Drives lexicon JSON through panproto parsing, the Schema-to-spec mapping, and
module emission, writing one committed module per pub.layers.* namespace
into :mod:lairs.records._generated. Cross-namespace embeds (for example
annotation embedding defs#anchor) are resolved to imports so each module
type-checks in isolation. The check entry powers the lairs gen --check
drift gate.
generate ¶
Generate model modules from a vendored lexicon tree.
| PARAMETER | DESCRIPTION |
|---|---|
lexicon_root
|
The root of the vendored lexicon tree (the directory that contains the
TYPE:
|
out_root
|
The output directory for emitted modules, normally
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list of pathlib.Path
|
The paths of the generated module files, in stable order. |
check ¶
Check whether committed modules match a fresh generation.
| PARAMETER | DESCRIPTION |
|---|---|
lexicon_root
|
The root of the vendored lexicon tree.
TYPE:
|
out_root
|
The directory holding the committed generated modules.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
|
namespace_specs ¶
namespace_specs(
lexicon_root: Path,
) -> dict[str, list[ModelSpec]]
Return the codegen specs for each namespace, for inspection and tests.
| PARAMETER | DESCRIPTION |
|---|---|
lexicon_root
|
The root of the vendored lexicon tree.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
dict of str to list of lairs._codegen.schema_to_spec.ModelSpec
|
A mapping of namespace name to its specs. |
Schema to spec¶
Fuses a parsed panproto Schema with its lexicon document into the
codegen intermediate representation: ModelSpec, FieldSpec, and
VariantSpec value models, one per record, object, or formal union.
lairs._codegen.schema_to_spec ¶
Walk a panproto Schema into lairs codegen spec models.
The parsed Schema retains union discriminators, refined value types, the
reference-versus-containment edge distinction, and integer ranges, all of which
the lossy theory_of path would drop. The lexicon JSON document retains the
field descriptions and the required set that panproto does not surface. This
module fuses both sources into a sequence of :class:ModelSpec value models,
one per record or object definition and one per formal union definition, which
the emitter renders to committed Python module text.
Notes
Every spec type here is a dx.Model; the codegen intermediate representation
is data, like everything else in lairs. The synthesised-model round-trip path
(didactic.models_from_specs) is intentionally not used for emission because
it discards descriptions, defaults, optionality, refined value types, and the
reference-versus-embed distinction. The emitter renders the rich spec directly.
FieldSpec ¶
Bases: Model
A single field of a generated model.
| ATTRIBUTE | DESCRIPTION |
|---|---|
name |
The lexicon property name, used verbatim as the python attribute name.
TYPE:
|
type_kind |
The resolved field shape, one of
TYPE:
|
target |
For
TYPE:
|
item |
For the
TYPE:
|
required |
Whether the lexicon lists this property in its
TYPE:
|
description |
The lexicon
TYPE:
|
string_format |
The lexicon
TYPE:
|
known_values |
The lexicon
TYPE:
|
minimum |
The lexicon
TYPE:
|
maximum |
The lexicon
TYPE:
|
min_length |
The lexicon
TYPE:
|
max_length |
The lexicon
TYPE:
|
VariantSpec ¶
Bases: Model
A single member of a formal union definition.
| ATTRIBUTE | DESCRIPTION |
|---|---|
discriminator_value |
The value the union discriminator takes for this variant, derived from the member reference shortname.
TYPE:
|
class_name |
The python class name of the variant model.
TYPE:
|
target |
The name of the embedded member model the variant wraps.
TYPE:
|
ModelSpec ¶
Bases: Model
A generated model or union, ready for emission.
| ATTRIBUTE | DESCRIPTION |
|---|---|
name |
The python class name (the capitalised lexicon definition shortname).
TYPE:
|
nsid |
The source lexicon namespace identifier (for example
TYPE:
|
def_name |
The lexicon definition shortname (for example
TYPE:
|
is_record |
Whether the definition is a top-level
TYPE:
|
is_union |
Whether the definition is a formal
TYPE:
|
discriminator |
For unions, the discriminator field name.
TYPE:
|
description |
The lexicon
TYPE:
|
fields |
The model fields, for non-union models.
TYPE:
|
variants |
The union members, for unions.
TYPE:
|
schema_to_specs ¶
Map a parsed Schema plus its lexicon document to codegen spec models.
| PARAMETER | DESCRIPTION |
|---|---|
schema
|
A Schema parsed from a lexicon document under the atproto protocol.
TYPE:
|
document
|
The raw lexicon JSON document the Schema was parsed from. It supplies
the
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
collections.abc.Sequence of lairs._codegen.schema_to_spec.ModelSpec
|
One spec per record, object, and formal union definition in the lexicon, with descriptions, optionality, refined types, integer ranges, knownValues, and union discriminators preserved. Method definitions (query, procedure, subscription) are skipped. |
Emit¶
Renders the spec models into deterministic, committed module source text with a generated-by header and the source manifest hash.
lairs._codegen.emit ¶
Emit Python module text for generated models.
Renders :class:~lairs._codegen.schema_to_spec.ModelSpec value models into
committed module source text with a generated-by header and the source manifest
hash. Emission is deterministic (stable class ordering and stable field
ordering) so the lairs gen --check drift gate is meaningful. The emitted
modules are the import surface of :mod:lairs.records; they are rich didactic
models carrying descriptions, optionality, refined value types, integer ranges,
knownValues, and union discriminators, which the lossy spec-synthesis path could
not reconstruct.
emit_module ¶
emit_module(
specs: Sequence[ModelSpec], *, manifest_hash: str
) -> str
Render record and union specs to Python module source text.
| PARAMETER | DESCRIPTION |
|---|---|
specs
|
The specs for one namespace, already ordered so embed targets precede the models that embed them.
TYPE:
|
manifest_hash
|
The content hash of the source lexicon tree, recorded in the header so the committed module records the lexicon revision it was generated from.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str
|
The module source text, with a generated-by header, the manifest hash,
a module docstring, imports, the emitted classes, and an |
Manifest¶
The vendoring manifest model and loader. The lexicon_tree_hash is
stamped into every emitted module.
lairs._codegen.manifest ¶
Vendoring manifest model and loader.
lairs/lexicons/MANIFEST.toml records the provenance of the vendored lexicon
tree: the upstream Layers revision, the vendoring date, and a content hash of
the tree. The runtime representation is a :class:Manifest didactic model; this
module loads the TOML form into that model. The lexicon_tree_hash is stamped
into every emitted module so a generated file records the lexicon revision it
came from.
Manifest ¶
Bases: Model
Provenance of the vendored lexicon tree.
| ATTRIBUTE | DESCRIPTION |
|---|---|
layers_git_sha |
The upstream Layers git revision the tree was vendored from.
TYPE:
|
layers_version |
The upstream Layers release version.
TYPE:
|
vendored_at |
The ISO date the tree was vendored.
TYPE:
|
lexicon_tree_hash |
A content hash of the vendored lexicon tree, stamped into emitted modules so a generated file records its source revision.
TYPE:
|
lexicon_files |
The number of vendored lexicon JSON files.
TYPE:
|
record_types |
The number of record definitions across the tree.
TYPE:
|