Metadata-Version: 2.4
Name: tallipoika
Version: 2026.7.19
Summary: Stableson (Finnish: tallipoika) - a JSON Canonicalization Scheme (JCS) implementation.
Author-email: Stefan Hagen <stefan@hagen.link>
Maintainer-email: Stefan Hagen <stefan@hagen.link>
License-Expression: MIT
Project-URL: Documentation, https://codes.dilettant.life/docs/tallipoika
Keywords: developer-tools,devops
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Dynamic: license-file

# tallipoika

A stable son (Finnish: tallipoika) — a JSON Canonicalization Scheme (JCS) implementation conforming to RFC 8785.

Requires Python 3.11 or later.

## Install

```
pip install tallipoika
```

## Manual

The [man page](docs/man/tallipoika.1) provides the CLI reference (`man tallipoika` after placing the file on your `MANPATH`):

```sh
mkdir -p ~/.local/share/man/man1
cp docs/man/tallipoika.1 ~/.local/share/man/man1/
```

## Quickstart

Run `tallipoika` with no arguments for a usage summary,
or `tallipoika --version` to check the installed version.

The library function for canonical JSON is `canonicalize`:

```python
from tallipoika.api import canonicalize

result = canonicalize({"b": 2, "a": 1})
# b'{"a":2,"b":1}'
```

To serialize without key sorting, use `serialize`:

```python
from tallipoika.api import serialize

result = serialize({"b": 2, "a": 1})
# b'{"b":2,"a":1}'
```

The command line tool reads JSON from a file or stdin and writes to a file or stdout:

```
tallipoika --in-path input.json --out-path output.json
echo '{"b":2,"a":1}' | tallipoika
# {"a":2,"b":1}
```

## RFC 8785 compliance

`tallipoika` implements the JSON Canonicalization Scheme (JCS) defined by RFC 8785:

- **UTF-8 output**: all output is UTF-8 encoded bytes.
- **No whitespace**: no indentation, no spaces around `:` or `,`.
- **Key sort by UTF-16BE byte order**: object keys are sorted by their UTF-16BE
  encoding, which matches the ES6 `String.prototype.localeCompare` ordering used
  by JCS-compliant implementations.
- **ES6 §7.1.12.1 number serialization**: floats are serialized using the
  shortest representation that round-trips through the ES6 number parsing algorithm.
- **NaN and Infinity rejected**: `allow_nan=False` by default per RFC 8785 §3.2.2.3.
- **Control character escaping**: code points U+0000–U+001F are escaped as `\uXXXX`.
- **Unicode passthrough**: non-ASCII characters above U+001F pass through verbatim
  (`ensure_ascii=False` by default).

## API

### `canonicalize(obj, utf8=True) -> bytes`

Produce RFC 8785 JCS-canonical JSON for `obj`.
Raises `ValueError` for NaN or Infinity float values.
Raises `TypeError` for non-serializable objects.

### `serialize(obj, utf8=True) -> bytes`

Produce JSON without key sorting; all other RFC 8785 rules (number format,
control-character escaping, no whitespace) still apply.

### `JSONEncoder`

The underlying encoder class with JCS defaults:

```python
from tallipoika.api import JSONEncoder

encoder = JSONEncoder(sort_keys=True)
output = encoder.encode({"b": 2, "a": 1})
# '{"a":2,"b":1}'
```

Constructor keyword arguments and their JCS defaults:

| Argument         | JCS default  | Description                                         |
|:-----------------|:-------------|:----------------------------------------------------|
| `skipkeys`       | `False`      | Skip non-string keys instead of raising `TypeError` |
| `ensure_ascii`   | `False`      | Escape non-ASCII; disabled for Unicode passthrough  |
| `check_circular` | `True`       | Raise `ValueError` on circular references           |
| `allow_nan`      | `False`      | Reject NaN/Infinity per RFC 8785 §3.2.2.3           |
| `sort_keys`      | `True`       | Sort object keys by UTF-16BE byte order             |
| `indent`         | `None`       | No indentation                                      |
| `separators`     | `(',', ':')` | No whitespace around `,` or `:`                     |
| `default`        | `None`       | Custom serializer for non-standard types            |

## CLI

```
tallipoika [--in-path PATH] [--out-path PATH] [--serialize-only] [--version]
```

| Option             | Default | Description                                               |
|:-------------------|:--------|:----------------------------------------------------------|
| `--in-path PATH`   | stdin   | Input JSON file; also accepted as positional argument     |
| `--out-path PATH`  | stdout  | Output path; writes bytes when path given, text to stdout |
| `--serialize-only` | off     | Serialize only — do not sort keys                         |
| `--version`, `-V`  | —       | Print version string and exit                             |

## Design and requirements

| Document                            | Identifier  | File                                                      |
|:------------------------------------|:------------|:----------------------------------------------------------|
| Software Requirements Specification | TAL-SRS-001 | [docs/requirements/srs/](docs/requirements/srs/README.md) |
| Software Design Description         | TAL-SDD-001 | [docs/design/sdd/](docs/design/sdd/README.md)             |

Both documents follow the MIL-STD-498 DID structure.

## Bug Tracker

Any feature requests or bug reports shall go to the [todos of tallipoika](https://todo.sr.ht/~sthagen/tallipoika).

## Primary Source repository

The main source of `tallipoika` is on a mountain in Central Switzerland under
configuration control ([fossil](https://fossil-scm.org/)).

## Contributions

If you like to share small changes under the repositories license please kindly
do so by sending a patchset.
You can send such a patchset per email using [git send-email](https://git-send-email.io).

## Support

Please kindly submit issues at https://todo.sr.ht/~sthagen/tallipoika or write plain
text email to ~sthagen/tallipoika@lists.sr.ht to support.
Thanks.

## Security Policy

See `SECURITY.md` for the security policy.

## Changes

See [docs/releases/](docs/releases/README.md) for release summaries
and [docs/releases/changes/](docs/releases/changes/README.md) for the detailed change log.

## Coverage

The test suite maintains high branch coverage (≥97%).
The HTML report (if generated) is in `site/coverage/`.

## SBOM

Runtime dependency information is published in `docs/sbom/` in SPDX 3.0 (JSON-LD)
and CycloneDX 1.6 (JSON) formats.
See `docs/sbom/README.md` for the component inventory and validation guide.
