typedparser 0.2.11__tar.gz → 0.2.27__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.
- {typedparser-0.2.11 → typedparser-0.2.27}/PKG-INFO +1 -1
- typedparser-0.2.27/src/typedparser/__init__.py +18 -0
- {typedparser-0.2.11 → typedparser-0.2.27}/src/typedparser/_typedattr.py +103 -32
- {typedparser-0.2.11 → typedparser-0.2.27}/src/typedparser.egg-info/PKG-INFO +1 -1
- typedparser-0.2.11/src/typedparser/__init__.py +0 -8
- {typedparser-0.2.11 → typedparser-0.2.27}/LICENSE +0 -0
- {typedparser-0.2.11 → typedparser-0.2.27}/README.md +0 -0
- {typedparser-0.2.11 → typedparser-0.2.27}/pyproject.toml +0 -0
- {typedparser-0.2.11 → typedparser-0.2.27}/requirements.txt +0 -0
- {typedparser-0.2.11 → typedparser-0.2.27}/setup.cfg +0 -0
- {typedparser-0.2.11 → typedparser-0.2.27}/src/typedparser/_typedparser.py +0 -0
- {typedparser-0.2.11 → typedparser-0.2.27}/src/typedparser/custom_format.py +0 -0
- {typedparser-0.2.11 → typedparser-0.2.27}/src/typedparser/funcs.py +0 -0
- {typedparser-0.2.11 → typedparser-0.2.27}/src/typedparser/objects.py +0 -0
- {typedparser-0.2.11 → typedparser-0.2.27}/src/typedparser.egg-info/SOURCES.txt +0 -0
- {typedparser-0.2.11 → typedparser-0.2.27}/src/typedparser.egg-info/dependency_links.txt +0 -0
- {typedparser-0.2.11 → typedparser-0.2.27}/src/typedparser.egg-info/requires.txt +0 -0
- {typedparser-0.2.11 → typedparser-0.2.27}/src/typedparser.egg-info/top_level.txt +0 -0
- {typedparser-0.2.11 → typedparser-0.2.27}/src/typedparser.egg-info/zip-safe +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from ._typedattr import definenumpy, attrs_from_dict, NamedTupleMixin
|
|
2
|
+
from ._typedparser import add_argument, TypedParser, define, VerboseQuietArgs
|
|
3
|
+
from .custom_format import CustomArgparseFmt
|
|
4
|
+
from .objects import get_attr_names
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"definenumpy",
|
|
8
|
+
"attrs_from_dict",
|
|
9
|
+
"NamedTupleMixin",
|
|
10
|
+
"add_argument",
|
|
11
|
+
"TypedParser",
|
|
12
|
+
"define",
|
|
13
|
+
"VerboseQuietArgs",
|
|
14
|
+
"CustomArgparseFmt",
|
|
15
|
+
"get_attr_names",
|
|
16
|
+
]
|
|
17
|
+
__version__ = "0.2.27"
|
|
18
|
+
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import collections
|
|
2
|
+
from abc import abstractmethod
|
|
2
3
|
from functools import partial
|
|
3
4
|
from inspect import isclass
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
from typing import (
|
|
6
|
-
Tuple,
|
|
7
|
+
Tuple,
|
|
8
|
+
Union,
|
|
9
|
+
Dict,
|
|
10
|
+
AbstractSet,
|
|
11
|
+
Iterable,
|
|
12
|
+
Mapping,
|
|
13
|
+
Collection,
|
|
14
|
+
Type,
|
|
15
|
+
Any,
|
|
16
|
+
List,
|
|
17
|
+
Optional,
|
|
18
|
+
overload,
|
|
19
|
+
)
|
|
7
20
|
|
|
8
21
|
import attrs
|
|
9
22
|
from attr import has, AttrsInstance
|
|
@@ -50,11 +63,25 @@ def definenumpy(maybe_cls: Union[bool, Type] = False, **kwargs):
|
|
|
50
63
|
return wrap
|
|
51
64
|
|
|
52
65
|
|
|
66
|
+
class NamedTupleMixin:
|
|
67
|
+
def __iter__(self):
|
|
68
|
+
return (getattr(self, att.name) for att in fields(type(self)))
|
|
69
|
+
|
|
70
|
+
def __getitem__(self, index_or_slice: int):
|
|
71
|
+
return tuple(self)[index_or_slice]
|
|
72
|
+
|
|
73
|
+
def __len__(self) -> int:
|
|
74
|
+
return len(fields(type(self)))
|
|
75
|
+
|
|
76
|
+
|
|
53
77
|
def attrs_from_dict(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
78
|
+
cls: AttrsClass,
|
|
79
|
+
input_dict_or_attrs_inst: Union[Dict, AttrsInstance],
|
|
80
|
+
strict: bool = True,
|
|
81
|
+
skip_unknowns: bool = False,
|
|
82
|
+
recursor_class: Type[RecursorInterface] = StrictRecursor,
|
|
83
|
+
conversions: Optional[conversion_type] = None,
|
|
84
|
+
) -> AttrsInstance:
|
|
58
85
|
"""
|
|
59
86
|
Create typechecked attrs instance from dictionary or existing attrs instance.
|
|
60
87
|
|
|
@@ -74,29 +101,47 @@ def attrs_from_dict(
|
|
|
74
101
|
"""
|
|
75
102
|
recursor = recursor_class()
|
|
76
103
|
try:
|
|
77
|
-
return _attrs_from_dict(
|
|
78
|
-
|
|
104
|
+
return _attrs_from_dict(
|
|
105
|
+
recursor,
|
|
106
|
+
cls,
|
|
107
|
+
input_dict_or_attrs_inst,
|
|
108
|
+
strict=strict,
|
|
109
|
+
skip_unknowns=skip_unknowns,
|
|
110
|
+
conversions=conversions,
|
|
111
|
+
)
|
|
79
112
|
except TypeError as e:
|
|
80
|
-
raise TypeError(
|
|
81
|
-
|
|
113
|
+
raise TypeError(
|
|
114
|
+
f"Error parsing {cls} from {input_dict_or_attrs_inst}, see the original "
|
|
115
|
+
f"error above."
|
|
116
|
+
) from e
|
|
82
117
|
|
|
83
118
|
|
|
84
119
|
def _attrs_from_dict(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
120
|
+
recursor: RecursorInterface,
|
|
121
|
+
cls: AttrsClass,
|
|
122
|
+
input_dict_or_attrs: Union[Dict, object],
|
|
123
|
+
strict: bool = False,
|
|
124
|
+
skip_unknowns: bool = False,
|
|
125
|
+
conversions: Optional[conversion_type] = None,
|
|
126
|
+
):
|
|
88
127
|
_print_fn(f"Parsing {cls} from {input_dict_or_attrs}")
|
|
89
128
|
input_cls = type(input_dict_or_attrs)
|
|
90
129
|
if has(input_cls):
|
|
91
130
|
# if given an attrs instance, convert it to dict and then
|
|
92
131
|
# parse it for conversions and typechecking
|
|
93
|
-
assert
|
|
94
|
-
|
|
132
|
+
assert (
|
|
133
|
+
input_cls == cls
|
|
134
|
+
), f"Mismatch: Trying to parse input of type {input_cls} as type {cls}"
|
|
95
135
|
input_fields_dict = fields_dict(type(input_dict_or_attrs))
|
|
96
136
|
input_dict: Dict[str, Any] = {k: getattr(input_dict_or_attrs, k) for k in input_fields_dict}
|
|
97
137
|
return _attrs_from_dict(
|
|
98
|
-
recursor,
|
|
99
|
-
|
|
138
|
+
recursor,
|
|
139
|
+
input_cls,
|
|
140
|
+
input_dict,
|
|
141
|
+
strict=strict,
|
|
142
|
+
skip_unknowns=skip_unknowns,
|
|
143
|
+
conversions=conversions,
|
|
144
|
+
)
|
|
100
145
|
|
|
101
146
|
input_dict: Dict[str, Any] = input_dict_or_attrs
|
|
102
147
|
if input_dict is None:
|
|
@@ -139,15 +184,24 @@ def _attrs_from_dict(
|
|
|
139
184
|
name = att.name
|
|
140
185
|
value = getattr(attrs_inst, name)
|
|
141
186
|
typ = att.type
|
|
142
|
-
new_value = _parse_nested(
|
|
143
|
-
|
|
187
|
+
new_value = _parse_nested(
|
|
188
|
+
recursor,
|
|
189
|
+
name,
|
|
190
|
+
value,
|
|
191
|
+
typ,
|
|
192
|
+
strict=strict,
|
|
193
|
+
skip_unknowns=skip_unknowns,
|
|
194
|
+
conversions=conversions,
|
|
195
|
+
)
|
|
144
196
|
setattr(attrs_inst, name, new_value)
|
|
145
197
|
|
|
146
198
|
# handle unknown fields
|
|
147
199
|
if len(nonmatching_input) > 0 and not skip_unknowns:
|
|
148
200
|
if strict:
|
|
149
|
-
raise TypeError(
|
|
150
|
-
|
|
201
|
+
raise TypeError(
|
|
202
|
+
f"Keys in input {list(nonmatching_input.keys())} not defined "
|
|
203
|
+
f"for class {cls} with attributes {sorted(all_att_names)}"
|
|
204
|
+
)
|
|
151
205
|
for key, value in nonmatching_input.items():
|
|
152
206
|
if skip_unknowns:
|
|
153
207
|
break
|
|
@@ -158,15 +212,23 @@ def _attrs_from_dict(
|
|
|
158
212
|
raise AttributeError(
|
|
159
213
|
f"Field {key} is missing from configuration {cls}. Either add it to the "
|
|
160
214
|
f"configuration or decorate with @attrs.define(slots=False) to allow adding "
|
|
161
|
-
f"unknown fields or set skip_unknowns=True to ignore them."
|
|
215
|
+
f"unknown fields or set skip_unknowns=True to ignore them."
|
|
216
|
+
) from e
|
|
162
217
|
|
|
163
218
|
_print_fn(f"Output of _attrs_from_dict: {attrs_inst}")
|
|
164
219
|
return attrs_inst
|
|
165
220
|
|
|
166
221
|
|
|
167
|
-
def _parse_nested(
|
|
168
|
-
|
|
169
|
-
|
|
222
|
+
def _parse_nested(
|
|
223
|
+
recursor: RecursorInterface,
|
|
224
|
+
name,
|
|
225
|
+
value,
|
|
226
|
+
typ,
|
|
227
|
+
strict: bool = True,
|
|
228
|
+
skip_unknowns: bool = False,
|
|
229
|
+
conversions: conversion_type = None,
|
|
230
|
+
depth: int = 0,
|
|
231
|
+
):
|
|
170
232
|
conversions = default_conversions if conversions is None else conversions
|
|
171
233
|
parse_recursive = partial(_parse_nested, recursor, depth=depth + 1, skip_unknowns=skip_unknowns)
|
|
172
234
|
|
|
@@ -176,10 +238,11 @@ def _parse_nested(recursor: RecursorInterface, name, value, typ,
|
|
|
176
238
|
target_type_name = typ.__name__ if hasattr(typ, "__name__") else str(typ)
|
|
177
239
|
value_type = type(value)
|
|
178
240
|
value_type_name = value_type.__name__ if hasattr(value_type, "__name__") else str(value_type)
|
|
179
|
-
err_msg = (
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
241
|
+
err_msg = (
|
|
242
|
+
f"Could not parse {name}={value} (type {value_type_name}) as type "
|
|
243
|
+
f"{target_type_name} with strict={strict} "
|
|
244
|
+
# f"depth={depth} type annotation origin={origin} args={args}"
|
|
245
|
+
)
|
|
183
246
|
|
|
184
247
|
def maybe_raise_typeerorr(full_err_msg):
|
|
185
248
|
if strict:
|
|
@@ -189,8 +252,14 @@ def _parse_nested(recursor: RecursorInterface, name, value, typ,
|
|
|
189
252
|
|
|
190
253
|
# resolve nested attrclass
|
|
191
254
|
if has(typ):
|
|
192
|
-
return _attrs_from_dict(
|
|
193
|
-
|
|
255
|
+
return _attrs_from_dict(
|
|
256
|
+
recursor,
|
|
257
|
+
typ,
|
|
258
|
+
value,
|
|
259
|
+
strict=strict,
|
|
260
|
+
skip_unknowns=skip_unknowns,
|
|
261
|
+
conversions=conversions,
|
|
262
|
+
)
|
|
194
263
|
|
|
195
264
|
# resolve any
|
|
196
265
|
if typ == Any:
|
|
@@ -217,7 +286,8 @@ def _parse_nested(recursor: RecursorInterface, name, value, typ,
|
|
|
217
286
|
return maybe_raise_typeerorr(f"{err_msg}. Expect a sequence, got {type(value)}")
|
|
218
287
|
if len(value) != len(args):
|
|
219
288
|
return maybe_raise_typeerorr(
|
|
220
|
-
f"{err_msg}. Expect a sequence with length {len(args)}, got length {len(value)}"
|
|
289
|
+
f"{err_msg}. Expect a sequence with length {len(args)}, got length {len(value)}"
|
|
290
|
+
)
|
|
221
291
|
new_tuple = []
|
|
222
292
|
for item, item_type in zip(value, args):
|
|
223
293
|
new_tuple.append(parse_recursive(name, item, item_type, strict=strict))
|
|
@@ -242,7 +312,8 @@ def _parse_nested(recursor: RecursorInterface, name, value, typ,
|
|
|
242
312
|
|
|
243
313
|
for key, val in value.items():
|
|
244
314
|
dict_output[parse_recursive(name, key, dict_keytype, strict=strict)] = parse_recursive(
|
|
245
|
-
name, val, dict_valuetype, strict=strict
|
|
315
|
+
name, val, dict_valuetype, strict=strict
|
|
316
|
+
)
|
|
246
317
|
|
|
247
318
|
return dict_output
|
|
248
319
|
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
from ._typedattr import definenumpy, attrs_from_dict
|
|
2
|
-
from ._typedparser import add_argument, TypedParser, define, VerboseQuietArgs
|
|
3
|
-
from .custom_format import CustomArgparseFmt
|
|
4
|
-
from .objects import get_attr_names
|
|
5
|
-
|
|
6
|
-
__all__ = ["definenumpy", "attrs_from_dict", "get_attr_names",
|
|
7
|
-
"add_argument", "TypedParser", "define", "VerboseQuietArgs", "CustomArgparseFmt"]
|
|
8
|
-
__version__ = "0.2.11"
|
|
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
|