Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Toony

TOON serialization for Python, powered by an independent Rust engine.

Toony turns Python data into TOON text and back, with a json-style API and optional Pydantic integration. Use it to place structured records in an LLM prompt without changing your models, tool schemas or JSON protocols.

Status: release candidate 0.1.0rc3, implementing TOON 4.4.0. This is an independent project, not the official TOON Python package.

Install

python -m pip install toony==0.1.0rc3
uv pip install toony==0.1.0rc3
poetry add toony==0.1.0rc3

For Pydantic integration:

python -m pip install 'toony[pydantic]==0.1.0rc3'

Requires CPython 3.11–3.15. A matching wheel does not require Rust. Where a wheel is unavailable, installation builds from source and requires Rust 1.88+. There are no mandatory Python runtime dependencies.

To install directly from source:

python -m pip install 'git+https://github.com/aeespinosao/toony.git@v0.1.0rc3'

A familiar API

import toony

value = {"users": [{"id": 1, "name": "Ana"}, {"id": 2, "name": "Bo"}]}
text = toony.dumps(value)
print(text)
# users[2]{id,name}:
#   1,Ana
#   2,Bo

assert toony.loads(text) == value

dump and load accept caller-owned streams. encode and decode are aliases. Defaults are two-space indentation, comma delimiter, strict decoding and no trailing newline. delimiter="\t" and delimiter="|" are also supported.

with open("users.toon", "w", encoding="utf-8") as file:
    toony.dump(value, file)

with open("users.toon", encoding="utf-8") as file:
    restored = toony.load(file)

Use existing Pydantic models

from pydantic import BaseModel
from toony.pydantic import ToonTypeAdapter

class User(BaseModel):
    id: int
    name: str

adapter = ToonTypeAdapter(list[User])
text = adapter.dump_toon([User(id=1, name="Ana")])
users = adapter.validate_toon(text, toon_strict=True, strict=True)
assert users == [User(id=1, name="Ana")]

The adapter uses public TypeAdapter.dump_json() and validate_json() APIs. Existing serializers, aliases, context and compatible inclusion/exclusion options continue through JSON mode. No custom model base class or monkey-patching is needed. TOON grammar strictness (toon_strict) and Pydantic strictness (strict) are separate.

TOON normalizes values: 1.0 becomes 1 and negative zero becomes 0. This can change numeric union selection or strict validation. Pydantic's Decimal-as-string serialization remains a string. The adapter does not override a validator's own numeric precision rules.

LLM context, without changing protocols

import toony

context = toony.dumps({"users": [{"id": 1, "name": "Ana"}]})
prompt = (
    "Read TOON data: array headers declare counts and fields; rows follow field order.\n"
    + context
    + "\nReturn the user IDs as JSON."
)
# Pass prompt to your existing model client.

Keep tool arguments, schemas and protocol envelopes in their native JSON contracts. Send TOON as text when it helps. Avoid passing the same context twice as both TOON and a second JSON rendering.

Runnable recipes are provided for LangChain, Pydantic AI, Strands and MCP. These frameworks are optional application choices, not dependencies of the core package.

For independent chunks with a verified token budget (this example needs pip install tiktoken; any token-counting function can be supplied):

import tiktoken
from toony.context import iter_chunks

encoding = tiktoken.get_encoding("o200k_base")
records = [{"id": i, "name": f"User {i}"} for i in range(1000)]
for chunk in iter_chunks(
    records, max_tokens=2000, count_tokens=lambda text: len(encoding.encode(text))
):
    assert len(encoding.encode(chunk)) <= 2000

Each chunk is a complete document with a valid header/count and preserved IDs. A single record that exceeds the budget raises OversizedRecordError; it is not silently truncated. Account for your surrounding instructions separately.

Precision, limits and errors

from decimal import Decimal
import toony

number = Decimal("0.123456789012345678901234567890")
assert toony.loads(toony.dumps(number), parse_float=Decimal) == number
assert toony.loads(toony.dumps(2**100 + 1)) == 2**100 + 1

limits = toony.Limits(max_input_bytes=1_048_576, max_depth=32)
restored = toony.loads("id: 1", limits=limits)

Supported inputs include JSON types, tuples (normalized to lists), finite Decimal values and custom types normalized with default=. Dictionary keys must be strings. Default float decoding follows Python floating-point behavior; use numeric hooks when exact decimals are required. Non-finite host floats normalize to null; non-finite Decimal values are rejected.

Default protections are 64 MiB input, 256 MiB output, depth 128, 1,000,000 value nodes, 16,384 fields per object and 4,096 characters per number. Python's own integer conversion limits still apply. User callbacks can allocate independently. ToonDecodeError, ToonEncodeError, ToonLimitError, ToonNumberError and ToonCycleError distinguish failure types. Syntax errors include a stable code, one-based line and bounded excerpt.

