nested-config 2.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. nested_config-2.1.3/.gitignore +5 -0
  2. nested_config-2.1.3/.gitlab-ci.yml +77 -0
  3. nested_config-2.1.3/CHANGELOG.md +102 -0
  4. nested_config-2.1.3/LICENSE +21 -0
  5. nested_config-2.1.3/PKG-INFO +290 -0
  6. nested_config-2.1.3/README.md +258 -0
  7. nested_config-2.1.3/dev/.gitignore +2 -0
  8. nested_config-2.1.3/dev/build_and_publish.sh +33 -0
  9. nested_config-2.1.3/dev/mypy.sh +15 -0
  10. nested_config-2.1.3/dev/ruff.sh +8 -0
  11. nested_config-2.1.3/dev/run_tests.sh +43 -0
  12. nested_config-2.1.3/dev/test_setup.sh +36 -0
  13. nested_config-2.1.3/dev/test_vers.sh +3 -0
  14. nested_config-2.1.3/poetry.lock +662 -0
  15. nested_config-2.1.3/pyproject.toml +67 -0
  16. nested_config-2.1.3/src/nested_config/__init__.py +21 -0
  17. nested_config-2.1.3/src/nested_config/_pydantic.py +192 -0
  18. nested_config-2.1.3/src/nested_config/_types.py +19 -0
  19. nested_config-2.1.3/src/nested_config/expand.py +220 -0
  20. nested_config-2.1.3/src/nested_config/loaders.py +99 -0
  21. nested_config-2.1.3/src/nested_config/py.typed +0 -0
  22. nested_config-2.1.3/src/nested_config/version.py +10 -0
  23. nested_config-2.1.3/tests/test_future_annotations.py +64 -0
  24. nested_config-2.1.3/tests/test_nc_BaseModel.py +23 -0
  25. nested_config-2.1.3/tests/test_pydantic_purepath.py +68 -0
  26. nested_config-2.1.3/tests/test_simple_files.py +23 -0
  27. nested_config-2.1.3/tests/test_sub_model.py +132 -0
  28. nested_config-2.1.3/tests/toml_files/garage.toml +2 -0
  29. nested_config-2.1.3/tests/toml_files/house.toml +2 -0
  30. nested_config-2.1.3/tests/toml_files/house_bad_dimpath.toml +2 -0
  31. nested_config-2.1.3/tests/toml_files/house_dictdim.toml +4 -0
  32. nested_config-2.1.3/tests/toml_files/house_listdim.toml +2 -0
  33. nested_config-2.1.3/tests/toml_files/house_with_garage.toml +3 -0
  34. nested_config-2.1.3/tests/toml_files/neighborhood.toml +20 -0
  35. nested_config-2.1.3/tests/toml_files/simple_house.toml +3 -0
  36. nested_config-2.1.3/tests/toml_files/subdir/garage_dimensions.toml +3 -0
  37. nested_config-2.1.3/tests/toml_files/subdir/house_dimensions.toml +3 -0
  38. nested_config-2.1.3/tests/yaml_files/garage.yaml +2 -0
  39. nested_config-2.1.3/tests/yaml_files/house.yaml +2 -0
  40. nested_config-2.1.3/tests/yaml_files/house_bad_dimpath.yaml +2 -0
  41. nested_config-2.1.3/tests/yaml_files/house_dictdim.yaml +4 -0
  42. nested_config-2.1.3/tests/yaml_files/house_listdim.yaml +4 -0
  43. nested_config-2.1.3/tests/yaml_files/house_with_garage.yaml +3 -0
  44. nested_config-2.1.3/tests/yaml_files/simple_house.yaml +3 -0
  45. nested_config-2.1.3/tests/yaml_files/subdir/garage_dimensions.yaml +3 -0
  46. nested_config-2.1.3/tests/yaml_files/subdir/house_dimensions.yaml +3 -0
  47. nested_config-2.1.3/uv.lock +717 -0
