dataconf 2.2.1__tar.gz → 2.2.2__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.
- {dataconf-2.2.1 → dataconf-2.2.2}/PKG-INFO +3 -3
- {dataconf-2.2.1 → dataconf-2.2.2}/dataconf/utils.py +30 -23
- dataconf-2.2.2/dataconf/version.py +6 -0
- {dataconf-2.2.1 → dataconf-2.2.2}/pyproject.toml +7 -7
- {dataconf-2.2.1 → dataconf-2.2.2}/setup.py +2 -2
- dataconf-2.2.1/dataconf/version.py +0 -1
- {dataconf-2.2.1 → dataconf-2.2.2}/LICENSE +0 -0
- {dataconf-2.2.1 → dataconf-2.2.2}/README.md +0 -0
- {dataconf-2.2.1 → dataconf-2.2.2}/dataconf/__init__.py +0 -0
- {dataconf-2.2.1 → dataconf-2.2.2}/dataconf/cli.py +0 -0
- {dataconf-2.2.1 → dataconf-2.2.2}/dataconf/exceptions.py +0 -0
- {dataconf-2.2.1 → dataconf-2.2.2}/dataconf/main.py +0 -0
- {dataconf-2.2.1 → dataconf-2.2.2}/dataconf/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dataconf
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.2
|
|
4
4
|
Summary: Simple dataclasses configuration management for Python with hocon/json/yaml/properties/env-vars/dict support.
|
|
5
5
|
Home-page: https://github.com/zifeo/dataconf
|
|
6
6
|
License: MPL-2.0
|
|
@@ -15,8 +15,8 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.8
|
|
17
17
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
-
Requires-Dist: PyYAML (>=6.0,<7.0)
|
|
19
|
-
Requires-Dist: pyhocon (==0.3.
|
|
18
|
+
Requires-Dist: PyYAML (>=6.0.1,<7.0.0)
|
|
19
|
+
Requires-Dist: pyhocon (==0.3.59)
|
|
20
20
|
Requires-Dist: python-dateutil (>=2.8.2,<3.0.0)
|
|
21
21
|
Project-URL: Repository, https://github.com/zifeo/dataconf
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
@@ -6,6 +6,7 @@ from datetime import datetime
|
|
|
6
6
|
from enum import Enum
|
|
7
7
|
from enum import IntEnum
|
|
8
8
|
from inspect import isclass
|
|
9
|
+
|
|
9
10
|
from typing import Any
|
|
10
11
|
from typing import Dict
|
|
11
12
|
from typing import get_args
|
|
@@ -28,6 +29,12 @@ from pyhocon.config_tree import ConfigList
|
|
|
28
29
|
from pyhocon.config_tree import ConfigTree
|
|
29
30
|
import pyparsing
|
|
30
31
|
|
|
32
|
+
from dataconf.version import PY310up
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
if PY310up:
|
|
36
|
+
from types import UnionType
|
|
37
|
+
|
|
31
38
|
|
|
32
39
|
NoneType = type(None)
|
|
33
40
|
|
|
@@ -42,9 +49,13 @@ def __parse_type(value: Any, clazz: Type, path: str, check: bool):
|
|
|
42
49
|
raise TypeConfigException(f"expected type {clazz} at {path}, got {type(value)}")
|
|
43
50
|
|
|
44
51
|
|
|
52
|
+
def is_union(origin):
|
|
53
|
+
return origin is Union or (PY310up and origin is UnionType)
|
|
54
|
+
|
|
55
|
+
|
|
45
56
|
def is_optional(type: Type):
|
|
46
57
|
# Optional = Union[T, NoneType]
|
|
47
|
-
return get_origin(type)
|
|
58
|
+
return is_union(get_origin(type)) and NoneType in get_args(type)
|
|
48
59
|
|
|
49
60
|
|
|
50
61
|
def __parse(value: any, clazz: Type, path: str, strict: bool, ignore_unexpected: bool):
|
|
@@ -123,33 +134,29 @@ def __parse(value: any, clazz: Type, path: str, strict: bool, ignore_unexpected:
|
|
|
123
134
|
}
|
|
124
135
|
return None
|
|
125
136
|
|
|
126
|
-
if
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return __parse(
|
|
130
|
-
value,
|
|
131
|
-
left if right is NoneType else right,
|
|
132
|
-
path,
|
|
133
|
-
strict,
|
|
134
|
-
ignore_unexpected,
|
|
135
|
-
)
|
|
136
|
-
except TypeConfigException:
|
|
137
|
-
# cannot parse Optional
|
|
138
|
-
return None
|
|
139
|
-
|
|
140
|
-
if origin is Union:
|
|
137
|
+
if is_union(origin):
|
|
138
|
+
# Optional = Union[T, NoneType]
|
|
139
|
+
has_none = False
|
|
141
140
|
for parse_candidate in args:
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
141
|
+
if parse_candidate is NoneType:
|
|
142
|
+
has_none = True
|
|
143
|
+
else:
|
|
144
|
+
try:
|
|
145
|
+
return __parse(
|
|
146
|
+
value, parse_candidate, path, strict, ignore_unexpected
|
|
147
|
+
)
|
|
148
|
+
except TypeConfigException:
|
|
149
|
+
continue
|
|
150
|
+
|
|
151
|
+
if has_none:
|
|
152
|
+
return None
|
|
146
153
|
|
|
147
154
|
raise TypeConfigException(
|
|
148
155
|
f"expected one of {', '.join(map(str, args))} at {path}, got {type(value)}"
|
|
149
156
|
)
|
|
150
157
|
|
|
151
158
|
if clazz is bool:
|
|
152
|
-
if not strict:
|
|
159
|
+
if not strict and value is not None:
|
|
153
160
|
try:
|
|
154
161
|
value = bool(value)
|
|
155
162
|
except ValueError:
|
|
@@ -157,7 +164,7 @@ def __parse(value: any, clazz: Type, path: str, strict: bool, ignore_unexpected:
|
|
|
157
164
|
return __parse_type(value, clazz, path, isinstance(value, bool))
|
|
158
165
|
|
|
159
166
|
if clazz is int:
|
|
160
|
-
if not strict:
|
|
167
|
+
if not strict and value is not None:
|
|
161
168
|
try:
|
|
162
169
|
value = int(value)
|
|
163
170
|
except ValueError:
|
|
@@ -165,7 +172,7 @@ def __parse(value: any, clazz: Type, path: str, strict: bool, ignore_unexpected:
|
|
|
165
172
|
return __parse_type(value, clazz, path, isinstance(value, int))
|
|
166
173
|
|
|
167
174
|
if clazz is float:
|
|
168
|
-
if not strict:
|
|
175
|
+
if not strict and value is not None:
|
|
169
176
|
try:
|
|
170
177
|
value = float(value)
|
|
171
178
|
except ValueError:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "dataconf"
|
|
3
|
-
version = "2.2.
|
|
3
|
+
version = "2.2.2"
|
|
4
4
|
description = "Simple dataclasses configuration management for Python with hocon/json/yaml/properties/env-vars/dict support."
|
|
5
5
|
authors = []
|
|
6
6
|
license = "MPL-2.0"
|
|
@@ -30,20 +30,20 @@ dataconf = 'dataconf.cli:run'
|
|
|
30
30
|
|
|
31
31
|
[tool.poetry.dependencies]
|
|
32
32
|
python = "^3.8"
|
|
33
|
-
pyhocon = "0.3.
|
|
33
|
+
pyhocon = "0.3.59"
|
|
34
34
|
python-dateutil = "^2.8.2"
|
|
35
|
-
PyYAML = "^6.0"
|
|
35
|
+
PyYAML = "^6.0.1"
|
|
36
36
|
|
|
37
37
|
[tool.poetry.group.dev.dependencies]
|
|
38
|
-
pytest = "^7.
|
|
38
|
+
pytest = "^7.4.2"
|
|
39
39
|
pre-commit = ">=2.21,<4.0"
|
|
40
40
|
commitizen = ">=2.42.1,<4.0.0"
|
|
41
|
-
pytest-httpserver = "^1.0.
|
|
42
|
-
ruff = ">=0.0.247,<0.0.
|
|
41
|
+
pytest-httpserver = "^1.0.8"
|
|
42
|
+
ruff = ">=0.0.247,<0.0.287"
|
|
43
43
|
|
|
44
44
|
[tool.commitizen]
|
|
45
45
|
name = "cz_conventional_commits"
|
|
46
|
-
version = "2.2.
|
|
46
|
+
version = "2.2.2"
|
|
47
47
|
tag_format = "v$major.$minor.$patch$prerelease"
|
|
48
48
|
version_files = [
|
|
49
49
|
"pyproject.toml:version",
|
|
@@ -8,14 +8,14 @@ package_data = \
|
|
|
8
8
|
{'': ['*']}
|
|
9
9
|
|
|
10
10
|
install_requires = \
|
|
11
|
-
['PyYAML>=6.0,<7.0', 'pyhocon==0.3.
|
|
11
|
+
['PyYAML>=6.0.1,<7.0.0', 'pyhocon==0.3.59', 'python-dateutil>=2.8.2,<3.0.0']
|
|
12
12
|
|
|
13
13
|
entry_points = \
|
|
14
14
|
{'console_scripts': ['dataconf = dataconf.cli:run']}
|
|
15
15
|
|
|
16
16
|
setup_kwargs = {
|
|
17
17
|
'name': 'dataconf',
|
|
18
|
-
'version': '2.2.
|
|
18
|
+
'version': '2.2.2',
|
|
19
19
|
'description': 'Simple dataclasses configuration management for Python with hocon/json/yaml/properties/env-vars/dict support.',
|
|
20
20
|
'long_description': '# Dataconf\n\n[](https://github.com/zifeo/dataconf/actions)\n[](https://badge.fury.io/py/dataconf)\n\nSimple dataclasses configuration management for Python with\nhocon/json/yaml/properties/env-vars/dict/cli support.\n\n## Getting started\n\nRequires at least Python 3.8.\n\n```bash\n# pypi\npip install dataconf\npoetry add dataconf\n\n# remote master\npip install --upgrade git+https://github.com/zifeo/dataconf.git\npoetry add git+https://github.com/zifeo/dataconf.git\n\n# local repo/dev\npoetry install\npre-commit install\n```\n\n## Usage\n\n```python\nimport os\nfrom dataclasses import dataclass, field\nfrom typing import List, Dict, Text, Union\nfrom dateutil.relativedelta import relativedelta\nfrom datetime import datetime\nimport dataconf\n\nconf = """\nstr_name = test\nstr_name = ${?HOME}\ndash-to-underscore = true\nfloat_num = 2.2\niso_datetime = "2000-01-01T20:00:00"\n# this is a comment\nlist_data = [\n a\n b\n]\nnested {\n a = test\n b : 1\n}\nnested_list = [\n {\n a = test1\n b : 2.5\n }\n]\nduration = 2s\nunion = 1\npeople {\n name = Thailand\n}\nzone {\n area_code = 42\n}\n"""\n\nclass AbstractBaseClass:\n pass\n \n@dataclass\nclass Person(AbstractBaseClass):\n name: Text\n \n@dataclass\nclass Zone(AbstractBaseClass):\n area_code: int\n\n@dataclass\nclass Nested:\n a: Text\n b: float\n\n@dataclass\nclass Config:\n str_name: Text\n dash_to_underscore: bool\n float_num: float\n iso_datetime: datetime\n list_data: List[Text]\n nested: Nested\n nested_list: List[Nested]\n duration: relativedelta\n union: Union[Text, int]\n people: AbstractBaseClass\n zone: AbstractBaseClass\n default: Text = \'hello\'\n default_factory: Dict[Text, Text] = field(default_factory=dict)\n\nprint(dataconf.string(conf, Config))\n# Config(\n# str_name=\'/users/root\',\n# dash_to_underscore=True,\n# float_num=2.2,\n# list_data=[\'a\', \'b\'],\n# nested=Nested(a=\'test\'),\n# nested_list=[Nested(a=\'test1\', b=2.5)],\n# duration=relativedelta(seconds=+2), \n# union=1, \n# people=Person(name=\'Thailand\'), \n# zone=Zone(area_code=42),\n# default=\'hello\', \n# default_factory={}\n# )\n\n@dataclass\nclass Example:\n hello: str\n world: str\n foo: List[str]\n\nos.environ[\'DC_WORLD\'] = \'monde\'\n\nprint(\n dataconf\n .multi\n .url(\'https://raw.githubusercontent.com/zifeo/dataconf/main/confs/simple.hocon\')\n .env(\'DC\')\n .on(Example)\n)\n# Example(hello=\'bonjour\',world=\'monde\')\n```\n\n## API\n\n```python\nimport dataconf\n\nconf = dataconf.string(\'{ name: Test }\', Config)\nconf = dataconf.string(\'name:\\n\\tvalue: Test\', Config, loader=dataconf.YAML) # dataconf.HOCON by default\nconf = dataconf.env(\'PREFIX_\', Config)\nconf = dataconf.dict({\'name\': \'Test\'}, Config)\nconf = dataconf.url(\'https://raw.githubusercontent.com/zifeo/dataconf/master/confs/test.hocon\', Config) # hocon, json, yaml, properties\nconf = dataconf.file(\'confs/test.hocon\', Config) # hocon, json, yaml, properties\nconf = dataconf.cli(sys.argv, Config)\n\n# Aggregation\nconf = dataconf.multi.string(...).env(...).url(...).file(...).dict(...).cli(...).on(Config)\n\n# Same api as Python json/yaml packages (e.g. `load`, `loads`, `dump`, `dumps`)\nconf = dataconf.load(\'confs/test.hocon\', Config) # hocon, json, yaml, properties\nconf = dataconf.load(\'confs/test.yaml\', Config, loader=dataconf.YAML) # dataconf.HOCON by default\ndataconf.dump(\'confs/test.hocon\', conf, out=\'hocon\')\ndataconf.dump(\'confs/test.json\', conf, out=\'json\')\ndataconf.dump(\'confs/test.yaml\', conf, out=\'yaml\')\ndataconf.dump(\'confs/test.properties\', conf, out=\'properties\')\n```\n\nFor full HOCON capabilities see\n[here](https://github.com/chimpler/pyhocon/#example-of-hocon-file).\n\n## Parse env vars\n\n```bash\nPREFIX_VAR=a\nPREFIX_VAR_NAME=b\nPREFIX_TEST__NAME=c\nPREFIX_LS_0=d\nPREFIX_LS_1=e\nPREFIX_LSLS_0_0=f\nPREFIX_LSOB_0__NAME=g\nPREFIX_NESTED_="{ name: Test }"\nPREFIX_SUB_="{ value: ${PREFIX_VAR} }"\n```\n\nis equivalent to\n\n```\n{\n var = a\n var_name = b\n test {\n name = c\n }\n ls = [\n d\n e\n ]\n lsls = [\n [\n f\n ]\n ]\n lsob = [\n {\n name = g\n }\n ]\n nested {\n # parse nested config by suffixing env var with `_`\n name: Test\n }\n sub {\n # will have value "a" at parsing, useful for aliases\n value = ${PREFIX_VAR}\n }\n}\n```\n\nNote that when using `.env` source, the strict mode is disabled and value might\nbe casted.\n\n## Parse CLI arguments\n\nSame as env vars parse (dashes are converted to underscore, e.g. `TEST_A` →\n`--test-a`).\n\n## CLI usage\n\nCan be used for validation or converting between supported file formats (`-o`).\n\n```shell\ndataconf -c confs/test.hocon -m tests.configs -d TestConf -o hocon\n# dataconf.exceptions.TypeConfigException: expected type <class \'datetime.timedelta\'> at .duration, got <class \'int\'>\n```\n',
|
|
21
21
|
'author': 'None',
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.2.1"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|