Experimental from_json and to_json convert directly in Rust without creating a Python value graph. to_json returns bytes; JSON duplicate keys are rejected. These paths may materialize a native tree and are not streaming APIs.

ASGI / Uvicorn

Install the asgi extra and see the Starlette application. toony.asgi provides content negotiation, bounded request bodies and helpers that offload synchronous conversions from the event loop. Uvicorn serves the application:

python -m pip install 'toony[asgi]==0.1.0rc3'
# Run from a checkout of this repository:
uvicorn examples.asgi_app:app

Traversal of Python objects holds the GIL. A thread offload is not a guarantee of uninterrupted event-loop responsiveness for large CPU-heavy conversions; measure your workload and use process workers when appropriate. An already-started thread operation may continue after its awaiting task is cancelled.

Measured performance

Measurements below use a local release build of the 0.1.0rc3 sources, on an Apple M4 (10 CPU cores, 16 GiB), macOS ARM64, CPython 3.14.7. Ten independent processes per codec/operation, seven samples per process, randomized order; intervals are 95% bootstrap intervals over process medians. Codec and inference runs are separate. The measured native-library hash is recorded in the data. Published wheels are built in CI; these timings are not measurements of every platform or interpreter.

Codec latency: Toony compared with JSON and TOON implementations

For 20,000 uniform records, Toony encoding is 6.36 ms and decoding 7.31 ms. toons encodes in 2.89 ms; Toony does not demonstrate general speed superiority. JSON codecs produce a different representation. Text outputs are aligned; orjson's bytes-to-text conversion is included in its encoding time.

Native TOON → JSON text conversion is 8.02 ms for Toony versus 10.66 ms for toons.to_json, a 24.8% reduction in this workload. This is a specific measured path, not an across-the-board claim. Total process RSS did not demonstrate a material improvement.

Full-prompt token changes including format instructions and negative savings

The token chart counts the complete prompt, including the TOON explanation, against compact JSON. Small and irregular inputs show negative savings. o200k_base is a representation comparison, not either local model's tokenizer. Exact counts, instructions, both tokenizers (o200k_base, cl100k_base), dependency versions and raw timing samples are in metrics.json. The serialized bytes were verified unchanged from the token-counting run.

Validation: 610 tests passed on the locally installed rc3 wheel with CPython 3.14.7. The release workflow tests installed wheels for Python 3.11–3.15 on Linux x86_64 and macOS ARM64 before publication. Windows remains unvalidated. Earlier Linux ARM64 tests were executed on rc2. The Rust runtime sources are unchanged; the rc2 ASAN smoke covered 227,963 executions in 181 seconds. Release CI also runs a fresh sanitizer smoke. A four-hour campaign on this candidate remains pending.

Local-model follow-up (executed on 0.1.0rc2): 336/336 tasks completed; allocated context 16,384, actual comprehension prompts 1012–15272 tokens, temperature zero, two repetitions and at most one syntax/schema repair.

  • qwen3:8b comprehension: JSON 36/48; TOON 26/48 correct.

  • llama3.2:3b comprehension: JSON 28/48; TOON 12/48 correct.

  • qwen3:8b generation: JSON text 24/24; TOON text 24/24; native JSON schema 24/24 correct.

  • llama3.2:3b generation: JSON text 12/24; TOON text 0/24; native JSON schema 20/24 correct.

  • qwen3:8b: 25.1% fewer input tokens; 3.7% more total tokens per correct comprehension task, including all attempts.

  • llama3.2:3b: 34.2% fewer input tokens; 53.6% more total tokens per correct comprehension task, including all attempts.

These model results characterize the TOON representation; identical serialized text from another implementation produces the same prompt.

Live framework smokes produced the expected result in 3/8 calls. Other calls returned incorrect/empty data or no usable structured result. API contract tests passing does not guarantee model comprehension.

Local inference latency, separating first and reused prefixes

Whiskers are 95% bootstrap intervals clustered by source document, not questions or repetitions. First-prefix requests unload the isolated runner before each document, format and repetition; they include model loading. The next three questions share that document prefix. OS file caches are not flushed. Observed cached-token counters are retained in the data; these phases are not isolated cold-hardware versus warm-hardware tests.

The rc3 runtime code is unchanged apart from version metadata. Serialized inputs and parsing outcomes were checked against rc2; this model study was not rerun or relabeled as an rc3 execution.

There are only six independent source documents per model. The non-inferiority result at a two-percentage-point margin is inconclusive. Generation uses an explicit TOON syntax primer and is a distinct experiment. No energy or monetary savings were measured. Only one model was resident during scored inference; these are local-host measurements rather than isolated hardware or energy measurements.

