configaroo 0.2.4__tar.gz → 0.3.0__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.
- {configaroo-0.2.4/src/configaroo.egg-info → configaroo-0.3.0}/PKG-INFO +1 -1
- {configaroo-0.2.4 → configaroo-0.3.0}/pyproject.toml +5 -6
- {configaroo-0.2.4 → configaroo-0.3.0}/src/configaroo/__init__.py +1 -1
- {configaroo-0.2.4 → configaroo-0.3.0}/src/configaroo/configuration.py +20 -6
- {configaroo-0.2.4 → configaroo-0.3.0/src/configaroo.egg-info}/PKG-INFO +1 -1
- {configaroo-0.2.4 → configaroo-0.3.0}/tests/test_configuration.py +7 -1
- {configaroo-0.2.4 → configaroo-0.3.0}/tests/test_environment.py +15 -1
- {configaroo-0.2.4 → configaroo-0.3.0}/LICENSE +0 -0
- {configaroo-0.2.4 → configaroo-0.3.0}/README.md +0 -0
- {configaroo-0.2.4 → configaroo-0.3.0}/setup.cfg +0 -0
- {configaroo-0.2.4 → configaroo-0.3.0}/src/configaroo/exceptions.py +0 -0
- {configaroo-0.2.4 → configaroo-0.3.0}/src/configaroo/loaders/__init__.py +0 -0
- {configaroo-0.2.4 → configaroo-0.3.0}/src/configaroo/loaders/json.py +0 -0
- {configaroo-0.2.4 → configaroo-0.3.0}/src/configaroo/loaders/toml.py +0 -0
- {configaroo-0.2.4 → configaroo-0.3.0}/src/configaroo/py.typed +0 -0
- {configaroo-0.2.4 → configaroo-0.3.0}/src/configaroo.egg-info/SOURCES.txt +0 -0
- {configaroo-0.2.4 → configaroo-0.3.0}/src/configaroo.egg-info/dependency_links.txt +0 -0
- {configaroo-0.2.4 → configaroo-0.3.0}/src/configaroo.egg-info/requires.txt +0 -0
- {configaroo-0.2.4 → configaroo-0.3.0}/src/configaroo.egg-info/top_level.txt +0 -0
- {configaroo-0.2.4 → configaroo-0.3.0}/tests/test_dynamic.py +0 -0
- {configaroo-0.2.4 → configaroo-0.3.0}/tests/test_json.py +0 -0
- {configaroo-0.2.4 → configaroo-0.3.0}/tests/test_loaders.py +0 -0
- {configaroo-0.2.4 → configaroo-0.3.0}/tests/test_print.py +0 -0
- {configaroo-0.2.4 → configaroo-0.3.0}/tests/test_toml.py +0 -0
- {configaroo-0.2.4 → configaroo-0.3.0}/tests/test_validation.py +0 -0
@@ -36,16 +36,15 @@ changelog = "https://github.com/gahjelle/configaroo/releases"
|
|
36
36
|
|
37
37
|
[dependency-groups]
|
38
38
|
build = ["build>=1.2.2.post1", "twine>=6.1.0"]
|
39
|
+
ci = ["mypy>=1.17.1", "pytest>=8.4.1", "rich>=14.1.0", "ruff>=0.12.7", "tomli-w>=1.2.0"]
|
39
40
|
dev = [
|
41
|
+
{ include-group = "ci" },
|
42
|
+
{ include-group = "test" },
|
40
43
|
"bumpver>=2024.1130",
|
41
44
|
"ipython>=8.36.0",
|
42
|
-
"mypy>=1.17.1",
|
43
45
|
"pre-commit>=4.2.0",
|
44
|
-
"pytest>=8.3.5",
|
45
|
-
"rich>=14.1.0",
|
46
|
-
"ruff>=0.11.11",
|
47
|
-
"tomli-w>=1.2.0",
|
48
46
|
]
|
47
|
+
test = ["pytest>=8.4.1", "pytest-cov>=6.2.1", "tomli-w>=1.2.0"]
|
49
48
|
|
50
49
|
|
51
50
|
[tool.setuptools.dynamic]
|
@@ -80,7 +79,7 @@ python_version = "3.11"
|
|
80
79
|
strict = true
|
81
80
|
|
82
81
|
[tool.bumpver]
|
83
|
-
current_version = "v0.
|
82
|
+
current_version = "v0.3.0"
|
84
83
|
version_pattern = "vMAJOR.MINOR.PATCH"
|
85
84
|
commit_message = "bump version {old_version} -> {new_version}"
|
86
85
|
tag_message = "{new_version}"
|
@@ -112,8 +112,22 @@ class Configuration(UserDict[str, Any]):
|
|
112
112
|
cls = type(self)
|
113
113
|
return self | {prefix: cls(self.setdefault(prefix, {})).add(rest, value)}
|
114
114
|
|
115
|
-
def add_envs(self, envs: dict[str, str], prefix: str = "") -> Self:
|
116
|
-
"""Add environment variables to configuration.
|
115
|
+
def add_envs(self, envs: dict[str, str] | None = None, prefix: str = "") -> Self:
|
116
|
+
"""Add environment variables to configuration.
|
117
|
+
|
118
|
+
If you don't specify which environment variables to read, you'll
|
119
|
+
automatically add any that matches a top-level value of the
|
120
|
+
configuration.
|
121
|
+
"""
|
122
|
+
if envs is None:
|
123
|
+
# Automatically add top-level configuration items
|
124
|
+
envs = {
|
125
|
+
re.sub(r"\W", "_", key).upper(): key
|
126
|
+
for key, value in self.data.items()
|
127
|
+
if isinstance(value, str | int | float)
|
128
|
+
}
|
129
|
+
|
130
|
+
# Read environment variables
|
117
131
|
for env, key in envs.items():
|
118
132
|
env_key = f"{prefix}{env}"
|
119
133
|
if env_value := os.getenv(env_key):
|
@@ -129,7 +143,7 @@ class Configuration(UserDict[str, Any]):
|
|
129
143
|
cls = type(self)
|
130
144
|
variables = (
|
131
145
|
(self.to_flat_dict() if _include_self else {})
|
132
|
-
| {"project_path":
|
146
|
+
| {"project_path": find_pyproject_toml()}
|
133
147
|
| ({} if extra is None else extra)
|
134
148
|
)
|
135
149
|
parsed = cls(
|
@@ -196,7 +210,7 @@ def print_configuration(config: Configuration | BaseModel, indent: int = 4) -> N
|
|
196
210
|
)
|
197
211
|
|
198
212
|
|
199
|
-
def _get_rich_print() -> Callable[[str], None]:
|
213
|
+
def _get_rich_print() -> Callable[[str], None]: # pragma: no cover
|
200
214
|
"""Initialize a Rich console if Rich is installed, otherwise use built-in print."""
|
201
215
|
try:
|
202
216
|
from rich.console import Console # noqa: PLC0415
|
@@ -228,7 +242,7 @@ def _print_dict_as_tree(
|
|
228
242
|
_print(" " * current_indent + f"- {key}: {value!r}")
|
229
243
|
|
230
244
|
|
231
|
-
def
|
245
|
+
def find_pyproject_toml(
|
232
246
|
path: Path | None = None, _file_name: str = "pyproject.toml"
|
233
247
|
) -> Path:
|
234
248
|
"""Find a directory that contains a pyproject.toml file.
|
@@ -241,7 +255,7 @@ def _find_pyproject_toml(
|
|
241
255
|
if (path / _file_name).exists() or path == path.parent:
|
242
256
|
return path.resolve()
|
243
257
|
|
244
|
-
return
|
258
|
+
return find_pyproject_toml(path.parent, _file_name=_file_name)
|
245
259
|
|
246
260
|
|
247
261
|
def _get_foreign_path() -> Path:
|
@@ -64,6 +64,12 @@ def test_get_nested_values(config: Configuration) -> None:
|
|
64
64
|
assert config.get("with_dot.org.num") == 1234
|
65
65
|
|
66
66
|
|
67
|
+
def test_get_with_default(config: Configuration) -> None:
|
68
|
+
"""Test that .get() falls back on default if the key doesn't exist."""
|
69
|
+
assert config.get("word", default="kangaroo") == "platypus"
|
70
|
+
assert config.get("another word", default="kangaroo") == "kangaroo"
|
71
|
+
|
72
|
+
|
67
73
|
def test_update_preserves_type(config: Configuration) -> None:
|
68
74
|
"""Test that an update operation gives a Configuration."""
|
69
75
|
assert isinstance(config | {"new": 1}, Configuration)
|
@@ -122,7 +128,7 @@ def test_contains_with_dotted_key(config: Configuration) -> None:
|
|
122
128
|
|
123
129
|
def test_find_pyproject_toml() -> None:
|
124
130
|
"""Test that the pyproject.toml file can be located."""
|
125
|
-
assert configuration.
|
131
|
+
assert configuration.find_pyproject_toml() == Path(__file__).parent.parent
|
126
132
|
|
127
133
|
|
128
134
|
def test_find_foreign_caller() -> None:
|
@@ -45,7 +45,7 @@ def test_missing_env_ok_if_optional(config: Configuration) -> None:
|
|
45
45
|
|
46
46
|
|
47
47
|
def test_env_prefix(config: Configuration, monkeypatch: pytest.MonkeyPatch) -> None:
|
48
|
-
"""Test that a common prefix can be used for
|
48
|
+
"""Test that a common prefix can be used for environment variables."""
|
49
49
|
monkeypatch.setenv("EXAMPLE_NUMBER", "14")
|
50
50
|
monkeypatch.setenv("EXAMPLE_WORD", "platypus")
|
51
51
|
config_w_env = config.add_envs(
|
@@ -53,3 +53,17 @@ def test_env_prefix(config: Configuration, monkeypatch: pytest.MonkeyPatch) -> N
|
|
53
53
|
)
|
54
54
|
assert config_w_env.number == "14"
|
55
55
|
assert config_w_env.nested.word == "platypus"
|
56
|
+
|
57
|
+
|
58
|
+
def test_env_automatic(config: Configuration, monkeypatch: pytest.MonkeyPatch) -> None:
|
59
|
+
"""Test that top-level keys can be automatically filled by env variables."""
|
60
|
+
monkeypatch.setenv("NUMBER", "28")
|
61
|
+
monkeypatch.setenv("WORD", "kangaroo")
|
62
|
+
monkeypatch.setenv("A_B_D_KEY_", "works")
|
63
|
+
monkeypatch.setenv("NESTED", "should not be replaced")
|
64
|
+
config_w_env = (config | {"A b@d-key!": ""}).add_envs()
|
65
|
+
|
66
|
+
assert config_w_env.number == "28"
|
67
|
+
assert config_w_env.word == "kangaroo"
|
68
|
+
assert config_w_env["A b@d-key!"] == "works"
|
69
|
+
assert config_w_env.nested != "should not be replaced"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|