Skip to main content

csexpr

S-expressions, as specified by RFC 9804. The name is short for canonical S-expression, which is what this format has long been called after the one representation of it that is unique, and by which it is known where it is used, as in SPKI and SDSI.

This package is the Rust crate of the same name, bound to Python. The parsing and the writing happen in Rust, and no Python code stands between them and you.

Install

Python 3.10 or later. One wheel per platform serves every version of it, since the extension is built against the stable ABI.

pip install csexpr

Use

An S-expression is either an octet string or a list of simpler S-expressions, and a Python value stands for one directly. bytes is an octet string, a list is a list, and Atom is an octet string that carries a display hint. Text is accepted wherever octets are, and is taken as UTF-8.

import csexpr

assert csexpr.to_canonical(["issuer", "bob"]) == b"(6:issuer3:bob)"
assert csexpr.parse(b"(6:issuer3:bob)") == [b"issuer", b"bob"]

# The three representations of §6 all carry the same value.
assert csexpr.parse(b"(issuer bob)") == [b"issuer", b"bob"]
assert csexpr.parse(b"{KDY6aXNzdWVyMzpib2Ip}") == [b"issuer", b"bob"]

# A display hint says how an octet string should be shown, and nothing else.
bob = csexpr.Atom(b"bob", hint=b"text/plain")

assert csexpr.to_advanced(["issuer", bob]) == "(issuer [text/plain]bob)"
assert csexpr.parse(b"(issuer [text/plain]bob)") == ["issuer".encode(), bob]

The three representations

Written by Looks like For
to_canonical (§6.2) (6:issuer3:bob) Hashing and signing, since one S-expression has exactly one of these
to_transport (§6.3) {KDY6aXNzdWVyMzpib2Ip} Channels that would disturb raw octets
to_advanced (§6.4) (issuer bob) Being read by a person

parse reads whichever of the three it is given. parse_canonical reads only the first, which is what verifying a signature calls for, since a signature is computed over those octets exactly.

Reading what cannot be trusted

Parser bounds the size of the input and of every octet string in it, and turns off whichever constructs an application has no use for. Each of the restrictions RFC 9804 §8 names is one keyword.

from csexpr import ParseError, Parser

parser = Parser(
    canonical=True,
    max_input_len=64 * 1024,
    max_atom_len=4096,
    max_depth=32,
    allow_display_hints=False,
    allow_empty_lists=False,
)

assert parser.parse(b"(6:issuer3:bob)") == [b"issuer", b"bob"]

try:
    parser.parse(b"(issuer bob)")
except ParseError as error:
    print(error.kind, error.offset)

A ParseError carries offset, the octet the offending construct begins at, and kind, a short name for what was wrong.

Parsing takes no stack in proportion to how deeply the input nests, and no memory on the strength of a length the input states. Lists may nest as deeply as DEFAULT_MAX_DEPTH, and writing refuses a structure nested deeper than that rather than risking the interpreter.

License

MIT, see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

csexpr-0.1.0.tar.gz (64.6 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

csexpr-0.1.0-cp310-abi3-win_amd64.whl (162.9 kB view details)

Uploaded CPython 3.10+Windows x86-64

csexpr-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (311.4 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

csexpr-0.1.0-cp310-abi3-macosx_11_0_arm64.whl (272.6 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

Details for the file csexpr-0.1.0.tar.gz.

File metadata

  • Download URL: csexpr-0.1.0.tar.gz
  • Upload date:
  • Size: 64.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for csexpr-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5a19f2004e768b156baff8c284869bcf28c59c69a61021a12796f3d1435c0f0c
MD5 018b46ee0e02c06ef3628e17553b9a11
BLAKE2b-256 c363b4daa0529a25795a25756a064b97a82a670572f9a93f0e012529e46283e1

See more details on using hashes here.

Provenance

The following attestation bundles were made for csexpr-0.1.0.tar.gz:

Publisher: release.yml on AndreKoraleski/csexpr

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file csexpr-0.1.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: csexpr-0.1.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 162.9 kB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for csexpr-0.1.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 684d5e5bc44fb5f054d269e8ab75adcd5785bbfea046b6b4c9b343add3e5bb01
MD5 ac443260ba2b08a8d8a613a64b98cd93
BLAKE2b-256 cff28698cecac87b35f31d03f20ff0410b85dafe9e0daebcb0838f85c3f2df0e

See more details on using hashes here.

Provenance

The following attestation bundles were made for csexpr-0.1.0-cp310-abi3-win_amd64.whl:

Publisher: release.yml on AndreKoraleski/csexpr

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file csexpr-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for csexpr-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ed4b666768e5a8a183e8f82290d8f5ba1711ab749e6faa4fde57422c0505ca11
MD5 520c50cdcbc8d2f3f94c2c080297b13e
BLAKE2b-256 66395f62d4368ad8a4bdae15af21a8312853796dfe3b83f5bc31d881ec115c7b

See more details on using hashes here.

Provenance

The following attestation bundles were made for csexpr-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on AndreKoraleski/csexpr

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file csexpr-0.1.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for csexpr-0.1.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4745592adb7ff0cb79e185d4337403de3cbca7af1e3cd85dbd23e55ec5953e4d
MD5 f701574e36b05e01b8c67756acea6297
BLAKE2b-256 9335d431a1b5086eaee7d8c70d4baa16969372cd0e68d31fa19900a527380ed4

See more details on using hashes here.

Provenance

The following attestation bundles were made for csexpr-0.1.0-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on AndreKoraleski/csexpr

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

4 files

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