configaroo 0.4.2__tar.gz → 0.5.1__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.4.2/src/configaroo.egg-info → configaroo-0.5.1}/PKG-INFO +3 -3
- {configaroo-0.4.2 → configaroo-0.5.1}/README.md +2 -2
- {configaroo-0.4.2 → configaroo-0.5.1}/pyproject.toml +12 -5
- {configaroo-0.4.2 → configaroo-0.5.1}/src/configaroo/__init__.py +1 -1
- {configaroo-0.4.2 → configaroo-0.5.1}/src/configaroo/configuration.py +34 -11
- {configaroo-0.4.2 → configaroo-0.5.1/src/configaroo.egg-info}/PKG-INFO +3 -3
- {configaroo-0.4.2 → configaroo-0.5.1}/tests/test_configuration.py +2 -2
- {configaroo-0.4.2 → configaroo-0.5.1}/tests/test_print.py +46 -0
- {configaroo-0.4.2 → configaroo-0.5.1}/LICENSE +0 -0
- {configaroo-0.4.2 → configaroo-0.5.1}/setup.cfg +0 -0
- {configaroo-0.4.2 → configaroo-0.5.1}/src/configaroo/exceptions.py +0 -0
- {configaroo-0.4.2 → configaroo-0.5.1}/src/configaroo/loaders/__init__.py +0 -0
- {configaroo-0.4.2 → configaroo-0.5.1}/src/configaroo/loaders/json.py +0 -0
- {configaroo-0.4.2 → configaroo-0.5.1}/src/configaroo/loaders/toml.py +0 -0
- {configaroo-0.4.2 → configaroo-0.5.1}/src/configaroo/py.typed +0 -0
- {configaroo-0.4.2 → configaroo-0.5.1}/src/configaroo.egg-info/SOURCES.txt +0 -0
- {configaroo-0.4.2 → configaroo-0.5.1}/src/configaroo.egg-info/dependency_links.txt +0 -0
- {configaroo-0.4.2 → configaroo-0.5.1}/src/configaroo.egg-info/requires.txt +0 -0
- {configaroo-0.4.2 → configaroo-0.5.1}/src/configaroo.egg-info/top_level.txt +0 -0
- {configaroo-0.4.2 → configaroo-0.5.1}/tests/test_dynamic.py +0 -0
- {configaroo-0.4.2 → configaroo-0.5.1}/tests/test_environment.py +0 -0
- {configaroo-0.4.2 → configaroo-0.5.1}/tests/test_json.py +0 -0
- {configaroo-0.4.2 → configaroo-0.5.1}/tests/test_loaders.py +0 -0
- {configaroo-0.4.2 → configaroo-0.5.1}/tests/test_toml.py +0 -0
- {configaroo-0.4.2 → configaroo-0.5.1}/tests/test_validation.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: configaroo
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.5.1
|
4
4
|
Summary: Bouncy handling of configuration files
|
5
5
|
Author-email: Geir Arne Hjelle <geirarne@gmail.com>
|
6
6
|
Maintainer-email: Geir Arne Hjelle <geirarne@gmail.com>
|
@@ -33,9 +33,9 @@ Dynamic: license-file
|
|
33
33
|
[](https://pypi.org/project/configaroo/)
|
34
34
|
[](https://github.com/gahjelle/configaroo/blob/main/LICENSE)
|
35
35
|
[](https://github.com/astral-sh/ruff)
|
36
|
-
[](https://github.com/gahjelle/configaroo/actions/workflows/lint.yml)
|
36
|
+
[](https://github.com/gahjelle/configaroo/actions/workflows/lint.yml)
|
37
37
|
[](https://github.com/gahjelle/configaroo/actions/workflows/test.yml)
|
38
|
-
[](https://microsoft.github.io/pyright/)
|
39
39
|
|
40
40
|
Configaroo is a light configuration package for Python that offers the following features:
|
41
41
|
|
@@ -4,9 +4,9 @@
|
|
4
4
|
[](https://pypi.org/project/configaroo/)
|
5
5
|
[](https://github.com/gahjelle/configaroo/blob/main/LICENSE)
|
6
6
|
[](https://github.com/astral-sh/ruff)
|
7
|
-
[](https://github.com/gahjelle/configaroo/actions/workflows/lint.yml)
|
7
|
+
[](https://github.com/gahjelle/configaroo/actions/workflows/lint.yml)
|
8
8
|
[](https://github.com/gahjelle/configaroo/actions/workflows/test.yml)
|
9
|
-
[](https://microsoft.github.io/pyright/)
|
10
10
|
|
11
11
|
Configaroo is a light configuration package for Python that offers the following features:
|
12
12
|
|
@@ -36,13 +36,14 @@ 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 = ["
|
39
|
+
ci = ["pytest>=8.4.1", "rich>=14.1.0", "ruff>=0.12.7", "tomli-w>=1.2.0"]
|
40
40
|
dev = [
|
41
41
|
{ include-group = "ci" },
|
42
42
|
{ include-group = "test" },
|
43
43
|
"bumpver>=2024.1130",
|
44
44
|
"ipython>=8.36.0",
|
45
45
|
"pre-commit>=4.2.0",
|
46
|
+
"pyright>=1.1.404",
|
46
47
|
]
|
47
48
|
test = ["pytest>=8.4.1", "pytest-cov>=6.2.1", "tomli-w>=1.2.0"]
|
48
49
|
|
@@ -74,12 +75,18 @@ ignore = [
|
|
74
75
|
"tests/test_*.py" = ["PLR2004", "S101", "SLF001", "UP018"]
|
75
76
|
"tests/*/test_*.py" = ["S101"]
|
76
77
|
|
77
|
-
[tool.
|
78
|
-
|
79
|
-
|
78
|
+
[tool.pyright]
|
79
|
+
pythonVersion = "3.11"
|
80
|
+
typeCheckingMode = "strict"
|
81
|
+
verboseOutput = false
|
82
|
+
include = ["src/", "tests/", "examples/"]
|
83
|
+
venv = ".venv"
|
84
|
+
|
85
|
+
reportUnknownArgumentType = "none"
|
86
|
+
reportUnknownMemberType = "none"
|
80
87
|
|
81
88
|
[tool.bumpver]
|
82
|
-
current_version = "v0.
|
89
|
+
current_version = "v0.5.1"
|
83
90
|
version_pattern = "vMAJOR.MINOR.PATCH"
|
84
91
|
commit_message = "bump version {old_version} -> {new_version}"
|
85
92
|
tag_message = "{new_version}"
|
@@ -155,7 +155,7 @@ class Configuration(UserDict[str, Any]):
|
|
155
155
|
self,
|
156
156
|
model: type[BaseModel],
|
157
157
|
prefix: str = "",
|
158
|
-
types: type | UnionType = str | bool | int | float,
|
158
|
+
types: type | UnionType = str | bool | int | float, # pyright: ignore[reportArgumentType]
|
159
159
|
) -> Self:
|
160
160
|
"""Add environment variables to configuration based on the given model.
|
161
161
|
|
@@ -220,26 +220,46 @@ class Configuration(UserDict[str, Any]):
|
|
220
220
|
}
|
221
221
|
|
222
222
|
|
223
|
-
def print_configuration(
|
223
|
+
def print_configuration(
|
224
|
+
config: Configuration | BaseModel, section: str | None = None, indent: int = 4
|
225
|
+
) -> None:
|
224
226
|
"""Pretty print a configuration.
|
225
227
|
|
226
228
|
If rich is installed, then a rich console is used for the printing.
|
227
229
|
"""
|
228
|
-
|
229
|
-
config.model_dump() if isinstance(config, BaseModel) else config
|
230
|
-
indent=indent,
|
231
|
-
_print=_get_rich_print(),
|
230
|
+
cfg = (
|
231
|
+
Configuration(config.model_dump()) if isinstance(config, BaseModel) else config
|
232
232
|
)
|
233
|
+
if section is None:
|
234
|
+
_print, _escape = _get_rich_print()
|
235
|
+
return _print_dict_as_tree(cfg, indent=indent, _print=_print, _escape=_escape)
|
236
|
+
|
237
|
+
cfg_section = cfg.get(section)
|
238
|
+
if cfg_section is None:
|
239
|
+
message = f"'{type(cfg).__name__}' has no section '{section}'"
|
240
|
+
raise KeyError(message) from None
|
241
|
+
|
242
|
+
if isinstance(cfg_section, Configuration):
|
243
|
+
return print_configuration(cfg_section, indent=indent)
|
233
244
|
|
245
|
+
*_, key = section.split(".")
|
246
|
+
return print_configuration(Configuration({key: cfg_section}), indent=indent)
|
234
247
|
|
235
|
-
|
236
|
-
|
248
|
+
|
249
|
+
def _get_rich_print() -> tuple[
|
250
|
+
Callable[[str], None], Callable[[str], str]
|
251
|
+
]: # pragma: no cover
|
252
|
+
"""Initialize a Rich console if Rich is installed, otherwise use built-in print.
|
253
|
+
|
254
|
+
Include a function that can be used to escape markup.
|
255
|
+
"""
|
237
256
|
try:
|
238
257
|
from rich.console import Console # noqa: PLC0415
|
258
|
+
from rich.markup import escape # noqa: PLC0415
|
239
259
|
|
240
|
-
return Console().print
|
260
|
+
return Console().print, escape
|
241
261
|
except ImportError:
|
242
|
-
return print
|
262
|
+
return print, str
|
243
263
|
|
244
264
|
|
245
265
|
def _print_dict_as_tree(
|
@@ -247,6 +267,7 @@ def _print_dict_as_tree(
|
|
247
267
|
indent: int = 4,
|
248
268
|
current_indent: int = 0,
|
249
269
|
_print: Callable[[str], None] = print,
|
270
|
+
_escape: Callable[[str], str] = str,
|
250
271
|
) -> None:
|
251
272
|
"""Print a nested dictionary as a tree."""
|
252
273
|
for key, value in data.items():
|
@@ -257,9 +278,11 @@ def _print_dict_as_tree(
|
|
257
278
|
indent=indent,
|
258
279
|
current_indent=current_indent + indent,
|
259
280
|
_print=_print,
|
281
|
+
_escape=_escape,
|
260
282
|
)
|
261
283
|
else:
|
262
|
-
|
284
|
+
escaped_repr = _escape(repr(value))
|
285
|
+
_print(" " * current_indent + f"- {key}: {escaped_repr}")
|
263
286
|
|
264
287
|
|
265
288
|
def find_pyproject_toml(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: configaroo
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.5.1
|
4
4
|
Summary: Bouncy handling of configuration files
|
5
5
|
Author-email: Geir Arne Hjelle <geirarne@gmail.com>
|
6
6
|
Maintainer-email: Geir Arne Hjelle <geirarne@gmail.com>
|
@@ -33,9 +33,9 @@ Dynamic: license-file
|
|
33
33
|
[](https://pypi.org/project/configaroo/)
|
34
34
|
[](https://github.com/gahjelle/configaroo/blob/main/LICENSE)
|
35
35
|
[](https://github.com/astral-sh/ruff)
|
36
|
-
[](https://github.com/gahjelle/configaroo/actions/workflows/lint.yml)
|
36
|
+
[](https://github.com/gahjelle/configaroo/actions/workflows/lint.yml)
|
37
37
|
[](https://github.com/gahjelle/configaroo/actions/workflows/test.yml)
|
38
|
-
[](https://microsoft.github.io/pyright/)
|
39
39
|
|
40
40
|
Configaroo is a light configuration package for Python that offers the following features:
|
41
41
|
|
@@ -127,12 +127,12 @@ def test_find_pyproject_toml() -> None:
|
|
127
127
|
|
128
128
|
def test_find_foreign_caller() -> None:
|
129
129
|
"""Test that a foreign caller (outside of configaroo) can be identified."""
|
130
|
-
assert configuration._get_foreign_path() == Path(__file__)
|
130
|
+
assert configuration._get_foreign_path() == Path(__file__) # pyright: ignore[reportPrivateUsage]
|
131
131
|
|
132
132
|
|
133
133
|
def test_incomplete_formatter() -> None:
|
134
134
|
"""Test that the incomplete formatter can handle fields that aren't replaced."""
|
135
|
-
formatted = configuration._incomplete_format(
|
135
|
+
formatted = configuration._incomplete_format( # pyright: ignore[reportPrivateUsage]
|
136
136
|
"{number:5.1f} {non_existent} {string!r} {name}",
|
137
137
|
{"number": 3.14, "string": "platypus", "name": "Geir Arne"},
|
138
138
|
)
|
@@ -54,3 +54,49 @@ def test_printing_of_dynamic_values(
|
|
54
54
|
assert "- number: 42" in lines
|
55
55
|
assert "- phrase: 'The meaning of life is 42'" in lines
|
56
56
|
assert " - format: '<level>{level:<8} testing configaroo</level>'" in lines
|
57
|
+
|
58
|
+
|
59
|
+
def test_printing_of_existing_section(
|
60
|
+
capsys: pytest.CaptureFixture[str], config: Configuration
|
61
|
+
) -> None:
|
62
|
+
"""Test that sections can be printed."""
|
63
|
+
print_configuration(config, section="paths")
|
64
|
+
stdout = capsys.readouterr().out
|
65
|
+
lines = stdout.splitlines()
|
66
|
+
|
67
|
+
assert "- absolute: '/home/configaroo'" in lines
|
68
|
+
assert "- number: 42" not in lines
|
69
|
+
|
70
|
+
|
71
|
+
def test_printing_of_nonexisting_section(config: Configuration) -> None:
|
72
|
+
"""Test that non-existing sections raise an error."""
|
73
|
+
with pytest.raises(KeyError):
|
74
|
+
print_configuration(config, section="nonexisting")
|
75
|
+
|
76
|
+
|
77
|
+
def test_printing_of_values(
|
78
|
+
capsys: pytest.CaptureFixture[str], config: Configuration
|
79
|
+
) -> None:
|
80
|
+
"""Test that individual values can be printed."""
|
81
|
+
print_configuration(config, section="number")
|
82
|
+
stdout = capsys.readouterr().out
|
83
|
+
lines = stdout.splitlines()
|
84
|
+
|
85
|
+
assert lines == ["- number: 42"]
|
86
|
+
|
87
|
+
|
88
|
+
def test_printing_of_nested_sections(
|
89
|
+
capsys: pytest.CaptureFixture[str], config: Configuration
|
90
|
+
) -> None:
|
91
|
+
"""Test that nested sections can be printed."""
|
92
|
+
print_configuration(config, section="nested.deep")
|
93
|
+
stdout = capsys.readouterr().out
|
94
|
+
lines = stdout.splitlines()
|
95
|
+
|
96
|
+
assert lines == ["- sea: 'Marianer'"]
|
97
|
+
|
98
|
+
|
99
|
+
def test_printing_of_rich_markup() -> None:
|
100
|
+
"""Test that a config value containing malformed Rich markup can be printed."""
|
101
|
+
config = Configuration({"markup": "[/]"})
|
102
|
+
print_configuration(config)
|
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
|