Changelog¶
All notable changes to this project are documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Unreleased¶
1.0.0 - 2026-09-08¶
Added¶
- Provenance spine:
Origin,Tracked, and a merge that records what each value shadowed. Sourceprotocol with aSourceChainsupporting name-addressed insertion, plus environment,.env, file, mapping and secrets-directory sources.- Format loaders for TOML, JSON,
.propertiesand XML on the standard library, and YAML behind thewhence[yaml]extra. YAML,.envand.propertiescarry exact line and column numbers. Discovery: a declarative five-step search chain over explicit paths,$APP_CONFIG, project roots, per-user config directories andpyproject.toml, with cross-platform directory conventions.Configwithget,require,explain,dump,bindandwith_fallback.- Interpolation with
${a.b},${a.b:-default},${?a.b},${env:VAR}and${file:/path}, resolved lazily after the merge. - Profiles, profile groups, and the invariant that profiles never reorder sources.
- Binding to frozen dataclasses (standard library) and to pydantic models when pydantic is installed, with batched errors that carry origins.
Secret,unlock_secrets(),_FILEindirection and a sanitizer applied to every dump.@settingsand@from_configdecorators.ArgvSource, reading--set key=valueout ofsys.argv.RelativePath, a path resolved against the file that declared it rather than the process working directory -- possible only because values carry origins.- A
whenceCLI:explain,dumpanddiscovery.
Design notes¶
- Loading is synchronous, and there is no reload. Configuration is read once
before the application runs, where there is no event loop for an
awaitto yield to. Reload was cut with it: a poll loop means whence owning a thread or a loop and mutating a generation other code holds, which is precisely where .NET'sChangeToken, viper'sWatchConfigand koanf'sWatch()each went wrong. A process that must pick up a change callsConfig.load(...)again on a schedule it owns.
Stability¶
- The public API is whatever
whence.__init__lists in__all__. From this release on it follows semantic versioning: anything else is internal, and a breaking change to the public surface requires a 2.0.0.