NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #4973 most downloaded on PyPI
Typed settings based on attrs classes
Last release 1 months ago
02 Sep 2026
Release timing varies
gaps range from 4 weeks to 9 months
Nearly every release is documented
notes for 38 of 38 stable releases
Nothing withdrawn
no release was ever pulled
6 years old
38 releases · first in 2020
One column per quarter.
✨ Add support for JSON files to the file loader
(v25-3-0)=
✨ Read CLI option help text from attribute docstrings.
✨ Read CLI option help text from attribute docstrings.
This only works for string literals defined below an attribute but not
for Sphinx style #: comments:
import typed_settings as ts
@ts.settings
class Settings:
a: int = 0
"""I am a valid help text"""
#: I will not be used as help text
b: int = 0
You can still override this via the attribute's metadata/description as described in the docs.
Inspired by David Lord.
✨ Add a DotEnvLoader which works very similarly to the EnvLoader
but uses python-dotenv to read .env files without polluting your
os.environ (see #58). Read the docs for details.
🐛 Detect if an existing Click context object is a dict or another type. Raise a helping exception if it is not a dict (#78).
(v25-2-0)=
🗑 The converter hooks to_path() and to_resolved_path() are now deprecated and replaced by [PathConverter].
os.chdir() when resolving relative paths. There
are some rare caes
where this call can fail, which will now no longer be the case. See
[#71].to_path() and to_resolved_path() are now
deprecated and replaced by PathConverter.(v25-1-0)=
💥 BREAKING: If a field of an attrs class or a Pydantic model defines an alias, use the alias instead of the original field name for loading settings.
💥 BREAKING: If a field of an attrs class or a Pydantic model
defines an alias, use the alias instead of the original field name
for loading settings. Dataclasses don't support alias, so these are
not affected. See [!56].
✨ Assert support for Python 3.14.
✨ Add support for Path subclasses (with argparse) (!55).
✨ Fix the support for Secret and recommend using it instead
of SecretStr.
✨ Add converter support for re.Pattern/re.compile().
✨ Add converter support for Literal (#68).
Caveat: When Literal is used for CLI generation, all values must be
strings.
(v25-0-0)=
💥 BREAKING: The InvalidSettingsError raised by the convert(), load(), and load_settings() functions is now an [ExceptionGroup] (but still also a subcl
💥 BREAKING: The InvalidSettingsError raised by the convert(),
load(), and load_settings() functions is now an ExceptionGroup
(but still also a subclass of TsError). For Python versions below
3.11, the 3rd party backport exceptiongroup is being used.
This allows you to dig deeper if the converter fails for strange
reasons (as in #70) (#71).
✨ Add support for typing.Mapping to converters (!48).
✨ Add support for enum.IntEnum and enum.StrEnum (#59).
In contrast to enum.Enum, they are converted by value and not by
name.
See the docs and #59 for details and an example of how to change the behavior.
🐛 Improve handling of nested options in collections (lists and dicts) and improve docs for nested settings (#67).
🐛 Improve error message when os.chdir() fails while resolving
relative paths. This error can occur if a config file is readable
but its parent directory is not (#71).
(v24-6-0)=
💥 BREAKING: Dropped support for Python 3.8. Also switch from Type[...] to type[...] style annotations (for list, tuple, dict, ...).
💥 BREAKING: Dropped support for Python 3.8. Also switch from
Type[...] to type[...] style annotations (for list, tuple,
dict, ...).
✨ Officially support Python 3.13.
🐛 Fix regression "dictionary changed size during iteration" (#60).
🐛 Fix handling of list types with Pydantic models (#61).
🐛 Fix handling default factories in dataclasses (#62).
👷 Improve pipeline performance by a factor of ~3.5 through more and better usage of uv and improved caching.
(v24-5-0)=
🗑️ Support for Python 3.8 will be dropped by the end of 2024. We will continue to provide fixes for critical bugs, though.
🗑️ Support for Python 3.8 will be dropped by the end of 2024. We will continue to provide fixes for critical bugs, though.
✨ Add reload_settings_on_invoke argument to click_options() to
allow reloading settings on each invocation. This can improve
testability of Click CLIs (#47).
🐛 Fix compatibility with cattrs 24.1. This is also the minium required version no (!40).
(v24-4-0)=
✨ Add resolve_types() function, which is an extended version of attrs.resolve_types() ([docs][docs-resolve_types], [#56]).
✨ Add resolve_types() function, which is an extended version of
attrs.resolve_types() (docs, #56).
✨ Add support for processing of list items, regardless if they are strings or nested settings classes. ([#57])
📝 Further improve the [docs about postponed annotations / forward references][information about forward references] (#56).
📦 Speed-up CI/CD pipeline and nox runs.
📦 Use Trusted Publishers for uploading to PyPI.
(v24-3-0)=
✨ Add converters for date and timedelta, e.g.:
✨ Add converters for date and timedelta, e.g.:
2025-05-04 (or 20250504 on Python ≥ 3.11) (docs)P180DT03H04M05S, PT0.5S, -P180D, PT1H30M (docs)180d03h04m05s, 0.5s, -180d, 1h30m (docs)180d,03:04:05, 0.5, -180d, 01:30:00 (docs)See: #55
🐛 typed_settings.cls_attrs.combine() now properly
populates the __annotations__ dict of the generated class. Without
that, forward references and postponed annotations (PEP 563)
wouldn't work properly (#54).
📝 Add information about forward references to the docs (#54).
📝 Update the development guide (#53).
(v24-2-0)=
✨ Allow passing a custom Jinja Environment to JinjaProcessor. This lets the library use custom Jinja functions, filters, etc. ([!32])
✨ Allow specifying an *env nested delimiter*. This is the string used for concatenating the attribute names of nested classes when creating env. var.
"_". (!31)(v24-0-1)=
🐛 Fix a bug with Pydantic SecretStr in Click options [#49].
SecretStr in Click options #49.(v24-0-0)=
✨ For Pydantic classes, read the CLI option's help from the field's *desription* if the field's metadata does not contain a help key [#45].
✨ For Pydantic classes, read the CLI option's help from the field's
desription if the field's metadata does not contain a help key
#45.
✨ Settings can now be loaded from the top level of a TOML and Python
file. This is only exposed by the loaders themselves, but not the
simple load() API, though #36.
✨ Added support for Pydantic SecretStr and SecretBytes fields in
settings #46.
🐛 The env var prefix for app names containing a - is now derived
like this: a-b => A_B_ (previously it was A-B_) !27.
(v23-1-1)=
🐛 Don't require click when typed_settings.secret() is used ([#44])
click when typed_settings.secret() is used (#44)(v23-1-0)=
💥 BREAKING: The deprecated typed_settings.attrs.hooks module has been removed.
💥 BREAKING: Dropped support for Python 3.7.
💥 BREAKING: Refactor internal handling of loaded option values.
This will affect you if you have created a custom loader or processor, or if you rely on internal functionality. Otherwise, you should be fine.
Every loader now stores some meta data with the settings it loaded. This meta data can, for example, be used to resolve relative paths in option values relative to the config file from which they were loaded.
You can re-enable the old behavior by explicitly using the converter
returned by default_converter(resolve_paths=False).
This also improves error messages for when one or more option values cannot be converted to the desired type.
💥 BREAKING: Relative paths are now always resolved relative to the source they are loaded from. This is either the parent directory of a config file or the current working directory (#30).
💥 BREAKING: The signature of argparse_utils’ make_parser()
and namespace2settings() function changed. They now return and take
the merged settings. The Signature of cli() remains unchanged.
See #41.
💥 BREAKING: The deprecated typed_settings.attrs.hooks module
has been removed.
🗑 The modules typed_settings.argparse_utils,
typed_settings.ckick_utils, and typed_settings.attrs are
deprecated and are now aliases of the renamed
typed_settings.cli_argparse, typed_settings.cli_click, and
typed_settings.cls_attrs. They will be removed in the next release.
🗑 The module typed_settings.attrs is deprecated and is now an alias
for typed_settings.cls_attrs. It will be removed in the next
release.
✨ Added support dataclasses and Pydantic models as
alternative to attrs (which is still the recommended backend).
✨ attrs is now an optional (but recommended) dependency. You can
install it with python -m pip install -U typed-settings[attrs].
✨ Added a built-in TSConverter as an alternative for cattrs
(which is still supported and recommended).
✨ cattrs is now an optional dependency. You can install it with
python -m pip install -U typed-settings[cattrs].
✨ Typed Settings now has no mandatory dependencies on Python >= 3.11.
On older versions, tomli is the only requirement. There is also an
official way to to vendor Typed Settings (i.e., to bundle it with
your application).
✨ Added a dictionary loader. This is useful for testing purposes.
✨ Added start_dir parameter to find().
✨ Officially support Python 3.12.
📝 Split guides into smaller pages
📝 Converted docs from ReST to Markdown/MyST and use [Sybil] to test all examples.
(v23-0-1)=
🐛 Fixed typing issues with Pylance/Pyright and attrs decorators (see [#40])
🗑 The next regular release (23.1.0) will introduce breaking changes to the converter API and settings dict. See [!16] for details and for feedback.
🗑 The next regular release (23.1.0) will drop support for Python 3.7.
🗑 The next regular release (23.1.0) will introduce breaking changes to the converter API and settings dict. See !16 for details and for feedback.
Your code will break when:
📦 Switch to CalVer with scheme YY.MINOR.MICRO (same as pip, attrs
and cattrs).
📦 Switch to ruff as linter.
♻️ Make dict_utils part of the public API.
♻️ Make optional imports in typed_settings more IDE friendly (see !14).
📝 Added a copy button to the examples in the docs. Prompt characters and out for doctest examples or bash are not copied, only the actual code / command.
📝 Start migration to Markdown docs with MyST-Parser.
📝 Start using Sybil for doctests and examples.
📝 Fixed spelling and grammatical mistakes.
✨ Added settings (post) processors. They allow modifying loaded settings before they are passed to your app. This allows, e.g., using settings templates/interpolation or loading secrets from external resources via helper scripts. (See #2, #19)
✨ Added a 1Password loader.
✨ Added an op:// resource handler for the new URL processor (see
#19).
✨ Optionally show env var name in the help string for Click options (see #33).
(v2-0-2)=
🐛 Fixed [#29]: Do not modify attrs metadata when creating CLI options. The metadata dict is now copied before popping items from it.
(v2-0-1)=
🐛 Fixed [#26]: Typing error with Pyright/VSCode.
💥 BREAKING: The click_utils.TypeHandler is now called cli_utils.TypeArgsMaker and has a completely different interface. If you do not explicitly use t
click_utils.TypeHandler is now called
cli_utils.TypeArgsMaker and has a completely different interface.
If you do not explicitly use this class, nothing will change for you.attrs.validators (see #17).--env VAR1=val1 --env VAR=val2).typed_settings.cli() (See
#14).SecretStr and Secret) that mask their
values when they are printed/logged.(v1-1-1)=
✨ Added support for [cattrs 22.2] which renamed the main converter classes. The older version 22.1 remains supported, too.
(v1-1-0)=
This release mainly focuses on improving the integration with [Click], especially if you want to use command groups or write extensible applications l
This release mainly focuses on improving the integration with Click, especially if you want to use command groups or write extensible applications like Pytest.
💥 BREAKING: Settings values that are dictionaries are no longer merged when they are provided by different settings sources. They override each other now as other scalar and container types do.
♻️ Replace toml with tomli for Python <= 3.10.
♻️ Use tomllib on Python 3.11 and do not depend on tomli.
♻️ Require cattrs >= 22.1.0.
✅ Increase test coverage to 100% (and enforce it).
📝 Impove and extend the docs' examples section.
📝 Extend the guides and split them into multiple pages.
✨ Support Python 3.11
✨ Improve Click option generation:
dict options to click_options() (e.g., --env PWD_FILE=/pwd --env DEBUG=1) (See #5).combine() function to merge multiple settings (e.g., from
plug-ins) with a base class.(v1-0-1)=
🗑 Deprecate the bundled attrs validators. They are now part of attrs.validators.
attrs validators. They are now part of
attrs.validators.🐛 Fixed #16: Support new (c)attrs namespaces. attrs 21.3 and
cattrs 1.10 are now required.
🐛 Bug fix
(v1-0-0)=
💥 BREAKING: Change Loader and FileFormat protocols to use __call__(). This allows "normal" functions to be used as loaders, too.
💥 BREAKING: Change Loader and FileFormat protocols to use
__call__(). This allows "normal" functions to be used as loaders,
too.
💥 BREAKING: Pass the settings class to loaders (in addition to
the list of OptionInfos).
💥 BREAKING: Enums are only converted from member name, not by value.
♻️ The attrs auto-convert hook now uses a Cattrs converter instead of
custom conversion logic.
✅ Increase test coverage to 100% again.
✅ Migrate to pytest7.
📝 Write "Guides" section of the docs.
📝 Update "Getting Started" section of the docs.
📝 Update "Why" section of the docs.
📝 Try MyST (Markdown) but switch back to ReST (only for now, MyST looks very promising).
✨ Add evolve() function for recursively updading settings.
✨ Add InstanceLoader which loads settings from an existing instance
of the settings class.
✨ click_options() accepts just an appname and then works similar to
load(). The old behavior (which is comparable to load_settings()
still exists.
✨ The strlisthook with : as separator is now activated by
default. It helps loading lists from environment variables.
🐛 Fixed #10: Fix handling tuples and sets in strlist hook.
🐛 Fixed #11: Properly convert loaded values to click default values.
(v0-11-1)=
🐛 Allow using instances of nested attrs/settings classes as default values for options again. Fixes a regression introduced by switching to cattrs.
(v0-11-0)=
🗑 The attrs specific converters and hooks are deprecated and will be removed in a future release.
💥 BREAKING: Use cattrs instead of attrs auto-convert hooks. This makes converters more robust and easier to extend.
💥 BREAKING: The signature of load_settings() has changed.
load() is now the pre-configured convenience loader while
load_settings() allows full customization of all settings loaders
and value converters.
✨ Loaders can now be extended by users. Typed settings bundles a file loader and an environment loader. New loaders must implement the Loader protocol.
✨ The file loader can be extended to support additional file formats. File loaders must implement the FileFormat protocol.
✨ Add experimental support for Python config files.
✨ Environment variables can now contain list values. Theses lists
can eitehr be JSON or simple {separator} spearted lists (the
separator can be configured, e.g., : or ,).
(v0-10-0)=
🗑 The signature of load_settings() will change in a backwars incompatible way in the next release.
load_settings() will change in a backwars
incompatible way in the next release.💥 BREAKING: Settings classes are now mutable by default. This
makes especially testing and monkeypatching a lot easier. Since
settings classes are normal attrs classes, you can make your
settings immutable again by passing frozen=True to the class
decorator.
🐍 Add support for Python 3.10.
🏗 Add support for click 8.
✨ load() is now the new main function for loading settings. It has
the same signature as load_settings() (See: #8).
✨ find() searches for a given config file from the current working
dir upwards.
✨ The to_bool() converter converts bools from addional values.
Please use load() instead (See: #8).
(v0-9-2)=
🐛 Fixed [#3]: Only replace - with _ for sections and option names, but not for dict keys.
🐛 Fixed #3: Only replace - with _ for sections and option
names, but not for dict keys.
🐛 Remove debug printa.
(v0-9-1)=
🐛 Fixed [#6]: Properly handle attrs default factories in options.
💥 BREAKING: A ValueError is now raised when a config file contains invalid options.
💥 BREAKING: A ValueError is now raised when a config file
contains invalid options.
💥 BREAKING: Click options without a default (or loaded value) are
now marked as required=True.
📝 Improve Why Typed Settings docs.
📝 Improve docs for attrs converters/validators/hooks.
✅ Increase test coverage to 100%.
✨ Click options support more types (datetimes, lists, tuples, ...)
multiple=Truenargs=XClick types can also be exteded by users now.
✨ Options can specify a help string for Click options via the
click_help parameter.
✨ Improve handling of container types (like set) in the attrs
auto-converter.
(v0-8)=
✨ Depend on attrs 20.3 and implement auto-converters for attribute values.
✨ Depend on attrs 20.3 and implement auto-converters for attribute values.
✨ Properly convert env. vars. with "bool strings" to real booleans.
📝 Use Furo as documentation theme
📝 Update docs:
(v0-7)=
🐛 Fixed loaded settings not being used as option defaults with click.
(v0-6)=
✨ Add pass_settings decorator that pass settings to nested Click commands.
pass_settings decorator that pass settings to nested Click
commands.(v0-5)=
✨ Click options for basic data types (bool, int, str, Enum) can be generated now.
bool, int, str, Enum)
can be generated now.(v0-4)=
💥 BREAKING: Flip *appname* and *settings_cls* args of load_settings().
💥 BREAKING: Flip appname and settings_cls args of
load_settings().
♻️ Refactor internals to improve extensibility.
✨ Added convenience wrappers for attrs:
settings is an alias for attr.frozenoption is an alias for attr.fieldsecret is an alias for attr.field and masks the options's value
with *** when the settings classes is printed.✨ Added update_settings() method which is useful for overriding
settings in tests.
✨ Mandatory config files can be prefixed with !
(e.g., !./credentials.toml). An error is raised if a mandatory
config file does not exist.
👷 Add pre-commit hooks
(v0-3)=
👷 Added code linting and improve CI
(v0-2)=
✨ Make sure env vars can be read
load_settings()(v0-1)=
- 🎉 Initial PoC (legend)=
Your coding agent can read these notes before it upgrades. Set up the MCP server →