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
Built Distributions
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 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5a19f2004e768b156baff8c284869bcf28c59c69a61021a12796f3d1435c0f0c
|
|
| MD5 |
018b46ee0e02c06ef3628e17553b9a11
|
|
| BLAKE2b-256 |
c363b4daa0529a25795a25756a064b97a82a670572f9a93f0e012529e46283e1
|
Provenance
The following attestation bundles were made for csexpr-0.1.0.tar.gz:
Publisher:
release.yml on AndreKoraleski/csexpr
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
csexpr-0.1.0.tar.gz -
Subject digest:
5a19f2004e768b156baff8c284869bcf28c59c69a61021a12796f3d1435c0f0c - Sigstore transparency entry: 2704333600
- Sigstore integration time:
-
Permalink:
AndreKoraleski/csexpr@620385c1fcab5a1aea5e57fdbd124865d805cbe4 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/AndreKoraleski
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@620385c1fcab5a1aea5e57fdbd124865d805cbe4 -
Trigger Event:
push
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
684d5e5bc44fb5f054d269e8ab75adcd5785bbfea046b6b4c9b343add3e5bb01
|
|
| MD5 |
ac443260ba2b08a8d8a613a64b98cd93
|
|
| BLAKE2b-256 |
cff28698cecac87b35f31d03f20ff0410b85dafe9e0daebcb0838f85c3f2df0e
|
Provenance
The following attestation bundles were made for csexpr-0.1.0-cp310-abi3-win_amd64.whl:
Publisher:
release.yml on AndreKoraleski/csexpr
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
csexpr-0.1.0-cp310-abi3-win_amd64.whl -
Subject digest:
684d5e5bc44fb5f054d269e8ab75adcd5785bbfea046b6b4c9b343add3e5bb01 - Sigstore transparency entry: 2704333667
- Sigstore integration time:
-
Permalink:
AndreKoraleski/csexpr@620385c1fcab5a1aea5e57fdbd124865d805cbe4 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/AndreKoraleski
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@620385c1fcab5a1aea5e57fdbd124865d805cbe4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file csexpr-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: csexpr-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 311.4 kB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed4b666768e5a8a183e8f82290d8f5ba1711ab749e6faa4fde57422c0505ca11
|
|
| MD5 |
520c50cdcbc8d2f3f94c2c080297b13e
|
|
| BLAKE2b-256 |
66395f62d4368ad8a4bdae15af21a8312853796dfe3b83f5bc31d881ec115c7b
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
csexpr-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
ed4b666768e5a8a183e8f82290d8f5ba1711ab749e6faa4fde57422c0505ca11 - Sigstore transparency entry: 2704333638
- Sigstore integration time:
-
Permalink:
AndreKoraleski/csexpr@620385c1fcab5a1aea5e57fdbd124865d805cbe4 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/AndreKoraleski
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@620385c1fcab5a1aea5e57fdbd124865d805cbe4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file csexpr-0.1.0-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: csexpr-0.1.0-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 272.6 kB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4745592adb7ff0cb79e185d4337403de3cbca7af1e3cd85dbd23e55ec5953e4d
|
|
| MD5 |
f701574e36b05e01b8c67756acea6297
|
|
| BLAKE2b-256 |
9335d431a1b5086eaee7d8c70d4baa16969372cd0e68d31fa19900a527380ed4
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
csexpr-0.1.0-cp310-abi3-macosx_11_0_arm64.whl -
Subject digest:
4745592adb7ff0cb79e185d4337403de3cbca7af1e3cd85dbd23e55ec5953e4d - Sigstore transparency entry: 2704333703
- Sigstore integration time:
-
Permalink:
AndreKoraleski/csexpr@620385c1fcab5a1aea5e57fdbd124865d805cbe4 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/AndreKoraleski
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@620385c1fcab5a1aea5e57fdbd124865d805cbe4 -
Trigger Event:
push
-
Statement type: