shcl
Simple Hierarchical Config Language. Forgiving to write, predictable to read.
Values are stored as plain text and coerced only when your code asks for a type, so a config file can never silently decide that NO means false. A bad line is skipped or repaired with a diagnostic instead of taking down the whole file.
Pure standard library, no dependencies, one module. Held byte-for-byte against the Rust reference by a shared conformance corpus.
Install
pip install shcl
Use
from shcl import Document, FileStatus, Status
# Reads and parses in one call, and never raises: the document is usable
# either way, and the status separates missing from unreadable from
# parsed-with-errors.
doc, file_status = Document.load_file("server.shcl")
if file_status is FileStatus.NotFound:
print("no config yet - using defaults")
# One call, a typed value, a visible fallback at the call site.
limit = doc.get_int("site[example.com].max-upload-mb", default=10)
# Or ask why a read failed: Good, Empty, NotFound, BadType, Multiple.
r = doc.read_int("site[example.com].max-upload-mb")
if r.status is not Status.Good:
print(r.status, r.raw)
# Wildcards read across instances, with a status per slot.
roots = doc.read_string_array("site[*].root")
# Writes through a temp file and a rename, so an interrupted save cannot
# truncate the config - and raises SaveRefused if the load dropped a line this
# write would delete (save_file_lossy is the override).
# A setter reports whether the write applied: a path that cannot be written
# writes nothing at all, and write_reason names which of the five reasons.
if not doc.set_int("site[example.com].max-upload-mb", limit * 2):
print(doc.write_reason("site[example.com].max-upload-mb"))
doc.save_file("server.shcl")
Document.parse never raises, and neither does load_file. When you want a hard error instead, use Document.parse_with(text, Strictness.Strict), which raises LoadError. A get_* call with no default= raises StatusError rather than inventing a value.
Also here: merge for layered config (defaults, site, user), validate against a schema that is itself a SHCL file, a full writer, and a canonical formatter that preserves comments.
Python 3.9 or newer.
Compatibility
Bindings are versioned in lockstep, so 2.x is the same behavior in every language. shcl~=2.0 picks up minor and patch releases on its own and never crosses a major version.
The CLI
This package is the library only. The shcl command comes as a prebuilt binary and as .deb/.rpm/Windows packages - see https://github.com/jim-collier/shcl.
Docs
Language spec, formal grammar, and the other bindings: https://github.com/jim-collier/shcl
License
MIT. SHCL™ is a trademark of Jim Collier - see the trademark policy.
Release files for shcl 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| shcl-2.0.0.tar.gz | 53.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| shcl-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 105.3 kB
Release files / shcl-2.0.0.tar.gz
| Download URL | shcl-2.0.0.tar.gz |
|---|---|
| Size | 53.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f935f4ef335c23e2f89960e9c24732b033e4cd46a5b827c559f82c782e471294
|
|
BLAKE2b-256 checksum How to use checksums |
f132240940306309308eb259d2bc93e33b5e30e7ff67be0b4e6a28a42891ae7c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Release files / shcl-2.0.0-py3-none-any.whl
| Download URL | shcl-2.0.0-py3-none-any.whl |
|---|---|
| Size | 52.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
73e741ace9e40a0be2ec3190c7e8ef8e2864837bf37dc14efbcefdf66726af6c
|
|
BLAKE2b-256 checksum How to use checksums |
779f741b746b06d295d4bb6c38cdc207b5829d7251a9a7e5c089cabc06ae7f25
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|