@@ -0,0 +1,5 @@
1
+ .venv
2
+ dist
3
+ __pycache__
4
+ test_envs
5
+ .env
@@ -0,0 +1,77 @@
1
+ # This file is a template, and might need editing before it works on your project.
2
+ # This is a sample GitLab CI/CD configuration file that should run without any modifications.
3
+ # It demonstrates a basic 3 stage CI/CD pipeline. Instead of real tests or scripts,
4
+ # it uses echo commands to simulate the pipeline execution.
5
+ #
6
+ # A pipeline is composed of independent jobs that run scripts, grouped into stages.
7
+ # Stages run in sequential order, but jobs within stages run in parallel.
8
+ #
9
+ # For more information, see: https://docs.gitlab.com/ee/ci/yaml/index.html#stages
10
+ #
11
+ # You can copy and paste this template into a new `.gitlab-ci.yml` file.
12
+ # You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
13
+ #
14
+ # To contribute improvements to CI/CD templates, please follow the Development guide at:
15
+ # https://docs.gitlab.com/ee/development/cicd/templates.html
16
+ # This specific template is located at:
17
+ # https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml
18
+
19
+ variables:
20
+ UV_VERSION: 0.5.20
21
+ BASE_LAYER: bookworm-slim
22
+ UV_RUN_NS: uv run --no-sync
23
+
24
+
25
+ stages:
26
+ - test
27
+
28
+ default:
29
+ image: ghcr.io/astral-sh/uv:$UV_VERSION-python3.12-$BASE_LAYER
30
+
31
+ before_script:
32
+ - echo "UV_RUN_NS means '$UV_RUN_NS'"
33
+ - uv venv
34
+ - uv sync --all-extras
35
+
36
+
37
+ pytest_38_oldest_pyd18:
38
+ stage: test
39
+ image: ghcr.io/astral-sh/uv:$UV_VERSION-python3.8-$BASE_LAYER
40
+ script:
41
+ # backtrack to all older versions
42
+ - uv pip install typing_extensions==4.6 pydantic==1.8 tomli==2.0.0 pyyaml==5.1
43
+ - $UV_RUN_NS mypy --always-true PYDANTIC_1 ./
44
+ - $UV_RUN_NS pytest
45
+
46
+
47
+ pytest_38_all_latest:
48
+ stage: test
49
+ image: ghcr.io/astral-sh/uv:$UV_VERSION-python3.8-$BASE_LAYER
50
+ script:
51
+ - $UV_RUN_NS mypy --always-false PYDANTIC_1 ./
52
+ - $UV_RUN_NS pytest
53
+
54
+
55
+ pytest_312_pyd18:
56
+ stage: test
57
+ script:
58
+ # backtrack to older pydantic
59
+ - uv pip install pydantic==1.8
60
+ - $UV_RUN_NS mypy --always-true PYDANTIC_1 ./
61
+ - $UV_RUN_NS pytest
62
+
63
+
64
+ pytest_312_pyd110:
65
+ stage: test
66
+ script:
67
+ # backtrack to older pydantic
68
+ - uv pip install pydantic==1.10
69
+ - $UV_RUN_NS mypy --always-true PYDANTIC_1 ./
70
+ - $UV_RUN_NS pytest
71
+
72
+
73
+ pytest_312_all_latest:
74
+ stage: test
75
+ script:
76
+ - $UV_RUN_NS mypy --always-false PYDANTIC_1 ./
77
+ - $UV_RUN_NS pytest
@@ -0,0 +1,102 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [2.1.3] - 2025-01-16
11
+
12
+ - README updated.
13
+ - Switch from poetry/poetry-core to uv/hatchling, including in CI/CI.
14
+ - Replace `setuptools` dependency with `packaging`, since we're using it to get the
15
+ vendored `packaging` anyway.
16
+
17
+ ## [2.1.2] - 2024-04-19
18
+
19
+ - Fixed problem where `expand_config` didn't work with PEP 563 stringized annotations. Now
20
+ using `typing.get_type_hints` rather than directly querying `__annotations__`.
21
+ - Added test with `from __future__ import annotations`
22
+
23
+ ## [2.1.1] - 2024-04-19
24
+
25
+ - Export ConfigExpansionError in `__init__.py`
26
+ - Fix/update docstrings
27
+
28
+ ## [2.1.0] - 2024-04-18
29
+
30
+ ### Added
31
+
32
+ - `nested_config.expand_config` - Recursively read in any config file(s) into a dict based
33
+ on model class(es). This is now the primary functionality, superseeding
34
+ `validate_config`, which will be deprecated.
35
+
36
+ ### Changed
37
+
38
+ - Pydantic is now an extra (optional) dependency, only needed to use the below [deprecated
39
+ syntax](#2.1.0-deprecated). All Pydantic stuff has been merged into a single module and
40
+ emits deprecation warnings when used.
41
+ - Improved deb build and test scripts
42
+
43
+ ### Deprecated <a name="2.1.0-deprecated"></a>
44
+
45
+ - Pydantic PurePath validator and JSON encoder -- Doesn't need to be part of this project
46
+ and not needed in Pydantic 2+
47
+ - Pydantic validation integration -- This project started out as being specifically for
48
+ working with Pydantic models and was tightly integrated with Pydantic, but that is no
49
+ longer necessary. Use with Pydantic or attrs or whatever is better left to the user.
50
+
51
+ ## [2.0.3] - 2024-04-15
52
+
53
+ - Fix typing issue regression for Pydantic < 2.0 introduced in last release
54
+ - Move package to `src` directory
55
+
56
+ ## [2.0.2] - 2024-04-12
57
+
58
+ - Generalize handling of lists and dicts such that if the source config value and the
59
+ model annotation are both lists, recursively evaluate each item. This addresses the
60
+ situation where there may be a dict in the source config that corresponds to a Pydantic
61
+ model and that dict contains paths to other configs.
62
+
63
+ ## [2.0.1] - 2024-04-10
64
+
65
+ - Make dependency specifications more generous
66
+ - Use `yaml.safe_load`
67
+ - Test minimum dependency versions in CI
68
+
69
+ ## [2.0.0] - 2024-04-09
70
+
71
+ ### Changed
72
+
73
+ - Project renamed from **pydantic-plus** to **nested-config**
74
+
75
+ ### Added
76
+
77
+ - Can find paths to other config files and parse them using their respective Pydantic
78
+ models using `validate_config` or `BaseModel` (this is the main functionality now).
79
+ - Pydantic 2.0 compatibility.
80
+ - Can validate any config file. TOML and JSON built in, YAML optional, others can be
81
+ added.
82
+ - Validators for `PurePath` and `PureWindowsPath`
83
+ - Simplify JSON encoder specification to work for all `PurePaths`
84
+ - pytest and mypy checks, checked with GitLab CI/CD
85
+
86
+ ## [1.1.3] - 2021-07-30
87
+
88
+ - Add README
89
+ - Simplify PurePosixPath validator
90
+ - Export `TomlParsingError` from rtoml for downstream exception handling (without needing to explicitly
91
+ import rtoml).
92
+
93
+ [Unreleased]: https://gitlab.com/osu-nrsg/nested-config/-/compare/v2.1.3...master
94
+ [2.1.3]: https://gitlab.com/osu-nrsg/nested-config/-/compare/v2.1.1...v2.1.3
95
+ [2.1.2]: https://gitlab.com/osu-nrsg/nested-config/-/compare/v2.1.1...v2.1.2
96
+ [2.1.1]: https://gitlab.com/osu-nrsg/nested-config/-/compare/v2.1.0...v2.1.1
97
+ [2.1.0]: https://gitlab.com/osu-nrsg/nested-config/-/compare/v2.0.3...v2.1.0
98
+ [2.0.3]: https://gitlab.com/osu-nrsg/nested-config/-/compare/v2.0.2...v2.0.3
99
+ [2.0.2]: https://gitlab.com/osu-nrsg/nested-config/-/compare/v2.0.1...v2.0.2
100
+ [2.0.1]: https://gitlab.com/osu-nrsg/nested-config/-/compare/v2.0.0...v2.0.1
101
+ [2.0.0]: https://gitlab.com/osu-nrsg/nested-config/-/compare/v1.1.3...v2.0.0
102
+ [1.1.3]: https://gitlab.com/osu-nrsg/nested-config/-/tags/v1.1.3
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Randall Pittman, Oregon State University
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,290 @@
1
+ Metadata-Version: 2.4
2
+ Name: nested-config
3
+ Version: 2.1.3
4
+ Summary: Parse configuration files that include paths to other config files into a single configuration object
5
+ Project-URL: Repository, https://gitlab.com/osu-nrsg/nested-config
6
+ Project-URL: Issues, https://gitlab.com/osu-nrsg/nested-config/-/issues
7
+ Project-URL: Changelog, https://gitlab.com/osu-nrsg/nested-config/-/blob/master/CHANGELOG.md
8
+ Project-URL: GitHub Mirror, https://github.com/RandallPittmanOrSt/nested-config
9
+ Author-email: Randall Pittman <pittmara@oregonstate.edu>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: config,configuration files
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Requires-Python: >=3.8
22
+ Requires-Dist: packaging>=24.2
23
+ Requires-Dist: pydantic<3.0.0,>=1.8
24
+ Requires-Dist: single-version>=1.6.0
25
+ Requires-Dist: tomli>=2.0.0; python_version < '3.11'
26
+ Requires-Dist: typing-extensions>=4.6.0
27
+ Provides-Extra: pydantic
28
+ Requires-Dist: pydantic>=1.8; extra == 'pydantic'
29
+ Provides-Extra: pyyaml
30
+ Requires-Dist: pyyaml>=5.1.0; extra == 'pyyaml'
31
+ Description-Content-Type: text/markdown
32
+
33
+ # nested-config <!-- omit in toc -->
34
+
35
+ [![PyPI package](https://img.shields.io/pypi/v/nested-config.svg)](http://python.org/pypi/nested-config)&nbsp;&nbsp;
36
+ [GitLab repository](https://gitlab.com/osu-nrsg/nested-config)&nbsp;&nbsp;
37
+ [GitHub mirror](https://github.com/RandallPittmanOrSt/nested-config)
38
+
39
+ <span style="font-size: larger">If you've ever wanted to have the option of replacing part
40
+ of a configuration file with a path to another configuration file that contains those
41
+ sub-parameters, then _nested-config_ might be for you.</span>
42
+
43
+ _nested-config_ allows you to parse configuration files that contain references to other
44
+ configuration files using a series of [models](#model). If a model includes a [nested
45
+ model](#nested-model) as one of its attributes and _nested-config_ finds a string value
46
+ for that parameter in the configuration file instead of an associative
47
+ array[^assoc-array], then it assumes that this string is a path to another configuration
48
+ file that should be parsed and whose contents should replace the string in the main
49
+ configuration file. If the string appears to be a relative path, it is assumed to be
50
+ relative to the path of its parent configuration file.
51
+
52
+ ## Contents
53
+
54
+ - [Contents](#contents)
55
+ - [Basic Usage](#basic-usage)
56
+ - [Nomenclature](#nomenclature)
57
+ - [loader](#loader)
58
+ - [model](#model)
59
+ - [nested model](#nested-model)
60
+ - [config dict](#config-dict)
61
+ - [API](#api)
62
+ - [`nested_config.expand_config(config_path, model, *, default_suffix = None)`](#nested_configexpand_configconfig_path-model--default_suffix--none)
63
+ - [`nested_config.config_dict_loaders`](#nested_configconfig_dict_loaders)
64
+ - [Included loaders](#included-loaders)
65
+ - [Adding loaders](#adding-loaders)
66
+ - [_Deprecated features in v2.1.0, to be removed in v3.0.0_](#deprecated-features-in-v210-to-be-removed-in-v300)
67
+ - [Pydantic 1.0/2.0 Compatibility](#pydantic-1020-compatibility)
68
+ - [Footnotes](#footnotes)
69
+
70
+ ## Basic Usage
71
+
72
+ Given the following configuration files `/tmp/house.toml` and `/tmp/tmp2/dimensions.toml`:
73
+
74
+ <figure>
75
+ <figcaption>Figure 1: /tmp/house.toml</figcaption>
76
+
77
+ ```toml
78
+ name = "my house"
79
+ dimensions = "tmp2/dimensions.toml"
80
+ ```
81
+
82
+ </figure>
83
+
84
+ <figure>
85
+ <figcaption>Figure 2: /tmp/tmp2/dimensions.toml</figcaption>
86
+
87
+ ```toml
88
+ length = 10
89
+ width = 20
90
+ ```
91
+
92
+ </figure>
93
+
94
+ You can expand these into a single dict with the following:
95
+
96
+ <figure>
97
+ <figcaption>Figure 3: Expand /tmp/house.toml</figcaption>
98
+
99
+ ```python
100
+ import nested_config
101
+
102
+ class Dimensions:
103
+ length: int
104
+ width: int
105
+
106
+
107
+ class House:
108
+ name: str
109
+ dimensions: Dimensions
110
+
111
+
112
+ house_dict = nested_config.expand_config("/tmp/house.toml", House)
113
+ print(house_dict)
114
+ # {'name': 'my house', 'dimensions': {'length': 10, 'width': 20}}
115
+ ```
116
+
117
+ Note that in `/tmp/house.toml`, `dimensions` is not a mapping but is a path to another
118
+ toml file at a path relative to `house.toml`.
119
+
120
+ See [tests](https://gitlab.com/osu-nrsg/nested-config/-/tree/master/tests) for more
121
+ detailed use-cases, such as where the root model contains lists or dicts of other models
122
+ and when those may be included in the root config file or specified as paths to sub-config
123
+ files.
124
+
125
+ ## Nomenclature
126
+
127
+ ### loader
128
+
129
+ A _loader_ is a function that reads a config file and returns a `dict` containing the
130
+ key-value pairs from the file. _nested-config_ includes loaders for JSON, TOML, and (if
131
+ PyYAML is installed) YAML. For example, the JSON loader looks like this:
132
+
133
+ ```python
134
+ import json
135
+
136
+ def json_load(path):
137
+ with open(path, "rb") as fobj:
138
+ return json.load(fobj)
139
+ ```
140
+
141
+ ### model
142
+
143
+ _nested-config_ uses the term _model_ to refer to a class definition that includes
144
+ annotated attributes. For example, this model, `Dimensions`, includes three attributes,
145
+ each of float type, `x`, `y`, and `z`:
146
+
147
+ ```python
148
+ class Dimensions:
149
+ x: float
150
+ y: float
151
+ z: float
152
+ ```
153
+
154
+ A model can be decorated as a [dataclass][dataclasses] or using [`attrs.define`][attrs] or
155
+ can subclass [`pydantic.BaseModel`][pydantic] to provide some method for instantiating an
156
+ object instance of the model but they aren't necessary to use _nested-config_.
157
+
158
+ The only criterion for a type to be a model is that is has a `__dict__` attribute that
159
+ includes an `__annotations__` member. _Note: This does **not** mean that **instances** of
160
+ the model must have a `__dict__` attribute. For example, instances of classes with
161
+ `__slots__` and `NamedTuple` instances may not have a `__dict__` attribute._
162
+
163
+ ### nested model
164
+
165
+ A _nested model_ is a model that is included within another model as one of its class
166
+ attributes. For example, the below model `House` includes an `name` of string type, and an
167
+ attribute `dimensions` of `Dimensions` type (defined above). Since `Dimensions` is a
168
+ _model_ type, this is an example of a _nested model_.
169
+
170
+ ```python
171
+ class House:
172
+ name: str
173
+ dimensions: Dimensions
174
+ ```
175
+
176
+ ### config dict
177
+
178
+ A _config dict_ is simply a `dict` with string keys such as may be obtained by reading in
179
+ configuration text. For example reading in a string of TOML text with `tomllib.loads`
180
+ returns a _config dict_.
181
+
182
+ ```python
183
+ import tomllib
184
+
185
+ config = "x = 2\ny = 3"
186
+ print(tomllib.loads(config))
187
+ # {'x': 2, 'y': 3}
188
+ ```
189
+
190
+ ## API
191
+
192
+ ### `nested_config.expand_config(config_path, model, *, default_suffix = None)`
193
+
194
+ This function first loads the config file at `config_path` into a [config
195
+ dict](#config-dict) using the appropriate [loader](#loader). It then uses the attribute
196
+ annotations of [`model`](#model) and/or any [nested models](#nested-model) within `model`
197
+ to see if any of the string values in the configuration file correspond to a nested model.
198
+ For each such case, the string is assumed to be a path and is loaded into another config
199
+ dict which replaces the string value in the parent config dict. This continues until all
200
+ paths are converted and then the fully-expanded config dict is returned.
201
+
202
+ Note that all non-absolute string paths are assumed to be relative to the path of their
203
+ parent config file.
204
+
205
+ The loader for a given config file is determined by file extension (AKA suffix). If
206
+ `default_suffix` is specified, any config file with an unknown suffix or no suffix will be
207
+ assumed to be of that type, e.g. `".toml"`. (Otherwise this is an error.) It is possible
208
+ for one config file to include a path to a config file of a different format, so long as
209
+ each file has the appropriate suffix and there is a loader for that suffix.
210
+
211
+ ### `nested_config.config_dict_loaders`
212
+
213
+ `config_dict_loaders` is a `dict` that maps file suffixes to [loaders](#loader).
214
+
215
+ #### Included loaders
216
+
217
+ _nested-config_ automatically loads the following files based on extension:
218
+
219
+ | Format | Extensions(s) | Library |
220
+ | ------ | ------------- | ------------------------------------------ |
221
+ | JSON | .json | `json` (stdlib) |
222
+ | TOML | .toml | `tomllib` (Python 3.11+ stdlib) or `tomli` |
223
+ | YAML | .yaml, .yml | `pyyaml` (extra dependency[^yaml-extra]) |
224
+
225
+ #### Adding loaders
226
+
227
+ To add a loader for another file extension, simply update `config_dict_loaders`:
228
+
229
+ ```python
230
+ import nested_config
231
+ from nested_config import ConfigDict # alias for dict[str, Any]
232
+
233
+ def dummy_loader(config_path: Path | str) -> ConfigDict:
234
+ return {"a": 1, "b": 2}
235
+
236
+ nested_config.config_dict_loaders[".dmy"] = dummy_loader
237
+
238
+ # or add another extension for an existing loader
239
+ nested_config.config_dict_loaders[".jsn"] = nested_config.config_dict_loaders[".json"]
240
+
241
+ # or use a different library to replace an existing loader
242
+ import rtoml
243
+
244
+ def rtoml_load(path) -> ConfigDict:
245
+ with open(path, "rb") as fobj:
246
+ return rtoml.load(fobj)
247
+
248
+ nested_config.config_dict_loaders[".toml"] = rtoml_load
249
+ ```
250
+
251
+ ### _Deprecated features in v2.1.0, to be removed in v3.0.0_
252
+
253
+ The following functionality is available only if Pydantic is installed:
254
+
255
+ - `nested_config.validate_config()` expands a configuration file according to a Pydantic
256
+ model and then validates the config dictionary into an instance of the Pydantic model.
257
+ - `nested_config.BaseModel` can be used as a replacement for `pydantic.BaseModel` to
258
+ include a `from_config()` classmethod on all models that uses
259
+ `nested_config.validate_config()` to create an instance of the model.
260
+ - By importing `nested_config`, `PurePath` validators and JSON encoders are added to
261
+ `pydantic` in Pydantic 1.8-1.10 (they are included in Pydantic 2.0+)
262
+
263
+ ## Pydantic 1.0/2.0 Compatibility
264
+
265
+ The [pydantic functionality](#deprecated-features-in-v210-to-be-removed-in-v300) in
266
+ nested-config is runtime compatible with Pydantic 1.8+ and Pydantic 2.0.
267
+
268
+ The follow table gives info on how to configure the [mypy](https://www.mypy-lang.org/) and
269
+ [Pyright](https://microsoft.github.io/pyright) type checkers to properly work, depending
270
+ on the version of Pydantic you are using.
271
+
272
+ | Pydantic Version | [mypy config][1] | mypy cli | [Pyright config][2] |
273
+ |------------------|-----------------------------|-----------------------------|---------------------------------------------|
274
+ | 2.0+ | `always_false = PYDANTIC_1` | `--always-false PYDANTIC_1` | `defineConstant = { "PYDANTIC_1" = false }` |
275
+ | 1.8-1.10 | `always_true = PYDANTIC_1` | `--always-true PYDANTIC_1` | `defineConstant = { "PYDANTIC_1" = true }` |
276
+
277
+ ## Footnotes
278
+
279
+ [^yaml-extra]: Install `pyyaml` separately with `pip` or install _nested-config_ with
280
+ `pip install nested-config[yaml]`.
281
+
282
+ [^assoc-array]: Each language uses one or more names for an associative arrays. JSON calls
283
+ it an _object_, YAML calls is a _mapping_, and TOML calls is a _table_.
284
+ Any of course in Python it's a _dictionary_, or `dict`.
285
+
286
+ [1]: https://mypy.readthedocs.io/en/latest/config_file.html
287
+ [2]: https://microsoft.github.io/pyright/#/configuration
288
+ [dataclasses]: https://docs.python.org/3/library/dataclasses.html
289
+ [attrs]: https://www.attrs.org
290
+ [pydantic]: https://pydantic.dev