literalizer¶
literalizer converts JSON, JSON5, YAML, and TOML data structures to native language literal syntax.
Supported languages¶
See Languages for the full list with per-language options.
Installation¶
Requires Python 3.12+.
pip install literalizer
Usage¶
Use literalizer.literalize() to convert data to native language literals.
Pass your data, its format, and a target language:
"""Minimal example of using literalizer."""
from literalizer import InputFormat, literalize
from literalizer.languages import Python
result = literalize( # returns LiteralizeResult with .code and .preamble
source='{"x": 1}',
input_format=InputFormat.JSON,
language=Python(),
)
# result.code:
# {
# "x": 1,
# }
The call returns a single LiteralizeResult.
Here result.code is the whole story, but for some languages and options the literal in code relies on a separate preamble to compile.
See Understanding the result for what each field means and how to assemble output that compiles.
Configure the language to control how individual data types are rendered. Comments in the source are preserved using the target language’s comment syntax:
"""Layering format options on top of the minimal call."""
from literalizer import InputFormat, literalize
from literalizer.languages import Go
yaml_config = """\
# Server configuration
host: localhost # default host
port: 8080
released: 2026-06-02
"""
result = literalize(
source=yaml_config,
input_format=InputFormat.YAML,
language=Go(date_format=Go.date_formats.ISO),
)
# result.code:
# map[string]any{
# // Server configuration
# "host": "localhost", // default host
# "port": 8080,
# "released": "2026-06-02",
# }
TOML is read the same way, and its comments are preserved too:
"""Reading TOML, with comments preserved."""
from literalizer import InputFormat, literalize
from literalizer.languages import Python
toml_config = """\
# Server configuration
host = "localhost" # default host
port = 8080
"""
result = literalize(
source=toml_config,
input_format=InputFormat.TOML,
language=Python(),
)
# result.code:
# {
# # Server configuration
# "host": "localhost", # default host
# "port": 8080,
# }
JSON5 is also accepted. Its relaxed syntax, such as comments, single-quoted strings, trailing commas, and hexadecimal numbers, is converted to the target language:
"""Reading JSON5's relaxed syntax."""
from literalizer import InputFormat, literalize
from literalizer.languages import Python
json5_config = """\
{
// Relaxed syntax is accepted here.
name: 'literalizer',
port: 0x1F90,
}"""
result = literalize(
source=json5_config,
input_format=InputFormat.JSON5,
language=Python(),
)
# result.code:
# {
# "name": "literalizer",
# "port": 8080,
# }
Binding the result to a variable¶
By default literalize() renders a bare literal.
Pass variable_form to bind that literal to a variable instead, so the output is a statement you can drop straight into source.
There are three forms, and the difference is visible in languages that distinguish declaring a variable from assigning to one:
NewVariabledeclares a fresh variable (Go’sconfig :=, JavaScript’sconst config =, Rust’slet config =). This is the form nearly every example uses.ExistingVariableassigns to a variable declared elsewhere (config =), emitting no declaration keyword.BothVariableFormsemits a declaration and a subsequent assignment together, for showing both styles from one source. It requireswrap_in_file=Trueand a language whose declaration style permits reassigning the same name.
The same source, rendered for Go in each form:
"""Contrast the three variable_form choices for one source."""
from literalizer import (
BothVariableForms,
ExistingVariable,
InputFormat,
NewVariable,
literalize,
)
from literalizer.languages import Go
source = '{"host": "localhost", "port": 8080}'
new_variable = literalize(
source=source,
input_format=InputFormat.JSON,
language=Go(),
variable_form=NewVariable(name="config"),
)
assert new_variable.code == (
'config := map[string]any{\n\t"host": "localhost",\n\t"port": 8080,\n}'
)
existing_variable = literalize(
source=source,
input_format=InputFormat.JSON,
language=Go(),
variable_form=ExistingVariable(name="config"),
)
assert existing_variable.code == (
'config = map[string]any{\n\t"host": "localhost",\n\t"port": 8080,\n}'
)
both_forms = literalize(
source=source,
input_format=InputFormat.JSON,
language=Go(),
variable_form=BothVariableForms(name="config"),
wrap_in_file=True,
)
assert both_forms.code == (
"package main\n"
"\n"
"func main() {\n"
"config := map[string]any{\n"
'\t"host": "localhost",\n'
'\t"port": 8080,\n'
"}\n"
"config = map[string]any{\n"
'\t"host": "localhost",\n'
'\t"port": 8080,\n'
"}\n"
"_ = config\n"
"}"
)
Whether the two forms differ at all depends on the language.
Python uses config = for both declaring and assigning, so with the default settings NewVariable and ExistingVariable render identically.
They diverge once a feature attaches to the declaration specifically: enabling variable_type_hints makes NewVariable annotate the binding (config: dict[str, str | int] = ...) while ExistingVariable stays a bare config = ....
Use cases¶
Generate test fixtures from JSON, JSON5, YAML, or TOML samples.
Convert API responses to language-native data structures for documentation.
Generate multi-language function call examples from data — see Rendering function calls.
Create type-safe literal data from JSON, JSON5, YAML, or TOML config files.
CLI¶
A command-line interface is available at literalizer-cli.
Sphinx extension¶
A Sphinx extension is available at sphinx-literalizer.
Reference¶
Guides
Reference
- API Reference
- Core functions
- Result type
- Variable forms
- Identifier cases
- Function calls
- Input formats
- Exceptions
CallArgNotSupportedErrorCallsNotSupportedByLanguageErrorCallsNotSupportedByToolErrorCommentSourceLengthMismatchErrorCommentSourceMultilineErrorDottedCallTargetNotSupportedErrorHeterogeneousCollectionErrorHeterogeneousScalarCollectionErrorHeterogeneousSetErrorHeterogeneousSiblingListsErrorIncompatibleFormatsErrorInvalidDictKeyErrorInvalidRecordNameErrorJSON5ParseErrorJSONParseErrorMixedDictKeysErrorMixedDictShapesErrorMixedDictValuesErrorMixedListValuesErrorNullInCollectionErrorParameterCountMismatchErrorParseErrorPerElementNotListErrorTOMLParseErrorTupleArityNotRepresentableErrorUnrepresentableEmptyDictErrorUnrepresentableInputErrorUnrepresentableIntegerErrorUnrepresentableSpecialFloatErrorUnsupportedCallShapeErrorUnsupportedIdentifierCaseErrorVariableNameNotSupportedErrorWrapCombinedInFileNotSupportedErrorWrapInFileWithoutVariableNotSupportedErrorYAMLParseErrorZipSourceWithoutInputFormatErrorZipValuesLengthMismatchErrorZipValuesWithoutCallTransformError
- Languages
- Selecting a language
- Format options
- Float emission scope
- Heterogeneous values
- JSON value types
- Empty mappings on Ada, Lua, PHP, and R
- Forth visitor stream
- Custom language implementations
- Language-definition API
- Built-in languages
AdaBashCCSharpClojureCobolCommonLispCppCrystalDDartDhallElixirElmErlangFSharpForthFortranGleamGoGroovyHaskellHaxeHclJavaJavaScriptJson5JsonnetJuliaKotlinLuaMatlabMojoNimNixNorgOCamlObjectiveCOccamOdinPerlPhpPowerShellPureScriptPythonRRacketRakuRocRubyRustScalaSchemeSmlSwiftSystemVerilogTclTomlTypeScriptVVisualBasicWrenYamlZig
Project / Development
- Release Process
- Unreleased changes
- Changelog
- 2026.06.02
- 2026.05.28
- 2026.05.21.1
- 2026.05.21
- 2026.05.20.1
- 2026.05.20
- 2026.05.18.1
- 2026.05.18
- 2026.05.17.1
- 2026.05.17
- 2026.05.16.1
- 2026.05.16
- 2026.05.15.2
- 2026.05.15.1
- 2026.05.15
- 2026.05.14.1
- 2026.05.14
- 2026.05.13.1
- 2026.05.13
- 2026.05.01.1
- 2026.05.01
- 2026.04.30.3
- 2026.04.30.2
- 2026.04.30.1
- 2026.04.30
- 2026.04.29
- 2026.04.24.1
- 2026.04.24
- 2026.04.23
- 2026.04.21.5
- 2026.04.21.4
- 2026.04.21.3
- 2026.04.21.2
- 2026.04.21.1
- 2026.04.21
- 2026.04.18
- 2026.04.15
- 2026.04.14
- 2026.04.13
- 2026.04.06
- 2026.03.30
- 2026.03.29
- 2026.03.26.2
- 2026.03.26.1
- 2026.03.26
- 2026.03.25
- 2026.03.23
- 2026.03.22.1
- 2026.03.22
- 2026.03.21
- 2026.03.20.3
- 2026.03.20.2
- 2026.03.20.1
- 2026.03.20
- 2026.03.19.1
- 2026.03.19
- 2026.03.18
- 2026.03.17.2
- 2026.03.17.1
- 2026.03.17
- 2026.03.16.2
- 2026.03.16.1
- 2026.03.16
- 2026.03.15.2
- 2026.03.15.1
- 2026.03.15
- 2026.03.14
- 2026.03.13
- Contributing to literalizer