dycw-utilities 0.109.3__py3-none-any.whl → 0.109.4__py3-none-any.whl
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.
- {dycw_utilities-0.109.3.dist-info → dycw_utilities-0.109.4.dist-info}/METADATA +1 -1
- {dycw_utilities-0.109.3.dist-info → dycw_utilities-0.109.4.dist-info}/RECORD +6 -6
- utilities/__init__.py +1 -1
- utilities/parse.py +64 -23
- {dycw_utilities-0.109.3.dist-info → dycw_utilities-0.109.4.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.109.3.dist-info → dycw_utilities-0.109.4.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
utilities/__init__.py,sha256=
|
1
|
+
utilities/__init__.py,sha256=TfQi7UYijWAmuZ8wsQ7kQKbgWiSQWgaXE80fBUn8qx8,60
|
2
2
|
utilities/altair.py,sha256=NSyDsm8QlkAGmsGdxVwCkHnPxt_35yJBa9Lg7bz9Ays,9054
|
3
3
|
utilities/astor.py,sha256=xuDUkjq0-b6fhtwjhbnebzbqQZAjMSHR1IIS5uOodVg,777
|
4
4
|
utilities/asyncio.py,sha256=41oQUurWMvadFK5gFnaG21hMM0Vmfn2WS6OpC0R9mas,14757
|
@@ -40,7 +40,7 @@ utilities/operator.py,sha256=0M2yZJ0PODH47ogFEnkGMBe_cfxwZR02T_92LZVZvHo,3715
|
|
40
40
|
utilities/optuna.py,sha256=loyJGWTzljgdJaoLhP09PT8Jz6o_pwBOwehY33lHkhw,1923
|
41
41
|
utilities/orjson.py,sha256=Wj5pzG_VdgoAy14a7Luhem-BgYrRtRFvvl_POiszRd0,36930
|
42
42
|
utilities/os.py,sha256=D_FyyT-6TtqiN9KSS7c9g1fnUtgxmyMtzAjmYLkk46A,3587
|
43
|
-
utilities/parse.py,sha256
|
43
|
+
utilities/parse.py,sha256=q1A1-bsXltdAh8We5Acy-lPuVIClWTxsRXQWq5wYyKk,6382
|
44
44
|
utilities/pathlib.py,sha256=31WPMXdLIyXgYOMMl_HOI2wlo66MGSE-cgeelk-Lias,1410
|
45
45
|
utilities/period.py,sha256=ikHXsWtDLr553cfH6p9mMaiCnIAP69B7q84ckWV3HaA,10884
|
46
46
|
utilities/pickle.py,sha256=Bhvd7cZl-zQKQDFjUerqGuSKlHvnW1K2QXeU5UZibtg,657
|
@@ -84,7 +84,7 @@ utilities/warnings.py,sha256=yUgjnmkCRf6QhdyAXzl7u0qQFejhQG3PrjoSwxpbHrs,1819
|
|
84
84
|
utilities/whenever.py,sha256=5x2t47VJmJRWcd_NLFy54NkB3uom-XQYxEbLtEfL1bs,17775
|
85
85
|
utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
|
86
86
|
utilities/zoneinfo.py,sha256=-DQz5a0Ikw9jfSZtL0BEQkXOMC9yGn_xiJYNCLMiqEc,1989
|
87
|
-
dycw_utilities-0.109.
|
88
|
-
dycw_utilities-0.109.
|
89
|
-
dycw_utilities-0.109.
|
90
|
-
dycw_utilities-0.109.
|
87
|
+
dycw_utilities-0.109.4.dist-info/METADATA,sha256=-fU_tSw6cCv59Fg6s0I0pUlV3YzXeuq15kfirsKUmik,13004
|
88
|
+
dycw_utilities-0.109.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
89
|
+
dycw_utilities-0.109.4.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
|
90
|
+
dycw_utilities-0.109.4.dist-info/RECORD,,
|
utilities/__init__.py
CHANGED
utilities/parse.py
CHANGED
@@ -7,30 +7,42 @@ from enum import Enum
|
|
7
7
|
from pathlib import Path
|
8
8
|
from re import DOTALL
|
9
9
|
from types import NoneType
|
10
|
-
from typing import Any, override
|
10
|
+
from typing import TYPE_CHECKING, Any, TypeVar, override
|
11
11
|
|
12
12
|
from utilities.datetime import is_subclass_date_not_datetime
|
13
13
|
from utilities.enum import ParseEnumError, parse_enum
|
14
14
|
from utilities.functions import is_subclass_int_not_bool
|
15
|
-
from utilities.iterables import one, one_str
|
15
|
+
from utilities.iterables import OneEmptyError, OneNonUniqueError, one, one_str
|
16
16
|
from utilities.re import ExtractGroupError, extract_group
|
17
17
|
from utilities.sentinel import ParseSentinelError, Sentinel, parse_sentinel
|
18
18
|
from utilities.text import ParseBoolError, ParseNoneError, parse_bool, parse_none
|
19
19
|
from utilities.typing import get_args, is_literal_type, is_optional_type, is_tuple_type
|
20
20
|
from utilities.version import ParseVersionError, Version, parse_version
|
21
21
|
|
22
|
+
if TYPE_CHECKING:
|
23
|
+
from collections.abc import Callable, Mapping
|
24
|
+
|
25
|
+
|
26
|
+
_T = TypeVar("_T")
|
27
|
+
|
22
28
|
|
23
29
|
def parse_text(
|
24
|
-
obj: Any,
|
30
|
+
obj: Any,
|
31
|
+
text: str,
|
32
|
+
/,
|
33
|
+
*,
|
34
|
+
case_sensitive: bool = False,
|
35
|
+
head: bool = False,
|
36
|
+
extra: Mapping[type[_T], Callable[[str], _T]] | None = None,
|
25
37
|
) -> Any:
|
26
38
|
"""Parse text."""
|
27
39
|
if obj is None:
|
28
40
|
try:
|
29
41
|
return parse_none(text)
|
30
42
|
except ParseNoneError:
|
31
|
-
raise
|
43
|
+
raise _ParseTextParseError(obj=obj, text=text) from None
|
32
44
|
if isinstance(obj, type):
|
33
|
-
return _parse_text_type(obj, text, case_sensitive=case_sensitive)
|
45
|
+
return _parse_text_type(obj, text, case_sensitive=case_sensitive, extra=extra)
|
34
46
|
if is_literal_type(obj):
|
35
47
|
return one_str(get_args(obj), text, head=head, case_sensitive=case_sensitive)
|
36
48
|
if is_optional_type(obj):
|
@@ -42,95 +54,111 @@ def parse_text(
|
|
42
54
|
):
|
43
55
|
try:
|
44
56
|
return _parse_text_type(inner, text, case_sensitive=case_sensitive)
|
45
|
-
except
|
46
|
-
raise
|
57
|
+
except _ParseTextParseError:
|
58
|
+
raise _ParseTextParseError(obj=obj, text=text) from None
|
47
59
|
if is_tuple_type(obj):
|
48
60
|
args = get_args(obj)
|
49
61
|
try:
|
50
62
|
texts = extract_group(r"^\((.*)\)$", text, flags=DOTALL).split(", ")
|
51
63
|
except ExtractGroupError:
|
52
|
-
raise
|
64
|
+
raise _ParseTextParseError(obj=obj, text=text) from None
|
53
65
|
if len(args) != len(texts):
|
54
|
-
raise
|
66
|
+
raise _ParseTextParseError(obj=obj, text=text)
|
55
67
|
return tuple(
|
56
68
|
parse_text(arg, text, case_sensitive=case_sensitive, head=head)
|
57
69
|
for arg, text in zip(args, texts, strict=True)
|
58
70
|
)
|
59
|
-
raise
|
71
|
+
raise _ParseTextParseError(obj=obj, text=text) from None
|
60
72
|
|
61
73
|
|
62
74
|
def _parse_text_type(
|
63
|
-
cls: type[Any],
|
75
|
+
cls: type[Any],
|
76
|
+
text: str,
|
77
|
+
/,
|
78
|
+
*,
|
79
|
+
case_sensitive: bool = False,
|
80
|
+
extra: Mapping[type[_T], Callable[[str], _T]] | None = None,
|
64
81
|
) -> Any:
|
65
82
|
"""Parse text."""
|
66
83
|
if issubclass(cls, NoneType):
|
67
84
|
try:
|
68
85
|
return parse_none(text)
|
69
86
|
except ParseNoneError:
|
70
|
-
raise
|
87
|
+
raise _ParseTextParseError(obj=cls, text=text) from None
|
71
88
|
if issubclass(cls, str):
|
72
89
|
return text
|
73
90
|
if issubclass(cls, bool):
|
74
91
|
try:
|
75
92
|
return parse_bool(text)
|
76
93
|
except ParseBoolError:
|
77
|
-
raise
|
94
|
+
raise _ParseTextParseError(obj=cls, text=text) from None
|
78
95
|
if is_subclass_int_not_bool(cls):
|
79
96
|
try:
|
80
97
|
return int(text)
|
81
98
|
except ValueError:
|
82
|
-
raise
|
99
|
+
raise _ParseTextParseError(obj=cls, text=text) from None
|
83
100
|
if issubclass(cls, float):
|
84
101
|
try:
|
85
102
|
return float(text)
|
86
103
|
except ValueError:
|
87
|
-
raise
|
104
|
+
raise _ParseTextParseError(obj=cls, text=text) from None
|
88
105
|
if issubclass(cls, Enum):
|
89
106
|
try:
|
90
107
|
return parse_enum(text, cls, case_sensitive=case_sensitive)
|
91
108
|
except ParseEnumError:
|
92
|
-
raise
|
109
|
+
raise _ParseTextParseError(obj=cls, text=text) from None
|
93
110
|
if issubclass(cls, Path):
|
94
111
|
return Path(text).expanduser()
|
95
112
|
if issubclass(cls, Sentinel):
|
96
113
|
try:
|
97
114
|
return parse_sentinel(text)
|
98
115
|
except ParseSentinelError:
|
99
|
-
raise
|
116
|
+
raise _ParseTextParseError(obj=cls, text=text) from None
|
100
117
|
if issubclass(cls, Version):
|
101
118
|
try:
|
102
119
|
return parse_version(text)
|
103
120
|
except ParseVersionError:
|
104
|
-
raise
|
121
|
+
raise _ParseTextParseError(obj=cls, text=text) from None
|
105
122
|
if is_subclass_date_not_datetime(cls):
|
106
123
|
from utilities.whenever import ParseDateError, parse_date
|
107
124
|
|
108
125
|
try:
|
109
126
|
return parse_date(text)
|
110
127
|
except ParseDateError:
|
111
|
-
raise
|
128
|
+
raise _ParseTextParseError(obj=cls, text=text) from None
|
112
129
|
if issubclass(cls, dt.datetime):
|
113
130
|
from utilities.whenever import ParseDateTimeError, parse_datetime
|
114
131
|
|
115
132
|
try:
|
116
133
|
return parse_datetime(text)
|
117
134
|
except ParseDateTimeError:
|
118
|
-
raise
|
135
|
+
raise _ParseTextParseError(obj=cls, text=text) from None
|
119
136
|
if issubclass(cls, dt.time):
|
120
137
|
from utilities.whenever import ParseTimeError, parse_time
|
121
138
|
|
122
139
|
try:
|
123
140
|
return parse_time(text)
|
124
141
|
except ParseTimeError:
|
125
|
-
raise
|
142
|
+
raise _ParseTextParseError(obj=cls, text=text) from None
|
126
143
|
if issubclass(cls, dt.timedelta):
|
127
144
|
from utilities.whenever import ParseTimedeltaError, parse_timedelta
|
128
145
|
|
129
146
|
try:
|
130
147
|
return parse_timedelta(text)
|
131
148
|
except ParseTimedeltaError:
|
132
|
-
raise
|
133
|
-
|
149
|
+
raise _ParseTextParseError(obj=cls, text=text) from None
|
150
|
+
if extra is not None:
|
151
|
+
try:
|
152
|
+
parser = one(p for c, p in extra.items() if issubclass(cls, c))
|
153
|
+
except OneEmptyError:
|
154
|
+
pass
|
155
|
+
except OneNonUniqueError as error:
|
156
|
+
raise _ParseTextExtraNonUniqueError(
|
157
|
+
obj=cls, text=text, first=error.first, second=error.second
|
158
|
+
) from None
|
159
|
+
else:
|
160
|
+
return parser(text)
|
161
|
+
raise _ParseTextParseError(obj=cls, text=text) from None
|
134
162
|
|
135
163
|
|
136
164
|
@dataclass
|
@@ -138,6 +166,19 @@ class ParseTextError(Exception):
|
|
138
166
|
obj: Any
|
139
167
|
text: str
|
140
168
|
|
169
|
+
|
170
|
+
@dataclass
|
171
|
+
class _ParseTextParseError(ParseTextError):
|
141
172
|
@override
|
142
173
|
def __str__(self) -> str:
|
143
174
|
return f"Unable to parse {self.obj!r}; got {self.text!r}"
|
175
|
+
|
176
|
+
|
177
|
+
@dataclass
|
178
|
+
class _ParseTextExtraNonUniqueError(ParseTextError):
|
179
|
+
first: type[Any]
|
180
|
+
second: type[Any]
|
181
|
+
|
182
|
+
@override
|
183
|
+
def __str__(self) -> str:
|
184
|
+
return f"Unable to parse {self.obj!r} since `extra` must contain exactly one parent class; got {self.first!r}, {self.second!r} and perhaps more"
|
File without changes
|
File without changes
|