Token reduction comes from the TOON representation, not the Rust implementation. Uniform tables can benefit; small or irregular documents can cost more tokens, especially after format instructions. A shorter prompt does not guarantee better model accuracy or lower end-to-end latency. Benchmark your data and model before switching a production workflow.

Build, test and benchmark

uv sync --frozen
uv run pytest -q
cargo test -p toony-core --locked
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
uv run mypy --follow-imports=silent tests/typing_check.py
uv run ruff check python tests examples benchmarks
uv build --wheel --sdist

The test suite includes all 564 pinned official fixtures, property tests, precision, limits, cycles, callbacks, Pydantic, chunking and HTTP integration. Run the benchmarks independently of model inference:

uv run python -m benchmarks.run --repeats 10
uv run --with matplotlib python -m benchmarks.plot

The benchmark harness currently measures RSS on macOS/Linux. It uses fresh processes, seven samples per process, seeded task order, bootstrap intervals and explicit compatibility exclusions. Raw JSON is retained; no performance threshold is used as a substitute for correctness.

The release workflow builds and tests installed wheels on Linux and macOS for Python 3.11–3.15, publishes to TestPyPI, verifies installation, then publishes to PyPI for matching v* tags. Credentials live in GitHub environment secrets. Windows checks remain available through the manual test workflow; a configured job does not mean that platform has been validated.

License and provenance

MIT. The Rust TOON engine is original to this project, written from the specification. Official compatibility fixtures are pinned in fixtures/manifest.json and retain their upstream license. Runtime/build dependency licenses are included in THIRD_PARTY_NOTICES.md.

Metadata

Release files for toony 0.1.0rc3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for toony 0.1.0rc3
File Size Uploaded Provenance Actions
toony-0.1.0rc3.tar.gz 582.8 kB Without provenance Details for toony-0.1.0rc3.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for toony 0.1.0rc3
File Actions
toony-0.1.0rc3-cp315-cp315-manylinux_2_28_x86_64.whl CPython 3.15 CPython 3.15 Linux glibc 2.28+ x86-64 Details for toony-0.1.0rc3-cp315-cp315-manylinux_2_28_x86_64.whl
toony-0.1.0rc3-cp315-cp315-macosx_11_0_arm64.whl CPython 3.15 CPython 3.15 macOS 11.0+ ARM64 Details for toony-0.1.0rc3-cp315-cp315-macosx_11_0_arm64.whl
toony-0.1.0rc3-cp314-cp314-manylinux_2_28_x86_64.whl CPython 3.14 CPython 3.14 Linux glibc 2.28+ x86-64 Details for toony-0.1.0rc3-cp314-cp314-manylinux_2_28_x86_64.whl
toony-0.1.0rc3-cp314-cp314-macosx_11_0_arm64.whl CPython 3.14 CPython 3.14 macOS 11.0+ ARM64 Details for toony-0.1.0rc3-cp314-cp314-macosx_11_0_arm64.whl
toony-0.1.0rc3-cp313-cp313-manylinux_2_28_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.28+ x86-64 Details for toony-0.1.0rc3-cp313-cp313-manylinux_2_28_x86_64.whl
toony-0.1.0rc3-cp313-cp313-macosx_11_0_arm64.whl CPython 3.13 CPython 3.13 macOS 11.0+ ARM64 Details for toony-0.1.0rc3-cp313-cp313-macosx_11_0_arm64.whl
toony-0.1.0rc3-cp312-cp312-manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ x86-64 Details for toony-0.1.0rc3-cp312-cp312-manylinux_2_28_x86_64.whl
toony-0.1.0rc3-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details for toony-0.1.0rc3-cp312-cp312-macosx_11_0_arm64.whl
toony-0.1.0rc3-cp311-cp311-manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.28+ x86-64 Details for toony-0.1.0rc3-cp311-cp311-manylinux_2_28_x86_64.whl
toony-0.1.0rc3-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details for toony-0.1.0rc3-cp311-cp311-macosx_11_0_arm64.whl

Total release size: 4.8 MB

Release files / toony-0.1.0rc3.tar.gz

Download URL toony-0.1.0rc3.tar.gz
Size 582.8 kB
Tags Source
SHA-256 checksum
How to use checksums
6c4efc50208751967b4f4bdc623d41c2be1c6f4fd56dd49fb24f05818adb803c
BLAKE2b-256 checksum
How to use checksums
ef4013f006236c002655c493b4a2613c74c54b0551b1d81724a899908656666b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / toony-0.1.0rc3-cp315-cp315-manylinux_2_28_x86_64.whl

Download URL toony-0.1.0rc3-cp315-cp315-manylinux_2_28_x86_64.whl
Size 444.3 kB
Tags CPython 3.15 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
bc011be94ed3a5869d124e9324931d7922cde0832d245ee6f30b515b09982bda
BLAKE2b-256 checksum
How to use checksums
2d56cdadd1ec86452edd31642910efdcc36d6f413bcbe015037dd052399ac682
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / toony-0.1.0rc3-cp315-cp315-macosx_11_0_arm64.whl

