Nano Markup for Python
nanomarkup is a zero-runtime-dependency Python parser and serializer for
Nano Markup, a minimal,
human-readable structured data format.
Version 1.0.0 implements the stable Nano Markup 1.0.0 specification.
Installation
python -m pip install nanomarkup
Python 3.11 or later is required.
Python API
Nano Markup values map directly to Python values:
| Nano Markup | Python |
|---|---|
| String | str |
| Mapping | dict[str, NanoValue] |
| Sequence | list[NanoValue] |
All scalars remain strings. The decoder never infers numbers, booleans, nulls, dates, or application-specific types.
import nanomarkup
document = """\
..
name Ariana
age 12
interests:
cycling
music
"""
value = nanomarkup.loads(document)
assert value == {
"name": "Ariana",
"age": "12",
"interests": ["cycling", "music"],
}
encoded = nanomarkup.dumps(value)
assert nanomarkup.loads(encoded) == value
assert nanomarkup.__version__ == "1.0.0"
assert nanomarkup.SPEC_VERSION == "1.0.0"
The API follows Python's standard serialization naming convention:
loads(source)decodes astr,bytes,bytearray, ormemoryview.load(stream)decodes an open text or binary stream.dumps(value)returns a Nano Markup string.dump(value, stream)writes to an open text stream.
Use binary input when decoding files so invalid UTF-8 can be diagnosed by the Nano Markup decoder:
with open("settings.nano", "rb") as source:
settings = nanomarkup.load(source)
with open("settings.nano", "w", encoding="utf-8", newline="") as destination:
nanomarkup.dump(settings, destination, newline="\n")
dumps and dump accept newline="\n" (the default) or
newline="\r\n". Writer output does not end with an automatic final newline.
Mapping insertion order is retained for readability, although mapping order is
not part of the Nano Markup data model.
Errors
Invalid input raises DecodeError, which provides the stable specification
category and source location:
try:
nanomarkup.loads(b"..\n bad indentation")
except nanomarkup.DecodeError as error:
print(error.code.value) # E_INDENT
print(error.byte_offset) # zero-based UTF-8 byte offset
print(error.line) # one-based line
print(error.column) # one-based Unicode column
Values outside the Nano Markup data model, invalid mapping keys, forbidden
characters, and cyclic containers raise EncodeError.
Validator
Validate one or more files with the installed command:
nanomarkup settings.nano other.nano
nanomarkup - < settings.nano
python -m nanomarkup settings.nano
nanomarkup --version
Each valid input is reported on standard output. Diagnostics use
path:line:column: CODE: message on standard error. Exit status is 0 when
all inputs are valid, 1 when a document is invalid, and 2 for usage or I/O
errors.
Conformance and development
The spec Git submodule pins the official conformance suite at commit
bba11e49ca3a904cef07b067f6fc0597b0facba2 (tag v1.0.0).
git clone --recurse-submodules https://github.com/nohainc/nanomarkup.python.git
cd nanomarkup.python
python -m pip install -e ".[dev]"
pytest
ruff check .
mypy
See CHANGELOG.md for release history. See CONTRIBUTING.md for development checks and SECURITY.md for private vulnerability reporting.
Publishing
Releases are built and published from tags matching the package version, such
as v1.0.0. Before the first release, configure a PyPI Trusted Publisher for
the nohainc/nanomarkup.python repository, workflow release.yml, and GitHub
environment pypi. Require manual approval for that environment. The workflow
uses short-lived OpenID Connect credentials and does not require a stored PyPI
API token.
The implementation provides data decoding and writing only. Comments, whitespace, quote choice, source line endings, and mapping source order are presentation metadata and are not preserved. There is no source-preserving document API, schema system, implicit type conversion, or executable syntax.
No explicit parser resource caps are imposed. Applications accepting untrusted documents should bound input size according to their environment.
License
The Python implementation is licensed under the MIT License.
The specification submodule and its conformance materials are separate works licensed under the Creative Commons Attribution 4.0 International License. See NOTICE.md for attribution and the pinned source revision.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nanomarkup-1.0.0.tar.gz.
File metadata
- Download URL: nanomarkup-1.0.0.tar.gz
- Upload date:
- Size: 14.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ec89080f1df0152c972507d7268675b51a32eacc59dc74598401de6f4faed8f5
|
|
| MD5 |
ec44b80197d0b71cf3e7a489df97070a
|
|
| BLAKE2b-256 |
12293a33cf4e80d24094feef6be857e21c5ce326a087ce1fc80a8553c964d420
|
Provenance
The following attestation bundles were made for nanomarkup-1.0.0.tar.gz:
Publisher:
release.yml on nohainc/nanomarkup.python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nanomarkup-1.0.0.tar.gz -
Subject digest:
ec89080f1df0152c972507d7268675b51a32eacc59dc74598401de6f4faed8f5 - Sigstore transparency entry: 2303148376
- Sigstore integration time:
-
Permalink:
nohainc/nanomarkup.python@b9ea9272a9c12e923aff502abb95e57f8ae47073 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/nohainc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b9ea9272a9c12e923aff502abb95e57f8ae47073 -
Trigger Event:
push
-
Statement type:
File details
Details for the file nanomarkup-1.0.0-py3-none-any.whl.
File metadata
- Download URL: nanomarkup-1.0.0-py3-none-any.whl
- Upload date:
- Size: 14.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7e3178bd86e06404abab7a53e8561edbcc0686afb93051588e1eae5495162824
|
|
| MD5 |
0c7637f375f521fc4d572bd1eead304e
|
|
| BLAKE2b-256 |
5fc91ef766388817a5f2c7531879c5604db185511ba25f7074c21fecd88c18a7
|
Provenance
The following attestation bundles were made for nanomarkup-1.0.0-py3-none-any.whl:
Publisher:
release.yml on nohainc/nanomarkup.python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nanomarkup-1.0.0-py3-none-any.whl -
Subject digest:
7e3178bd86e06404abab7a53e8561edbcc0686afb93051588e1eae5495162824 - Sigstore transparency entry: 2303148443
- Sigstore integration time:
-
Permalink:
nohainc/nanomarkup.python@b9ea9272a9c12e923aff502abb95e57f8ae47073 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/nohainc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b9ea9272a9c12e923aff502abb95e57f8ae47073 -
Trigger Event:
push
-
Statement type: