Metadata-Version: 2.5
Name: unstd
Version: 1.0.3
Summary: stdlib-faithful accelerated replacements behind optional extras
Project-URL: Homepage, https://github.com/The-Billy-Company/unstd
Project-URL: Repository, https://github.com/The-Billy-Company/unstd
Project-URL: Changelog, https://github.com/The-Billy-Company/unstd/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/The-Billy-Company/unstd/issues
Author: The Billy Company
License-Expression: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Keywords: blake3,extras,json,msgspec,orjson,stdlib,uuid
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.12
Provides-Extra: audio
Requires-Dist: numpy>=2.5.2; extra == 'audio'
Requires-Dist: soundfile>=0.14.0; extra == 'audio'
Provides-Extra: clone
Requires-Dist: msgspec>=0.21.1; extra == 'clone'
Provides-Extra: containers
Requires-Dist: immutables>=0.21; extra == 'containers'
Requires-Dist: sortedcontainers>=2.4.0; extra == 'containers'
Provides-Extra: crypto
Requires-Dist: blake3>=1.0.9; extra == 'crypto'
Provides-Extra: ids
Requires-Dist: blake3>=1.0.9; extra == 'ids'
Requires-Dist: uuid-utils>=0.17.0; extra == 'ids'
Provides-Extra: model
Requires-Dist: pydantic-settings>=2.15.0; extra == 'model'
Requires-Dist: pydantic>=2.13.5; extra == 'model'
Provides-Extra: pack
Requires-Dist: numpy>=2.5.2; extra == 'pack'
Provides-Extra: proto
Requires-Dist: protobuf>=7.36.1; extra == 'proto'
Provides-Extra: rand
Requires-Dist: numpy>=2.5.2; extra == 'rand'
Provides-Extra: rex
Requires-Dist: irregex>=2.3.0; extra == 'rex'
Provides-Extra: serde
Requires-Dist: msgspec>=0.21.1; extra == 'serde'
Requires-Dist: orjson>=3.12.0; extra == 'serde'
Requires-Dist: pybase64>=1.5.0; extra == 'serde'
Provides-Extra: text
Requires-Dist: rapidfuzz>=3.12.0; extra == 'text'
Provides-Extra: time
Requires-Dist: whenever>=0.10.5; extra == 'time'
Provides-Extra: toml
Requires-Dist: tomlkit>=0.15.1; extra == 'toml'
Description-Content-Type: text/markdown

# unstd

stdlib-faithful accelerated replacements. Each module wraps a native codec
behind the call surface of the stdlib module it stands in for, so migrating a
call site is an import swap, not a rewrite.

```python
import json  # →
from unstd.serde import jsonx  # jsonx.dumps / jsonx.loads, same surface, faster
```

The base install is pure stdlib: depending on `unstd` adds zero third-party
closure. Every accelerated backend rides an optional extra with a guarded
import that falls back to the stdlib (or raises a clear `ImportError` where
no fallback is faithful). Install `unstd` and you pay nothing. Install
`unstd[serde]` and the serde modules light up.

## Install

```console
python3 -m pip install unstd
python3 -m pip install 'unstd[serde,ids,crypto]'
```

## Groups

| Group | Extra | Backend / fallback |
|---|---|---|
| [`serde`](src/unstd/serde/README.md) | `unstd[serde]` | orjson / msgspec / pybase64 → stdlib `json`/`base64` |
| [`ids`](src/unstd/ids/README.md) | `unstd[ids]` | blake3 / uuid-utils → `hash` requires the extra; `uid` falls back to stdlib UUIDv7 |
| [`crypto`](src/unstd/crypto/README.md) | `unstd[crypto]` | blake3 (required; hashlib ships BLAKE2, a different algorithm) |
| [`time`](src/unstd/time/README.md) | `unstd[time]` | `timeutil` is pure stdlib; `dateutil` requires `whenever`, and `timeutil`'s protobuf `Timestamp` bridge requires `unstd[proto]` |
| [`model`](src/unstd/model/README.md) | `unstd[model]` | pydantic (required) |
| [`rex`](src/unstd/rex/README.md) | `unstd[rex]` | irregex → stdlib `re` |
| [`containers`](src/unstd/containers/README.md) | `unstd[containers]` | sortedcontainers + immutables (required) |
| [`rand`](src/unstd/rand/README.md) | `unstd[rand]` | numpy PCG64 → stdlib `random`; `crypto` is always `secrets` |
| [`pack`](src/unstd/pack/README.md) | `unstd[pack]` | numpy → stdlib `struct` |
| [`clone`](src/unstd/clone/README.md) | `unstd[clone]` | msgspec → `copy.deepcopy` |
| [`text`](src/unstd/text/README.md) | `unstd[text]` | rapidfuzz → stdlib `difflib` |
| [`audio`](src/unstd/audio/README.md) | `unstd[audio]` | soundfile + numpy → stdlib `wave` |
| [`toml`](src/unstd/toml/README.md) | `unstd[toml]` | read is `tomllib`; write requires tomlkit |
| [`proc`](src/unstd/proc/README.md) | — | stdlib `subprocess` |
| [`fs`](src/unstd/fs/README.md) | — | stdlib `os` |
| [`iters`](src/unstd/iters/README.md) | — | stdlib `itertools` |

`proc`, `fs`, and `iters` ship in the base install.

## Prior art

- **orjson** (Kloss) / **msgspec** (Fitzgerald) / **pybase64** (aklomp libbase64) — the serde backends.
- The guarded-optional-backend pattern is the one uvloop popularized: import the accelerator, fall back when it is absent.

## License

Apache-2.0
