Code generation¶
Emitter framework¶
didactic.codegen.Emitter ¶
Bases: Protocol
The protocol every custom emitter implements.
| ATTRIBUTE | DESCRIPTION |
|---|---|
file_extension |
A class-level attribute naming the canonical filename
extension for this emitter (
TYPE:
|
Notes
Implement either or both of emit_class
(Model class -> bytes) and emit_instance
(Model instance -> bytes). Calls to the missing direction raise
NotImplementedError.
didactic.codegen.IndentWriter ¶
A small buffer with managed indentation for emitter authors.
Mirrors panproto_protocols::emit::IndentWriter from the
panproto Rust crate. Use as the standard helper for emitting
nested format text.
| PARAMETER | DESCRIPTION |
|---|---|
indent_str
|
The string used for each indent level. Defaults to four spaces.
TYPE:
|
Examples:
>>> w = IndentWriter()
>>> w.line("class Foo:")
>>> with w.indent():
... w.line("x: int")
>>> w.text_str()
'class Foo:\\n x: int\\n'
didactic.codegen.emitter ¶
Register a class as the emitter for name.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
The target name (e.g.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
decorator
|
A class decorator that calls register_emitter with an instance of the decorated class. |
Examples:
JSON Schema¶
didactic.codegen.json_schema_of ¶
json_schema_of(cls: type[Model]) -> JsonSchemaDoc
Bulk export¶
didactic.codegen.write ¶
write(
models: Iterable[type[Model]],
targets: Mapping[str, str],
*,
filename: str = "{model_name}.{ext}",
) -> dict[str, Path]
Emit each model under each target, writing files to disk.
| PARAMETER | DESCRIPTION |
|---|---|
models
|
The Model classes to emit.
TYPE:
|
targets
|
Mapping of
TYPE:
|
filename
|
A format string for filenames. Available placeholders:
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
dict
|
Map of |
| RAISES | DESCRIPTION |
|---|---|
LookupError
|
If |
Instance-level emit¶
didactic.codegen.io.emit ¶
emit(protocol: str, instance: Model) -> bytes
Encode instance as bytes in the named protocol.
| PARAMETER | DESCRIPTION |
|---|---|
protocol
|
A panproto protocol name (e.g.
TYPE:
|
instance
|
A Model instance.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bytes
|
The encoded bytes. |
| RAISES | DESCRIPTION |
|---|---|
IoError
|
If the codec rejects the instance (mismatch with the Model's Theory, value out of range, etc.). |
didactic.codegen.io.parse ¶
Decode data from protocol back to a Model instance.
| PARAMETER | DESCRIPTION |
|---|---|
protocol
|
A panproto protocol name.
TYPE:
|
data
|
The encoded bytes.
TYPE:
|
schema
|
The expected Model class. The decoded payload is validated against this class.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Model
|
A new |
| RAISES | DESCRIPTION |
|---|---|
IoError
|
If the codec cannot decode |
didactic.codegen.io.list_protocols ¶
List the supported instance-protocol names.
| RETURNS | DESCRIPTION |
|---|---|
list of str
|
Every codec the running panproto build registers, sorted. |
didactic.codegen.io.check_round_trip ¶
check_round_trip(protocol: str, instance: Model) -> None
Assert that parse(emit(instance)) == instance for protocol.
| PARAMETER | DESCRIPTION |
|---|---|
protocol
|
A panproto protocol name.
TYPE:
|
instance
|
A Model instance. The check round-trips it through the codec and asserts equality.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
AssertionError
|
If the round trip does not produce an equal Model. |
IoError
|
If the codec rejects either direction. |
Source-level emit¶
didactic.codegen.source.emit_pretty ¶
emit_pretty(model: type[Model], *, target: str) -> bytes
Render model as fresh source in the named target language.
| PARAMETER | DESCRIPTION |
|---|---|
model
|
A Model subclass.
TYPE:
|
target
|
A panproto grammar name (e.g.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bytes
|
Source code that the target grammar accepts as syntactically valid. |
| RAISES | DESCRIPTION |
|---|---|
PanprotoError
|
If the grammar rejects the schema (typically because the
grammar lacks a |
Notes
The output is syntactically valid; idiomatic formatting (rustfmt
spacing rules, gofmt conventions) is left to a post-processor.
Configure one in pyproject.toml under
[tool.didactic.emit.targets.{target}.post_process].
didactic.codegen.source.emit ¶
Re-emit a parse-recovered schema as source bytes.
| PARAMETER | DESCRIPTION |
|---|---|
schema
|
A
TYPE:
|
protocol
|
The grammar name to emit under (typically the same as the parse step).
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bytes
|
The reconstructed source. |
Notes
Use this for edit pipelines (parse, transform, emit). For fresh emission from a Model class, use emit_pretty.
didactic.codegen.source.parse ¶
Parse source bytes into a panproto.Schema.
| PARAMETER | DESCRIPTION |
|---|---|
source
|
The source bytes to parse.
TYPE:
|
protocol
|
The grammar name (e.g.
TYPE:
|
file_path
|
A filename for error messages. Does not need to exist.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Schema
|
The parsed schema with byte-position fragments. Pass to emit to re-emit, or to didactic.codegen.source.for_protocol for lens-style round-trip checks. |
didactic.codegen.source.available_targets ¶
List every grammar the running panproto build supports.
| RETURNS | DESCRIPTION |
|---|---|
list of str
|
Grammar names, sorted. |
didactic.codegen.source.detect_language ¶
Return the grammar name that handles path's extension, if any.
didactic.codegen.source.for_protocol ¶
Build a parse function bound to protocol.
| PARAMETER | DESCRIPTION |
|---|---|
protocol
|
The grammar name.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Callable
|
A function that takes source bytes and returns a Schema. Use in lens compositions or as a partial-application helper. |