Metadata-Version: 2.4
Name: shcl
Version: 1.0.0
Summary: SHCL - Simple Hierarchical Config Language. Parser, accessor, writer, and formatter.
Author: Jim Collier
License-Expression: MIT
Project-URL: Homepage, https://github.com/jim-collier/shcl
Project-URL: Source, https://github.com/jim-collier/shcl
Project-URL: Issues, https://github.com/jim-collier/shcl/issues
Project-URL: Changelog, https://github.com/jim-collier/shcl/blob/main/changelog.md
Keywords: config,configuration,parser,shcl
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Text Processing :: General
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# shcl

**S**imple **H**ierarchical **C**onfig **L**anguage. 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

```sh
pip install shcl
```

## Use

```python
from shcl import Document, Status

with open("server.shcl", encoding="utf-8") as f:
	doc = Document.parse(f.read())

# 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")
```

`Document.parse` never raises. 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 `1.x` is the same behavior in every language. `shcl~=1.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 ships 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](https://github.com/jim-collier/shcl/blob/main/trademark.md).
