Skip to content

Latest commit

 

History

History
742 lines (597 loc) · 37.4 KB

api.md

File metadata and controls

742 lines (597 loc) · 37.4 KB
doc_radar
sentinels
file contains
../src/unstd/time/timeutil.py
wall_ns = _time.time_ns
perf_ns = _time.perf_counter_ns
strptime = datetime.strptime
combine = datetime.combine
from_iso = datetime.fromisoformat
def parse_iso(
file contains
../src/unstd/yaml/__init__.py
if name in ("pyyaml", "ruamel"):
globals()[name] = backend
file contains
../tests/suites/assurance/gates/packaging/test_public_api.py
def test_public_inventory_retains_all_exports(
file contains
../src/unstd/fs/__init__.py
def ensure_dir(path: _Pathish, *, check_first: bool = True)
if not check_first or not p.is_dir():
file contains
../src/unstd/math/__init__.py
def within(
"within",

Public API inventory

This is the supported import surface of unstd. Source links provide the full signatures, overloads, errors, and behavioral contracts. Package and module names remain stable when their private implementation is reorganized.

Imports and package boundaries

The root package provides the lazy __version__ attribute. Importing unstd does not eagerly import every package or optional dependency. Import the packages or domain modules that the application uses:

from unstd import clone, containers, fs, iters, proc, rand, rex, toml, yaml
from unstd.audio import wavx
from unstd.cache import Cache
from unstd.compress import gzipx
from unstd.crypto import digest, tls, token
from unstd.dataset import Dataset, build
from unstd.ids import uid
from unstd import math as numeric
from unstd.model import FrozenModel, StrictModel, StrictSettings
from unstd.pack import binpack
from unstd.rand import crypto
from unstd.serde import b64, jsonx, ndjson, structs
from unstd.text import fuzz
from unstd.time import timeutil, zoned

These examples identify the available import paths; individual applications need only their relevant imports. Some capabilities require optional extras, as described below. Importing a group package such as unstd.crypto does not require importing all of its submodules.

Python module attributes can include imported dependencies and private helper names. Those incidental attributes are outside the supported API listed here. Existing backend availability flags are retained for compatibility and are listed separately at the end of this document.

Numeric calculations

Import from unstd import math as numeric. The optional math extra supplies NumPy for the focused array operations. The math guide defines input shapes, numeric policies, production use cases, and measured comparisons. These helpers accept numeric arrays extracted from dataframe columns without adding a dataframe dependency.

Module Exported API
unstd.math cosine_rows, frame, grouped_mean, mean_square, normalize_rows, pearson, topk, weighted_mean, within

topk(values, k) returns descending indices with stable ties. normalize_rows and cosine_rows accept an additive eps norm floor. mean_square reduces each matrix row, pearson correlates two vectors, and weighted_mean pools rows. Normalization, cosine, mean-square and weighted pooling accept dtype="float32" or dtype="float64" (the default) for calculation and output. grouped_mean(values, labels, groups) produces dense means including zero rows for absent labels. frame(values, length, hop) creates complete read-only frame views. Calculations default to float64; framing preserves the input numeric dtype. within(actual, expected, *, atol) returns a bool for exact integer distances with a nonnegative integer scalar or same-shaped tolerance. Operands have equal shapes; signed/unsigned extremes do not round or wrap. Relative and floating tolerances remain the caller's policy.

Persistent result cache

Import from unstd.cache import Cache.

Module Exported API
unstd.cache Cache
Cache(path, *, namespace="default", timeout=30.0, max_entries=None)
cache.get(key, default=None)
cache.set(key, value, *, ttl=None)
cache.get_many(keys) -> dict[str, Json]
cache.set_many(values, *, ttl=None)
cache.delete(key) -> bool
cache.clear() -> int
cache.get_or_compute(key, factory, *, ttl=None, codec=None)

Cache persists JSON values in a dedicated local SQLite database. Instances open a fresh connection per operation, so the same instance can be shared by threads and needs no close() or context manager. Namespaces isolate keys and clear(); max_entries applies FIFO eviction within the writing namespace. Reads decode independent values and preserve the documented JSON normalization, including tuple-to-list conversion.

get_or_compute(..., codec=codec) instead preserves a typed artifact return: the codec exposes encode(value: T) -> bytes and validating decode(bytes) -> T as methods or callable attributes. Cold and warm results both pass through the decoder; cold validation failure publishes nothing, and malformed warm data raises without recomputing. All readers must use the same codec and a versioned artifact namespace. The other read/write methods retain their JSON contract.

An optional nonnegative ttl is measured in seconds from a successful write or producer completion. Expired values behave as missing; writes clean them up. get_many reads live hits in one consistent snapshot; set_many publishes a fully prepared mapping atomically in one transaction. Empty batches avoid I/O. get_or_compute rechecks under a key lock and computes outside SQLite transactions. Different lock stripes fill concurrently while same-key callers share a result. Warm reads and unrelated writes continue during computation. Canonical database paths and lock identities are prepared once per handle. Mutations use the same bounded 64-stripe protocol; clearing fences in-flight fills. A producer may read warm dependencies but same-database mutations or nested cold fills raise RuntimeError. Failures publish nothing, and a crash or later expiry can cause recomputation. External side effects are outside the cache transaction. No extra is required. See the cache guide for usage, validation, storage, and contention limits.

Indexed JSON datasets

Import from unstd.dataset import Dataset, build.

Module Exported API
unstd.dataset Dataset, build
build(path, rows, *, max_row_bytes=16_777_216) -> int
Dataset(path)
len(dataset) -> int
dataset[index] -> Json
dataset[slice] -> list[Json]
dataset.take(indices) -> list[Json]
dataset.iter_rows(start=None, stop=None, step=1) -> Iterator[Json]
dataset.batches(size=1024, *, start=0, stop=None) -> Iterator[list[Json]]
dataset.verify() -> None
dataset.close() -> None

build atomically publishes a standalone indexed JSON file from one pass over an iterable. Dataset opens it as a read-only Sequence, with constant-time length and offset lookup. Slices return lists; take preserves requested order and duplicates; lazy row slices and bounded batches support streaming consumers. Each read returns independent JSON values. Use a context manager or call close(); closed reads fail with ValueError.

Opening checks geometry and endpoints. verify checks all row offsets and the SHA-256 body checksum without JSON decoding. Native row extraction is optional; compiler-free installs retain the same behavior. No extra is required. The dataset guide describes resource ownership, atomic publication, integrity, and platform limits.

Audio

Import from unstd.audio import wavx.

Module Exported API
unstd.audio.wavx Writer, blocks, decode_pcm, read, wrap_pcm, write

read returns (samples, samplerate); blocks yields sample chunks. write writes samples, wrap_pcm adds a WAV header to a contiguous PCM buffer, and decode_pcm(raw, *, channels=1, width=2, dtype="float32") converts raw frames directly to independent samples. Mutable and typed buffers are accepted; sizes count bytes. decode_pcm rejects incomplete frames and nonpositive channels. The audio extra provides soundfile and NumPy. The stdlib fallback supports PCM16 with Python sample lists; NumPy without soundfile also supports the documented 8/16/32-bit read and PCM16/PCM32 write paths.

Writer owns incremental WAV output:

Writer(path_or_file, samplerate, *, channels=1, subtype="PCM_16")
writer.write(samples) -> None
writer.close() -> None

It also supports with Writer(...) as writer; entering returns the writer and exiting closes it. Channel count and subtype are fixed at construction. Output must support the seeking needed to finalize the WAV header.

PathOrFile and Samples remain named annotation aliases in wavx; they are not additional wildcard exports.

Cloning

Import from unstd import clone.

Module Exported API
unstd.clone asdict, copy, deep, deepcopy
unstd.clone.structural The same four objects, available through the existing module path

copy and deepcopy are the original stdlib functions. deep is the structural clone operation; asdict preserves the documented dataclasses.asdict behavior. deep preserves shared-reference identity within each clone: repeated references to one source object reach one cloned object. Owned mutable data is independent of the source; immutable atoms may stay shared. Foreign copy hooks receive the same memo and control their own result. asdict retains the stdlib conversion's separate copies at structural positions. No extra is needed.

Compression

Import from unstd.compress import gzipx.

Module Exported API
unstd.compress.gzipx BadGzipFile, GzipFile, compress, decompress, open
unstd.compress.zlibx zlib constants, complete-buffer codecs, compressor objects, checksums; original stdlib incremental decompressor
unstd.compress.bz2, .lzma, .zlib, .zipfile, .tarfile Complete original stdlib modules, including qualified imports
unstd.compress.zstandard Complete original zstandard module with unstd[zstd]
unstd.compress.zstd Complete original compression.zstd module on Python 3.14+
unstd.compress.libarchive Original libarchive-c package and qualified child modules with unstd[archives] and a native libarchive library

These preserve the running interpreter's gzip API and defaults. BadGzipFile is the stdlib exception. GzipFile exposes the stdlib binary file interface, including reading, iteration, seeking, writing, flushing, closing, and context management. open also supports the stdlib text modes. The compress extra enables native codecs; a base install uses stdlib gzip.

Linux streaming selects zlib-ng; macOS retains platform libz. The interpreter still supplies framing, member checks, output budgets and error-delivery order. zlibx accelerates compression, complete-buffer decoding and checksums while retaining the interpreter's exact incremental decompressor state. Python 3.15 also retains its stdlib compressor state, avoiding zlib-ng's finished-copy lock error. Both accelerated interfaces preserve recovered bytes; compressed output can differ by engine. Use from unstd.compress import zlib where persisted compressed bytes must match the running interpreter's stock codec.

Original-module ports preserve module, class, exception and native callback identity and add no per-operation adapter. Their upstream version-specific contracts remain in force. Archive policies, cumulative expansion limits and Zstandard frame/window checks remain caller responsibilities. See the port contract matrix for consumer operation mapping and verification.

Containers

Import from unstd.containers import Map, SortedDict, SortedList, SortedSet.

Module Supported API
unstd.containers Map, SortedDict, SortedList, SortedSet
unstd.containers.persistent Map
unstd.containers.sorted SortedDict, SortedList, SortedSet

With the containers extra, Map is the actual immutables.Map. Sorted collections use compatible subclasses of sortedcontainers when the optional CPython kernels are available, and the original classes otherwise. Constructors, methods, generic typing and iteration retain the backend API; accelerated sorted class identities differ from the upstream classes. For example, Map.set and Map.delete return new persistent mappings. Missing backends leave importable placeholders that raise an actionable ImportError on construction. Each family loads on first access to its types or submodule.

Cryptography and TLS

Import from unstd.crypto import digest, token, tls.

Module Exported API
unstd.crypto.digest DIGEST_BYTES, Stream, derive_key, hex, legacy_blake2b, raw
unstd.crypto.token KEY_BYTES, SEPARATOR, TAG_BYTES, equal, mac_hex, mac_raw, mint, prepare_verifier, verify, verify_mac
unstd.crypto.tls LEGACY_MINIMUM_VERSION, MINIMUM_VERSION, TlsContext, client_context

digest and token require the crypto extra. BLAKE3 outputs, derived keys, token envelopes, and the explicit legacy BLAKE2b helper retain their algorithms and byte formats. DIGEST_BYTES, KEY_BYTES, and TAG_BYTES are each 32; SEPARATOR is ".".

Stream provides incremental BLAKE3 hashing:

Stream(chunks=())
stream.update(chunk: bytes) -> Stream
stream.raw() -> bytes
stream.hex(n: int | None = None) -> str

update returns the same stream. Reading a digest does not finalize or consume the stream; later updates remain valid. Chunks are concatenated without adding separators. The n option follows digest.hex: it counts digest bytes and produces 2n hex characters.

token.prepare_verifier(*, max_token_chars=8192) returns a callable with the surface verify(key: bytes, token: str) -> bytes | None. The returned callable retains the selected limit and backend references; keys and tokens remain call arguments. token.verify takes the same size policy as a keyword argument. Passing max_token_chars=None selects no size limit.

tls is pure stdlib. TlsContext is an annotation alias for ssl.SSLContext; client_context returns an actual stdlib context. Its parameters are cafile=None, certfile=None, keyfile=None, and minimum_version=MINIMUM_VERSION, all keyword-only. The default minimum is TLS 1.3; LEGACY_MINIMUM_VERSION names TLS 1.2. Certificate and hostname verification remain enabled.

Filesystem operations

Import from unstd import fs.

Module Exported API
unstd.fs atomic_replace, atomic_write, atomic_writer, ensure_dir, sync_dir, walk_files

ensure_dir returns a Path; walk_files yields paths. atomic_writer is a context manager for writing the replacement file; atomic_write and atomic_replace perform complete operations and return the destination Path. All three write operations accept durable=False, True, or "strict". Strict mode requires directory-sync acknowledgments before and after replacement; a post-commit failure reports that the new data is already committed. sync_dir(path, *, strict=False) returns None and suppresses OS errors by default, while strict=True reports them.

ensure_dir(path, *, check_first=True) checks before attempting creation. Use check_first=False to retain a direct Path.mkdir call's creation attempts and audit events, including when the directory already exists.

This package needs no extra or third-party runtime dependency. Ordinary GIL-enabled Linux CPython builds use the bundled native atomic_write backend for exact bytes and default UTF-8 text with an existing parent. Other platforms, unsupported inputs, custom OS/path bindings, and unavailable native capabilities retain the complete Python path. Native I/O errors propagate without retrying the write. atomic_writer retains the Python streaming implementation. The filesystem guide describes admission, mode preservation, cancellation, cleanup notes, and the durability limits.

Identifiers

Import from unstd.ids import uid.

Module Exported API
unstd.ids.uid derive, new, new_hex, parse

new() returns a hyphenated UUIDv7 string; new_hex() returns its 32-character hex form. parse is the original stdlib uuid.UUID class and returns UUID objects. derive is the original stdlib uuid.uuid5 function; identical namespace/name inputs retain their existing UUIDv5 values. The ids extra accelerates minting, with the documented stdlib fallback.

Iterators

Import from unstd import iters, or import individual combinators from it.

Module Exported API
unstd.iters batched, chunked, first, flatten, ilen, last, nth, pairwise, partition, runs, take, unique_everseen, unique_justseen, windowed
unstd.iters.consecutive chunked, runs, windowed
unstd.iters.distinct unique_everseen, unique_justseen
unstd.iters.reshape flatten, partition
unstd.iters.select first, ilen, last, nth, take

batched and pairwise are the stdlib objects. Existing submodule imports resolve to the same combinators exposed by iters. This package needs no extra.

Models and settings

Import from unstd.model import StrictModel, FrozenModel, StrictSettings.

Module Exported API
unstd.model FrozenModel, StrictModel, StrictSettings
unstd.model.base FrozenModel, StrictModel
unstd.model.settings StrictSettings

These are subclassable model bases with inherited Pydantic interfaces, including validation, field access, serialization, JSON schema, and model configuration. They add no separate instance methods. StrictModel forbids unknown fields and accepts names or aliases; FrozenModel adds frozen instances; StrictSettings ignores unknown root inputs and accepts names or aliases. The model extra is required. The same class objects remain available at the existing submodule paths.

Binary packing

Import from unstd.pack import binpack, ragged.

Module Exported API
unstd.pack.binpack Struct, calcsize, error, iter_unpack, pack, pack_array, pack_array_portable, pack_into, unpack, unpack_array, unpack_array_portable, unpack_from
unstd.pack.ragged RaggedDecoder

The scalar functions, Struct, and error are the exact stdlib struct objects. Compiled Struct instances keep their stdlib format, size, pack, pack_into, unpack, unpack_from, and iter_unpack interfaces.

pack_array and unpack_array retain backend-dependent conversion and array/view return behavior. The pack extra provides NumPy. The explicit pack_array_portable and unpack_array_portable functions always use the portable dtype subset and stdlib validation, returning bytes and an owned list.

RaggedDecoder(dtype, *, columns, index_dtype="=i8", finite=False, allow_empty=True) compiles an integer-boundary table followed by numeric rows. unpack(buf, *, index_count) validates geometry, boundaries, and the configured finite-value constraint on every call. Exact bytes back immutable NumPy views; other contiguous exporters snapshot before validation. Without NumPy, results are tuple rows and integer boundaries. The optional native validator and stdlib fallback enforce the same contract. Identity, publication limits, and normalization remain with the caller.

unpack_array and unpack_array_portable accept keyword-only offset=0 in bytes and count=-1 in elements. The default count consumes the whole remainder; an explicit nonnegative count selects a region without slicing and permits unrelated trailing bytes. Portable decoding validates bounds and always returns independent Python scalars; NumPy decoding retains views over the original buffer.

Portable packing can copy matching primitive storage from exact one-dimensional array.array and NumPy arrays, including admitted strides and byte orders, without boxing every scalar. Integer width/signedness and float64 must match; float16/float32 conversions, subclasses and other iterables retain stdlib validation. Output remains owned bytes. The packing guide documents admission and fallback.

Processes

Import from unstd import proc.

Module Exported API
unstd.proc DEFAULT_TIMEOUT, CalledProcessError, CompletedProcess, ProcessError, TimeoutExpired, capture, run, run_ok

DEFAULT_TIMEOUT is 60.0 seconds. CalledProcessError and TimeoutExpired are the original stdlib exception classes. run returns CompletedProcess, run_ok returns a boolean, and capture returns stripped stdout. Execution continues to use explicit argument sequences, captured output, and finite positive timeouts.

An optional bundled C backend handles admitted macOS process creation and captured output without stdin on Linux/macOS. Linux keeps stdlib creation; bounded waits use kernel exit notifications. Unsupported shapes retain stdlib execution. The public signatures, captured output, timeout exceptions and direct-child cleanup contracts are unchanged. See the backend details and measurements.

CompletedProcess(argv, returncode, stdout, stderr, duration) is a frozen, slotted dataclass with these public instance members:

Member Meaning
argv: tuple[str, ...] Executed arguments
returncode: int Child exit status
stdout: str Captured decoded standard output
stderr: str Captured decoded standard error
duration: float Elapsed execution time in seconds
ok: bool Read-only property, true for exit status zero

ProcessError(result) is a CalledProcessError subclass. Its result member holds the CompletedProcess; inherited returncode, cmd, output, stdout, and stderr remain available. Its string representation includes captured stderr. Both result classes retain the public module identity unstd.proc, including for class lookup and CompletedProcess pickles, while their definitions live privately.

Randomness

Import from unstd import rand; use rand.crypto for secure draws.

Module Supported API
unstd.rand Generator, choice, choices, crypto, floats, ints, randint, random, sample, seed, shuffle, uniform
unstd.rand.draw Generator, choice, choices, floats, ints, randint, random, sample, seed, shuffle, uniform
unstd.rand.crypto below, bits, choice, token_bytes, token_hex, token_urlsafe

Module-level scalar calls use the shared stdlib PRNG; optional NumPy accelerates bulk draws. The secure functions are the original secrets functions, with below naming secrets.randbelow and bits naming secrets.randbits. Seeding does not affect secure randomness.

Generator owns an independent stream:

Generator(seed=None, *, backend="stdlib", bit_generator=None)
generator.backend -> Literal["stdlib", "numpy"]
generator.seed(n: int | None = None) -> None
generator.random() -> float
generator.randint(a: int, b: int) -> int
generator.uniform(a: float, b: float) -> float
generator.choice(seq: Sequence[T]) -> T
generator.shuffle(x: MutableSequence[T]) -> None
generator.sample(population: Sequence[T], k: int, *, counts=None) -> list[T]
generator.floats(n: int, *, low=0.0, high=1.0) -> FloatArray
generator.ints(n: int, low: int, high: int, *, endpoint=False, seeds=None) -> IntArray
generator.choices(seq: Sequence[T], n: int, *, weights=None) -> list[T]

backend is read-only. NumPy selection is explicit and requires the rand extra. bit_generator accepts PCG64, PCG64DXSM, SFC64, or Philox when using NumPy. Instance streams do not reseed module-level draws. FloatArray and IntArray remain the existing return annotation aliases in rand.draw.

Module-level ints accepts the same seeds=None keyword. Supplying one unsigned 64-bit integer key per result selects the explicit SplitMix64-v1 stream, with effective inclusive output bounds in signed int64. This opt-in changes values relative to constructing an MT19937 generator per key. It preserves each key's value across reordered/chunked batches and leaves both ordinary engines untouched; duplicate keys repeat results. Counts, keys and bounds are validated even for empty batches. Return containers retain the selected backend's list or int64 ndarray contract. Secure draws continue to use rand.crypto.

Generator.shuffle can use an optional CPython kernel for ordinary lists while preserving exact stdlib permutations and subsequent RNG state. Custom methods, engine hooks, sequence types and missing native support retain stdlib execution. Module-level scalar aliases keep their direct stdlib bindings. The rand guide covers these choices; the qualification separates keyed count-phase speedups from complete consumer costs.

Regular expressions

Import from unstd import rex.

Category Exported API
Functions compile, compile_faithful, compile_linear, error, escape, findall, finditer, fullmatch, match, purge, search, split, sub, subn
Types and policy exception LinearRegexError, Match, Pattern, RegexFlag
Flags ASCII, DEBUG, DOTALL, IGNORECASE, LOCALE, MULTILINE, NOFLAG, UNICODE, VERBOSE, A, I, L, M, S, U, X

unstd.rex preserves the stdlib flag/type objects, error, and escape. compile retains its documented native dialect boundaries; compile_faithful uses Python semantics with fallback; compile_linear requires native execution and raises LinearRegexError when that guarantee cannot be met.

Ordinary compiled patterns expose search, match, fullmatch, finditer, findall, split, sub, subn, and pattern metadata such as pattern, flags, groups, and groupindex. Existing stdlib ancillary operations remain available where the selected ordinary pattern supplies them. Match values retain their documented stdlib/native projections and callback behavior.

Strict patterns returned by compile_linear support search, match, and fullmatch, plus pattern, flags, groups, groupindex, and the read-only requires_ascii property. Iteration, splitting, replacement, and scanner operations are refused with LinearRegexError. No public constructor for the private pattern adapter classes is added.

Serialization

Import from unstd.serde import jsonx, b64, ndjson, structs as needed.

Module Exported API
unstd.serde.jsonx JSONDecodeError, JSONDecoder, JSONEncoder, Json, canonical, canonical_strict, dump, dump_array, dumpb, dumps, iterload, load, loads
unstd.serde.b64 Error, b64decode, b64encode, decode, decode_file, decode_json, decode_text, decodebytes, encode, encode_file, encode_json, encodebytes, standard_b64decode, standard_b64encode, urlsafe_b64decode, urlsafe_b64encode
unstd.serde.ndjson NDJSONDecodeError, dump, dumpb, dumps, iter_loads, load, loads
unstd.serde.structs Codec, DecHook, EncHook, FloatHook, Order, float_enc_hook

jsonx retains stdlib JSON formatting, hooks, classes, and errors. JSONEncoder, JSONDecoder, and JSONDecodeError are stdlib's original objects, including their existing instance interfaces. dumpb adds compact UTF-8 bytes. The legacy canonical format remains stable; canonical_strict provides its existing restricted-value format. Neither format changes during module reorganization.

jsonx.iterload(fp, *, chunk_size=65536, **kw) lazily reads a top-level JSON array from a text or binary stream. Each item is decoded independently with loads and its options; the outer array is framing only. Memory follows the chunk and largest item. The caller owns the stream. Exhaust the iterator to validate the closing bracket and trailing input. Errors use positions within the current item or chunk.

jsonx.dump_array(rows, fp, *, chunk_size=65536, sort_keys=False, default=None, numpy=False) writes an iterable as a compact JSON array and returns its record count. Each record uses dumpb; binary sinks receive UTF-8 and io.TextIOBase sinks receive Unicode. Buffering follows the chunk and largest record, with each write request bounded by the chunk size. Short writes are completed. Batching can consume records ahead of a sink failure, which leaves partial output. The caller owns flushing and closing the destination.

b64.Error is binascii.Error. Standard Base64 functions keep their documented stdlib signatures and behavior. Convenience encode/decode keep their distinct text, URL, padding, and validation defaults. encode_file/decode_file retain the stdlib stream functions under the established non-conflicting names.

All six NDJSON read/write functions support the optional codec= argument. Readers accept skip_errors=False and on_error=None. NDJSONDecodeError instances expose lineno (the physical one-based line number) and err (the original parsing or validation exception).

structs requires the serde extra. Codec[T] has this constructor:

Codec(
    spec: type[T],
    *,
    enc_hook=None,
    dec_hook=None,
    order=None,
    decimal_format="string",
    uuid_format="canonical",
    strict=True,
    float_hook=None,
)
codec.encode(value: T) -> bytes
codec.decode(raw: bytes | str) -> T
codec.decode_or(raw: bytes | str, default: T | None = None) -> T | None

encode and decode are bound callable attributes backed by reusable msgspec codecs. decode_or returns the default for msgspec decoding/validation failures and malformed Unicode, with other exceptions propagating. order accepts None, "deterministic", or "sorted"; decimal_format accepts "string", "number", or a callable over Decimal; uuid_format accepts "canonical" or "hex". EncHook, DecHook, FloatHook, and Order name the public annotation types used by this constructor.

Untyped JSON, Base64, and NDJSON remain usable without the extra through their stdlib paths.

Text matching

Import from unstd.text import fuzz.

Module Exported API
unstd.text.fuzz best_match, cdist, difflib_ratio, distance, extract, indel_ratio, jaro_winkler, ratio

The text extra supplies RapidFuzz. The historical ratio keeps its existing backend-selected metric. indel_ratio and difflib_ratio name explicit algorithms. best_match, extract, and cdist retain scorer= selection and the documented cutoff/tie behavior. Portable implementations remain available.

Time

Import from unstd.time import timeutil, zoned as needed.

Module Exported API
unstd.time.timeutil Unit, combine, date_from_iso, date_today, datetime_today, elapsed_ms, epoch_ms, epoch_s, from_epoch_ms, from_epoch_s, from_iso, from_timestamp, gmtime, human, iso, localtime, mono, mono_ns, now, now_tz, parse_date, parse_iso, parse_utc, perf, perf_ns, process_time, process_time_ns, proto_timestamp, proto_timestamp_ms, sleep, span, strftime, strptime, thread_time, thread_time_ns, time_from_iso, today, utcnow, wall, wall_ns
unstd.time.zoned Disambiguate, Instant, PlainDateTime, RepeatedTime, SkippedTime, ZonedDateTime, instant, now, parse, to_utc, wall

timeutil uses stdlib time/datetime values. Clocks, sleep, native calendar reads, conversion, formatting and assembly are direct native bindings. Thread CPU clocks retain platform availability. now() and from_timestamp(seconds) are local and naive by default; pass a zone for an aware result. utcnow is the pre-bound UTC datetime call.

from_iso, date_from_iso, time_from_iso, and strptime retain native accepted forms and exceptions. parse_iso, parse_date, and parse_utc return None for invalid input; parse_utc also normalizes aware values to UTC and reads naive values as UTC.

Unit is "seconds" | "minutes" | "hours" | "days". Only the protobuf bridge requires the proto extra, loaded on demand.

zoned requires the time extra. Its Instant, PlainDateTime, ZonedDateTime, RepeatedTime, and SkippedTime names are the actual whenever classes and exceptions, preserving their constructors and instance APIs. now is bound from ZonedDateTime.now. Disambiguate is "compatible" | "raise" | "earlier" | "later"; the wall-clock helpers preserve their existing fold/gap policies and return types.

TOML

Import from unstd import toml.

Module Exported API
unstd.toml TOMLDecodeError, aot, array, comment, document, dump, dumps, inline_table, item, load, loads, nl, parse, table

load, loads, and TOMLDecodeError are stdlib tomllib objects. Writing and editable builders require the toml extra. parse and the builders remain tomlkit's own objects; their editable document/node APIs are retained. dump and dumps keep the existing common-dialect validation for plain data and preserve metadata on tomlkit values. Missing write capabilities raise an actionable ImportError while stdlib reads continue to work.

YAML

Import from unstd import yaml.

Module Exported API
unstd.yaml YAMLError, YamlScalar, YamlValue, dump, dump_all, dumps, load, load_all, loads, parse

The yaml extra provides both backend contracts. yaml.pyyaml and yaml.ruamel are lazy public module bindings outside the wildcard exports. Each is the original backend, retaining its loaders, dumpers, exceptions, nodes and events. Accessing one does not import the other or the YAML 1.2 codec.

from unstd.yaml import pyyaml as yaml

yaml.safe_load(raw)

Our document helpers use YAML 1.2 policy. loads and load read one safe document; load_all reads lazily. parse preserves editable metadata; dumps, dump, and dump_all retain it when writing. Duplicate-key and unknown-tag rejection remain part of the parser policy. YAMLError is the backend exception when installed, and retains the existing ValueError fallback when absent.

YamlScalar covers strings, integers, floats, booleans, bytes, dates, datetimes, and None. YamlValue additionally covers the documented recursive mappings, lists, tuples, and mutable sets. Both aliases retain their public unstd.yaml identity even though validation and parser policy live in private modules.

Compatibility paths and private implementation

Existing application imports continue to use their established module paths. The public submodules listed above are retained, including direct imports from clone.structural, containers.sorted, containers.persistent, iters' combinator modules, model.base, model.settings, and rand.draw.

The following legacy availability attributes remain accessible and remain in their existing __all__ lists so wildcard imports keep working. They are compatibility diagnostics rather than the supported capability API for new code:

Module Retained flag
unstd.rand HAVE_NUMPY
unstd.rand.draw HAVE_NUMPY
unstd.containers.sorted HAVE_SORTEDCONTAINERS
unstd.containers.persistent HAVE_IMMUTABLES

Supporting modules have descriptive concern names; their location does not add them to the supported API. The bundled extension modules unstd.serde._json_native, unstd.clone._clone_native, unstd.crypto._stream_native, unstd.text._text_native, unstd.compress._gzip_native, unstd.containers._sorted_native, unstd.proc._proc_native, and unstd.pack._pack_native retain their private import names for build/runtime compatibility. They are not user APIs, and users do not need to import them to enable acceleration. Their presence may differ between builds.

Backend handles, native admission helpers, caches, parser subclasses, and other underscore names are private. Moving their source does not introduce a public native package or a new application configuration surface. Intentionally public stdlib/backend classes and builders remain the original objects where the existing API promises that identity.