Understanding the result¶
Every call to literalize() and literalize_call() returns a single LiteralizeResult.
The examples elsewhere reach for whichever field they need, but the object is worth understanding as a whole: for several languages the headline code does not compile on its own, and assembling output correctly means knowing which other fields to place around it.
The fields¶
The members below are rendered directly from the LiteralizeResult source, the authoritative description of each field.
code is the field most callers read; the rest of this page explains when you need the others.
- class literalizer.LiteralizeResult(declaration_code: str, preamble: tuple[str, ...], body_preamble: tuple[str, ...], pre_declaration_comments: tuple[str, ...] = (), types_present: frozenset[type] = frozenset({}), contains_standalone_comments: bool = False, source_data: Value = None, sections: tuple[FileSection, ...] = ())
Result of converting data to a native language literal.
- property bare_code: str
The literal text without
body_preambleprepended.Identical to
codewhenbody_preambleis empty.pre_declaration_commentsare preserved.
- body_preamble: tuple[str, ...]
Type-definition lines (e.g. F#’s
type Val = …, Haskell’sdata Val = …and typeclass instances) that are prepended tocode. Empty when none are needed.Use
bare_codeto obtain the literal text without these lines.
- property code: str
The formatted literal text.
When a language defines
scalar_body_preambleentries (e.g. Haskell typeclass instances), those lines are prepended to the code so they appear in the correct structural position.
- contains_standalone_comments: bool = False
Whether the rendered source carried standalone comments (lines whose only content is a comment, distinct from inline trailing comments). Set when
literalize_callparses YAML input that contains top-level before-element or trailing comments. Callers that wrap the result viaLanguage.wrap_calls_with_declarations()can consult this together withLanguage.supports_standalone_comments_in_wrapped_callsto decide whether wrapping is safe.
- declaration_code: str
The variable declaration or assignment text, without any
body_preambleorpre_declaration_commentslines.Use
codefor the full formatted text including all prefix lines.
- pre_declaration_comments: tuple[str, ...] = ()
Already-formatted comment lines that appear between
body_preambleand the variable declaration/assignment incode. These come from scalar before-comments when the language does not support them inline.Included in
bare_codebut excluded fromdeclaration_code.
- preamble: tuple[str, ...]
Lines (imports, package declarations, etc.) that must precede the generated code. Empty when none are needed.
- sections: tuple[FileSection, ...] = ()
For multi-section languages, the rendered output split into its file regions; empty for the single-section common case.
A few languages cannot express a value as one drop-in fragment: their output spans more than one region of a source file that a wrapping template must place separately. COBOL under
json_type=CJSONis the current example, emitting aWORKING-STORAGEregion of declarations and aPROCEDUREregion of statements.Only populated when
wrap_in_file=False(withwrap_in_file=Truethe language has already composed the regions into a complete file). When non-empty, compose theseFileSectionregions into your own template;code/declaration_codethen hold an opaque marker-bracketed payload (the form the language’s wrappers consume), not usable source. Empty for almost every language; usecodethen.
- source_data: Value = None
The parsed source value the literal was rendered from. Most callers do not need it. Callers that combine multiple
literalizeresults and re-invokeLanguage.compute_body_preambleto derive a single body preamble surface this so the second call can inspect the actual values (e.g. datetime microsecond precision) rather than a placeholder.
- types_present: frozenset[type] = frozenset({})
The set of Python types observed in the source data (e.g.
int,str,list,dict). Callers that combine multipleliteralizeresults (for example, a test harness that pairs$refdeclarations with a downstream call) can union these and re-invokeLanguage.compute_body_preambleto derive a single body preamble that covers every type referenced across the combined output.
When code is not enough on its own¶
For many languages and the default settings, code is a complete, drop-in literal and preamble is empty.
That changes the moment a strategy or json_type synthesizes a declaration.
Rendering a heterogeneous list for Rust with the TAGGED_ENUM strategy puts the generated enum in preamble; the literal in code references that enum and will not compile without it:
"""The Rust TAGGED_ENUM literal needs its preamble to compile."""
from literalizer import InputFormat, literalize
from literalizer.languages import Rust
result = literalize(
source='[1, "two", 3.0]',
input_format=InputFormat.JSON,
language=Rust(
heterogeneous_strategy=Rust.heterogeneous_strategies.TAGGED_ENUM,
),
)
# The literal references a type that is defined in the preamble:
assert "Value::I32(1)" in result.code
assert result.preamble == (
"enum Value {",
" I32(i32),",
" Str(&'static str),",
" F64(f64),",
"}",
)
To turn this into source that compiles by hand, join preamble ahead of code:
"""Assemble preamble + code into a fragment that compiles by hand."""
from literalizer import InputFormat, literalize
from literalizer.languages import Rust
result = literalize(
source='[1, "two", 3.0]',
input_format=InputFormat.JSON,
language=Rust(
heterogeneous_strategy=Rust.heterogeneous_strategies.TAGGED_ENUM,
),
)
source = "\n".join((*result.preamble, result.code))
assert source.startswith("enum Value {")
assert source.endswith("]")
Letting wrap_in_file do the assembly¶
Stitching the fields together yourself is error-prone, because the correct placement of preamble and body_preamble differs by language.
Pass wrap_in_file=True and literalizer assembles a complete, valid file for you: the preamble is placed at the top, the literal is bound to your variable inside whatever scope the language requires, and the regions are ordered correctly.
"""wrap_in_file=True assembles the preamble and literal into a file."""
from literalizer import InputFormat, NewVariable, literalize
from literalizer.languages import Rust
result = literalize(
source='[1, "two", 3.0]',
input_format=InputFormat.JSON,
language=Rust(
heterogeneous_strategy=Rust.heterogeneous_strategies.TAGGED_ENUM,
),
variable_form=NewVariable(name="values"),
wrap_in_file=True,
)
# The enum, a main function, and the bound literal are all present,
# in the order required to compile:
assert result.code == (
"enum Value {\n"
" I32(i32),\n"
" Str(&'static str),\n"
" F64(f64),\n"
"}\n"
"fn main() {\n"
" let values = vec![\n"
" Value::I32(1),\n"
' Value::Str("two"),\n'
" Value::F64(3.0),\n"
" ];\n"
" let _ = values;\n"
"}"
)
Prefer wrap_in_file=True whenever you need output that compiles or runs as-is.
Read code and preamble separately only when you are embedding the literal into a larger template of your own and want to control where the preamble lands.
body_preamble and bare_code¶
Some languages express a heterogeneous value as a literal of a type they must also define, where that type definition belongs immediately ahead of the literal rather than at file scope.
F# is one such language: its type Val = discriminated union appears in body_preamble, already folded into code.
Use bare_code when you want the literal on its own and intend to place the type definition yourself:
"""code folds in the body_preamble; bare_code omits it."""
from literalizer import InputFormat, literalize
from literalizer.languages import FSharp
result = literalize(
source='[1, "two", 3.0]',
input_format=InputFormat.JSON,
language=FSharp(),
)
assert result.body_preamble == (
"type Val =",
" | FInt of int64",
" | FFloat of float",
" | FStr of string",
" | FList of Val list",
)
# code includes the type definition; bare_code starts at the literal:
assert result.code.startswith("type Val =")
assert result.bare_code.startswith("FList [")
Multi-section output¶
A few languages cannot express a value as one drop-in fragment: their output spans more than one region of a source file that a wrapping template must place separately.
For these, sections holds the rendered FileSection regions and code holds an opaque marker payload rather than usable source.
This is empty for almost every language; see sections for details and the one current example.