dycw-utilities 0.109.24__py3-none-any.whl → 0.109.26__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.24.dist-info → dycw_utilities-0.109.26.dist-info}/METADATA +1 -1
- {dycw_utilities-0.109.24.dist-info → dycw_utilities-0.109.26.dist-info}/RECORD +8 -8
- utilities/__init__.py +1 -1
- utilities/dataclasses.py +3 -5
- utilities/text.py +80 -7
- utilities/types.py +2 -0
- {dycw_utilities-0.109.24.dist-info → dycw_utilities-0.109.26.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.109.24.dist-info → dycw_utilities-0.109.26.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
utilities/__init__.py,sha256=
|
1
|
+
utilities/__init__.py,sha256=u3bOXUZkUtu44-KigskBo_7SPJ0LgayUw3iTPoGATOo,61
|
2
2
|
utilities/altair.py,sha256=Gpja-flOo-Db0PIPJLJsgzAlXWoKUjPU1qY-DQ829ek,9156
|
3
3
|
utilities/astor.py,sha256=xuDUkjq0-b6fhtwjhbnebzbqQZAjMSHR1IIS5uOodVg,777
|
4
4
|
utilities/asyncio.py,sha256=41oQUurWMvadFK5gFnaG21hMM0Vmfn2WS6OpC0R9mas,14757
|
@@ -11,7 +11,7 @@ utilities/contextlib.py,sha256=OOIIEa5lXKGzFAnauaul40nlQnQko6Na4ryiMJcHkIg,478
|
|
11
11
|
utilities/contextvars.py,sha256=RsSGGrbQqqZ67rOydnM7WWIsM2lIE31UHJLejnHJPWY,505
|
12
12
|
utilities/cryptography.py,sha256=HyOewI20cl3uRXsKivhIaeLVDInQdzgXZGaly7hS5dE,771
|
13
13
|
utilities/cvxpy.py,sha256=Rv1-fD-XYerosCavRF8Pohop2DBkU3AlFaGTfD8AEAA,13776
|
14
|
-
utilities/dataclasses.py,sha256=
|
14
|
+
utilities/dataclasses.py,sha256=8-38WHrScAvElBNvFxBnhJwab1XXkSXpDOiNPOAvh2Q,23295
|
15
15
|
utilities/datetime.py,sha256=GOs-MIEW_A49kzqa1yhIoeNeSqqPVgGO-h2AThtgTDk,37326
|
16
16
|
utilities/enum.py,sha256=HoRwVCWzsnH0vpO9ZEcAAIZLMv0Sn2vJxxA4sYMQgDs,5793
|
17
17
|
utilities/errors.py,sha256=BtSNP0JC3ik536ddPyTerLomCRJV9f6kdMe6POz0QHM,361
|
@@ -73,11 +73,11 @@ utilities/streamlit.py,sha256=U9PJBaKP1IdSykKhPZhIzSPTZsmLsnwbEPZWzNhJPKk,2955
|
|
73
73
|
utilities/sys.py,sha256=h0Xr7Vj86wNalvwJVP1wj5Y0kD_VWm1vzuXZ_jw94mE,2743
|
74
74
|
utilities/tempfile.py,sha256=VqmZJAhTJ1OaVywFzk5eqROV8iJbW9XQ_QYAV0bpdRo,1384
|
75
75
|
utilities/tenacity.py,sha256=1PUvODiBVgeqIh7G5TRt5WWMSqjLYkEqP53itT97WQc,4914
|
76
|
-
utilities/text.py,sha256=
|
76
|
+
utilities/text.py,sha256=Ax_n-nY80_onWxag9M0PkmbaAqwyut9AEA9tEMd5lBs,6694
|
77
77
|
utilities/threading.py,sha256=GvBOp4CyhHfN90wGXZuA2VKe9fGzMaEa7oCl4f3nnPU,1009
|
78
78
|
utilities/timer.py,sha256=Rkc49KSpHuC8s7vUxGO9DU55U9I6yDKnchsQqrUCVBs,4075
|
79
79
|
utilities/traceback.py,sha256=KwHPLdEbdj0fFhXo8MBfxcvem8A-VXYDwFMNJ6f0cTM,27328
|
80
|
-
utilities/types.py,sha256=
|
80
|
+
utilities/types.py,sha256=z1hbBOT5TkzTn2JOvSldw6DScxi3erG9qpJ3xci66GI,17963
|
81
81
|
utilities/typing.py,sha256=gLg4EbE1FX52fJ1d3ji4i08qolwu9qgWt8w_w_Y5DTk,5512
|
82
82
|
utilities/tzdata.py,sha256=2ZsPmhTVM9Ptrxb4QrWKtKOB9RiH8IOO-A1u7ULdVbg,176
|
83
83
|
utilities/tzlocal.py,sha256=42BCquGF54oIqIKe5RGziP4K8Nbm3Ey7uqcNn6m5ge8,534
|
@@ -87,7 +87,7 @@ utilities/warnings.py,sha256=yUgjnmkCRf6QhdyAXzl7u0qQFejhQG3PrjoSwxpbHrs,1819
|
|
87
87
|
utilities/whenever.py,sha256=TjoTAJ1R27-rKXiXzdE4GzPidmYqm0W58XydDXp-QZM,17786
|
88
88
|
utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
|
89
89
|
utilities/zoneinfo.py,sha256=-DQz5a0Ikw9jfSZtL0BEQkXOMC9yGn_xiJYNCLMiqEc,1989
|
90
|
-
dycw_utilities-0.109.
|
91
|
-
dycw_utilities-0.109.
|
92
|
-
dycw_utilities-0.109.
|
93
|
-
dycw_utilities-0.109.
|
90
|
+
dycw_utilities-0.109.26.dist-info/METADATA,sha256=aJEgBNp03JxSJvRWENUjCb_0CqvmCZktjl1S-XNYfDQ,13005
|
91
|
+
dycw_utilities-0.109.26.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
92
|
+
dycw_utilities-0.109.26.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
|
93
|
+
dycw_utilities-0.109.26.dist-info/RECORD,,
|
utilities/__init__.py
CHANGED
utilities/dataclasses.py
CHANGED
@@ -24,7 +24,7 @@ from utilities.iterables import OneStrEmptyError, OneStrNonUniqueError, one_str
|
|
24
24
|
from utilities.operator import is_equal
|
25
25
|
from utilities.parse import ParseTextError, parse_text
|
26
26
|
from utilities.sentinel import Sentinel, sentinel
|
27
|
-
from utilities.types import ParseTextExtra, TDataclass
|
27
|
+
from utilities.types import ParseTextExtra, StrStrMapping, TDataclass
|
28
28
|
from utilities.typing import get_type_hints
|
29
29
|
|
30
30
|
if TYPE_CHECKING:
|
@@ -444,7 +444,7 @@ class StrMappingToFieldMappingError(Exception):
|
|
444
444
|
|
445
445
|
|
446
446
|
def text_to_dataclass(
|
447
|
-
text_or_mapping: str |
|
447
|
+
text_or_mapping: str | StrStrMapping,
|
448
448
|
cls: type[TDataclass],
|
449
449
|
/,
|
450
450
|
*,
|
@@ -499,9 +499,7 @@ def text_to_dataclass(
|
|
499
499
|
)
|
500
500
|
|
501
501
|
|
502
|
-
def _text_to_dataclass_split_text(
|
503
|
-
text: str, cls: type[TDataclass], /
|
504
|
-
) -> Mapping[str, str]:
|
502
|
+
def _text_to_dataclass_split_text(text: str, cls: type[TDataclass], /) -> StrStrMapping:
|
505
503
|
pairs = (t for t in text.split(",") if t != "")
|
506
504
|
return dict(_text_to_dataclass_split_key_value_pair(pair, cls) for pair in pairs)
|
507
505
|
|
utilities/text.py
CHANGED
@@ -6,8 +6,13 @@ from re import IGNORECASE, Match, search
|
|
6
6
|
from textwrap import dedent
|
7
7
|
from typing import TYPE_CHECKING, Any, Literal, overload, override
|
8
8
|
|
9
|
+
from utilities.iterables import CheckDuplicatesError, check_duplicates
|
10
|
+
from utilities.reprlib import get_repr
|
11
|
+
|
9
12
|
if TYPE_CHECKING:
|
10
|
-
from collections.abc import Iterable, Sequence
|
13
|
+
from collections.abc import Iterable, Mapping, Sequence
|
14
|
+
|
15
|
+
from utilities.types import StrStrMapping
|
11
16
|
|
12
17
|
|
13
18
|
def parse_bool(text: str, /) -> bool:
|
@@ -81,14 +86,81 @@ def _snake_case_title(match: Match[str], /) -> str:
|
|
81
86
|
##
|
82
87
|
|
83
88
|
|
89
|
+
@overload
|
90
|
+
def split_key_value_pairs(
|
91
|
+
text: str,
|
92
|
+
/,
|
93
|
+
*,
|
94
|
+
list_separator: str = ",",
|
95
|
+
pair_separator: str = "=",
|
96
|
+
mapping: Literal[True],
|
97
|
+
) -> StrStrMapping: ...
|
98
|
+
@overload
|
99
|
+
def split_key_value_pairs(
|
100
|
+
text: str,
|
101
|
+
/,
|
102
|
+
*,
|
103
|
+
list_separator: str = ",",
|
104
|
+
pair_separator: str = "=",
|
105
|
+
mapping: Literal[False] = False,
|
106
|
+
) -> Sequence[tuple[str, str]]: ...
|
107
|
+
@overload
|
108
|
+
def split_key_value_pairs(
|
109
|
+
text: str,
|
110
|
+
/,
|
111
|
+
*,
|
112
|
+
list_separator: str = ",",
|
113
|
+
pair_separator: str = "=",
|
114
|
+
mapping: bool = False,
|
115
|
+
) -> Sequence[tuple[str, str]] | StrStrMapping: ...
|
84
116
|
def split_key_value_pairs(
|
85
|
-
text: str,
|
86
|
-
|
117
|
+
text: str,
|
118
|
+
/,
|
119
|
+
*,
|
120
|
+
list_separator: str = ",",
|
121
|
+
pair_separator: str = "=",
|
122
|
+
mapping: bool = False,
|
123
|
+
) -> Sequence[tuple[str, str]] | StrStrMapping:
|
87
124
|
"""Split a string into key-value pairs."""
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
125
|
+
try:
|
126
|
+
pairs = [
|
127
|
+
split_str(text_i, separator=pair_separator, n=2)
|
128
|
+
for text_i in split_str(text, separator=list_separator)
|
129
|
+
]
|
130
|
+
except SplitStrError as error:
|
131
|
+
raise _SplitKeyValuePairsSplitError(text=text, inner=error.text) from None
|
132
|
+
if not mapping:
|
133
|
+
return pairs
|
134
|
+
try:
|
135
|
+
check_duplicates(k for k, _ in pairs)
|
136
|
+
except CheckDuplicatesError as error:
|
137
|
+
raise _SplitKeyValuePairsDuplicateKeysError(
|
138
|
+
text=text, counts=error.counts
|
139
|
+
) from None
|
140
|
+
return dict(pairs)
|
141
|
+
|
142
|
+
|
143
|
+
@dataclass(kw_only=True, slots=True)
|
144
|
+
class SplitKeyValuePairsError(Exception):
|
145
|
+
text: str
|
146
|
+
|
147
|
+
|
148
|
+
@dataclass(kw_only=True, slots=True)
|
149
|
+
class _SplitKeyValuePairsSplitError(SplitKeyValuePairsError):
|
150
|
+
inner: str
|
151
|
+
|
152
|
+
@override
|
153
|
+
def __str__(self) -> str:
|
154
|
+
return f"Unable to split {self.text!r} into key-value pairs; got {self.inner!r}"
|
155
|
+
|
156
|
+
|
157
|
+
@dataclass(kw_only=True, slots=True)
|
158
|
+
class _SplitKeyValuePairsDuplicateKeysError(SplitKeyValuePairsError):
|
159
|
+
counts: Mapping[str, int]
|
160
|
+
|
161
|
+
@override
|
162
|
+
def __str__(self) -> str:
|
163
|
+
return f"Unable to split {self.text!r} into a mapping since there are duplicate keys; got {get_repr(self.counts)}"
|
92
164
|
|
93
165
|
|
94
166
|
##
|
@@ -182,6 +254,7 @@ def strip_and_dedent(text: str, /, *, trailing: bool = False) -> str:
|
|
182
254
|
__all__ = [
|
183
255
|
"ParseBoolError",
|
184
256
|
"ParseNoneError",
|
257
|
+
"SplitKeyValuePairsError",
|
185
258
|
"SplitStrError",
|
186
259
|
"join_strs",
|
187
260
|
"parse_bool",
|
utilities/types.py
CHANGED
@@ -46,6 +46,7 @@ type OpenMode = Literal[
|
|
46
46
|
"a+b",
|
47
47
|
]
|
48
48
|
type StrMapping = Mapping[str, Any]
|
49
|
+
type StrStrMapping = Mapping[str, str]
|
49
50
|
type TupleOrStrMapping = tuple[Any, ...] | StrMapping
|
50
51
|
type MaybeCallable[_T] = _T | Callable[[], _T]
|
51
52
|
type MaybeStr[_T] = _T | str
|
@@ -288,6 +289,7 @@ __all__ = [
|
|
288
289
|
"RoundMode",
|
289
290
|
"Seed",
|
290
291
|
"StrMapping",
|
292
|
+
"StrStrMapping",
|
291
293
|
"SupportsAbs",
|
292
294
|
"SupportsAdd",
|
293
295
|
"SupportsBytes",
|
File without changes
|
File without changes
|