Download URL toony-0.1.0rc3-cp315-cp315-macosx_11_0_arm64.whl
Size 400.1 kB
Tags CPython 3.15 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
e4975868630479ed666771217bf6782a0c698687a577a29e40d69dbc874a3a31
BLAKE2b-256 checksum
How to use checksums
657c034547c7c48d4fd07742eeea2653526a18ead12d9f700b5fcb0e5e441301
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / toony-0.1.0rc3-cp314-cp314-manylinux_2_28_x86_64.whl

Download URL toony-0.1.0rc3-cp314-cp314-manylinux_2_28_x86_64.whl
Size 444.1 kB
Tags CPython 3.14 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
8edeea57eb1d3e0ebde9d6f29ad4ebaba8c62623194afc76488cc0a02a06223f
BLAKE2b-256 checksum
How to use checksums
337f4922e5e16f107ce759e7943fe9c506d3c8634f84f296e1a325ed4f641d64
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / toony-0.1.0rc3-cp314-cp314-macosx_11_0_arm64.whl

Download URL toony-0.1.0rc3-cp314-cp314-macosx_11_0_arm64.whl
Size 399.9 kB
Tags CPython 3.14 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
b551969ca6bc7f05ce5c77f446cab9a050f7382493ea2c3f3b384ee9653f9896
BLAKE2b-256 checksum
How to use checksums
c0f29e6d4791d82707aaade7cb63b25750e0253bd485ee18507c7d19064076ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / toony-0.1.0rc3-cp313-cp313-manylinux_2_28_x86_64.whl

Download URL toony-0.1.0rc3-cp313-cp313-manylinux_2_28_x86_64.whl
Size 444.0 kB
Tags CPython 3.13 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
1b77aac83c77d9190d28406a113f68f0a7922163a4671d7450e0adba733eca6a
BLAKE2b-256 checksum
How to use checksums
1d4b8ebb0f3c6399d40db10d7efa6d227426f966ae77f5033c3efc31fbb4c5f4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / toony-0.1.0rc3-cp313-cp313-macosx_11_0_arm64.whl

Download URL toony-0.1.0rc3-cp313-cp313-macosx_11_0_arm64.whl
Size 399.7 kB
Tags CPython 3.13 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
4f0195c42e89c0e68547e2e8e633dffec6ba339357d4c862dc62b565115022f5
BLAKE2b-256 checksum
How to use checksums
61e62c004c8a0904f2499365ca4e0a751c3551e9422f1e80fbbea02c6d790df3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / toony-0.1.0rc3-cp312-cp312-manylinux_2_28_x86_64.whl

Download URL toony-0.1.0rc3-cp312-cp312-manylinux_2_28_x86_64.whl
Size 444.2 kB
Tags CPython 3.12 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
3a02ef3e05c2334384400d3c7e854ad8c67f3294fe7ef95a1ee9d1b6a483efb8
BLAKE2b-256 checksum
How to use checksums
bd57b2860bda27935649d037a51a3561c54e3cfabb03d5b35c365e2181d1f18d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / toony-0.1.0rc3-cp312-cp312-macosx_11_0_arm64.whl

Download URL toony-0.1.0rc3-cp312-cp312-macosx_11_0_arm64.whl
Size 400.0 kB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
a67a2f46d68a2c89739bcdd73030ce83891a141576a830dce90d1b98af412f85
BLAKE2b-256 checksum
How to use checksums
1803e3a5acfc4e06d7c39e6a37849f3ba51e9ea1a88a0dfcfead2d9f45a0b8ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / toony-0.1.0rc3-cp311-cp311-manylinux_2_28_x86_64.whl

Download URL toony-0.1.0rc3-cp311-cp311-manylinux_2_28_x86_64.whl
Size 444.9 kB
Tags CPython 3.11 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
5a2c317226f3be258b154030f9e37f593c5a0ba292bab2eb10d0d2ba5cb9772e
BLAKE2b-256 checksum
How to use checksums
821de33c6650562633e0c4eae44a4f510bbc305ac99e96131dd801ef2ae45881
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / toony-0.1.0rc3-cp311-cp311-macosx_11_0_arm64.whl

Download URL toony-0.1.0rc3-cp311-cp311-macosx_11_0_arm64.whl
Size 403.1 kB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
7a37fc61e14d4c41e52f3e1243f1218fdb5b187f65387ddf8850fb75db94f072
BLAKE2b-256 checksum
How to use checksums
744bbe095f6c87568dd4a8172a2b92f719809970009aff780f80f65b5b41b749
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Security for toony 0.1.0rc3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page