dycw-utilities 0.110.2__py3-none-any.whl → 0.110.3__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.110.2
3
+ Version: 0.110.3
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -1,4 +1,4 @@
1
- utilities/__init__.py,sha256=N5L_-mBy__dabTcP63GXeZ0UmhNEqKjJ0SR5XKVgg5Y,60
1
+ utilities/__init__.py,sha256=SPilOBQUT3LssunOfCSklrHeCvASfNJWhSufL04nwh8,60
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=e2YuCj1DF4eecFFxsu20MknghXJ4SNkWCmbIAOXXr18,25942
14
+ utilities/dataclasses.py,sha256=pIRUFMD9JDrwudl16w4a242hoM4A6kCQqirUfsYRcL0,25925
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
@@ -41,7 +41,7 @@ utilities/operator.py,sha256=0M2yZJ0PODH47ogFEnkGMBe_cfxwZR02T_92LZVZvHo,3715
41
41
  utilities/optuna.py,sha256=loyJGWTzljgdJaoLhP09PT8Jz6o_pwBOwehY33lHkhw,1923
42
42
  utilities/orjson.py,sha256=Wj5pzG_VdgoAy14a7Luhem-BgYrRtRFvvl_POiszRd0,36930
43
43
  utilities/os.py,sha256=D_FyyT-6TtqiN9KSS7c9g1fnUtgxmyMtzAjmYLkk46A,3587
44
- utilities/parse.py,sha256=wxqh4YwBfQ7nm249-F_6uqiLo1js9_xji9AVvUxZ5nI,17091
44
+ utilities/parse.py,sha256=RRRTu3TOTDWiO-vVjP6VIg5Z-BojN2dRwPHQGxDQCGg,17758
45
45
  utilities/pathlib.py,sha256=31WPMXdLIyXgYOMMl_HOI2wlo66MGSE-cgeelk-Lias,1410
46
46
  utilities/period.py,sha256=ikHXsWtDLr553cfH6p9mMaiCnIAP69B7q84ckWV3HaA,10884
47
47
  utilities/pickle.py,sha256=Bhvd7cZl-zQKQDFjUerqGuSKlHvnW1K2QXeU5UZibtg,657
@@ -73,7 +73,7 @@ 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=VcNAJtjA2BOGEVY6yXnC9UIAsgECgiWCQ_QnpilZV2o,10089
76
+ utilities/text.py,sha256=0rdjh4_qqGf_wbJyCKQDIbqrb0fQRke2pJEEr_TAWoM,10918
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
@@ -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.110.2.dist-info/METADATA,sha256=TK9SINDsRCnIKjF2YyzOvlQ5mTpD1hjJJ6SD_aNKFI4,13004
91
- dycw_utilities-0.110.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
- dycw_utilities-0.110.2.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
93
- dycw_utilities-0.110.2.dist-info/RECORD,,
90
+ dycw_utilities-0.110.3.dist-info/METADATA,sha256=0rjOLcXZr0om0AtgTlgw0_4Zh_Lbh8k7ic_EqfmwP5s,13004
91
+ dycw_utilities-0.110.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
+ dycw_utilities-0.110.3.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
93
+ dycw_utilities-0.110.3.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.110.2"
3
+ __version__ = "0.110.3"
utilities/dataclasses.py CHANGED
@@ -21,15 +21,11 @@ from utilities.functions import (
21
21
  )
22
22
  from utilities.iterables import OneStrEmptyError, OneStrNonUniqueError, one_str
23
23
  from utilities.operator import is_equal
24
- from utilities.parse import (
25
- LIST_SEPARATOR,
26
- PAIR_SEPARATOR,
27
- ParseObjectError,
28
- parse_object,
29
- serialize_object,
30
- )
24
+ from utilities.parse import ParseObjectError, parse_object, serialize_object
31
25
  from utilities.sentinel import Sentinel, sentinel
32
26
  from utilities.text import (
27
+ LIST_SEPARATOR,
28
+ PAIR_SEPARATOR,
33
29
  _SplitKeyValuePairsDuplicateKeysError,
34
30
  _SplitKeyValuePairsSplitError,
35
31
  join_strs,
utilities/parse.py CHANGED
@@ -20,6 +20,9 @@ from utilities.math import ParseNumberError, parse_number
20
20
  from utilities.re import ExtractGroupError, extract_group
21
21
  from utilities.sentinel import ParseSentinelError, Sentinel, parse_sentinel
22
22
  from utilities.text import (
23
+ BRACKETS,
24
+ LIST_SEPARATOR,
25
+ PAIR_SEPARATOR,
23
26
  ParseBoolError,
24
27
  ParseNoneError,
25
28
  join_strs,
@@ -43,14 +46,10 @@ from utilities.typing import (
43
46
  from utilities.version import ParseVersionError, Version, parse_version
44
47
 
45
48
  if TYPE_CHECKING:
46
- from collections.abc import Mapping, Sequence
49
+ from collections.abc import Iterable, Mapping, Sequence
47
50
  from collections.abc import Set as AbstractSet
48
51
 
49
52
 
50
- LIST_SEPARATOR = ","
51
- PAIR_SEPARATOR = "="
52
-
53
-
54
53
  def parse_object(
55
54
  type_: Any,
56
55
  text: str,
@@ -58,6 +57,7 @@ def parse_object(
58
57
  *,
59
58
  list_separator: str = LIST_SEPARATOR,
60
59
  pair_separator: str = PAIR_SEPARATOR,
60
+ brackets: Iterable[tuple[str, str]] | None = BRACKETS,
61
61
  head: bool = False,
62
62
  case_sensitive: bool = False,
63
63
  extra: ParseObjectExtra | None = None,
@@ -78,6 +78,7 @@ def parse_object(
78
78
  text,
79
79
  list_separator=list_separator,
80
80
  pair_separator=pair_separator,
81
+ brackets=brackets,
81
82
  head=head,
82
83
  case_sensitive=case_sensitive,
83
84
  extra=extra,
@@ -89,6 +90,7 @@ def parse_object(
89
90
  text,
90
91
  list_separator=list_separator,
91
92
  pair_separator=pair_separator,
93
+ brackets=brackets,
92
94
  head=head,
93
95
  case_sensitive=case_sensitive,
94
96
  extra=extra,
@@ -100,6 +102,7 @@ def parse_object(
100
102
  text,
101
103
  list_separator=list_separator,
102
104
  pair_separator=pair_separator,
105
+ brackets=brackets,
103
106
  head=head,
104
107
  case_sensitive=case_sensitive,
105
108
  extra=extra,
@@ -116,6 +119,7 @@ def parse_object(
116
119
  text,
117
120
  list_separator=list_separator,
118
121
  pair_separator=pair_separator,
122
+ brackets=brackets,
119
123
  head=head,
120
124
  case_sensitive=case_sensitive,
121
125
  extra=extra,
@@ -128,6 +132,7 @@ def parse_object(
128
132
  text,
129
133
  list_separator=list_separator,
130
134
  pair_separator=pair_separator,
135
+ brackets=brackets,
131
136
  head=head,
132
137
  case_sensitive=case_sensitive,
133
138
  extra=extra,
@@ -138,6 +143,7 @@ def parse_object(
138
143
  text,
139
144
  list_separator=list_separator,
140
145
  pair_separator=pair_separator,
146
+ brackets=brackets,
141
147
  head=head,
142
148
  case_sensitive=case_sensitive,
143
149
  extra=extra,
@@ -244,6 +250,7 @@ def _parse_object_dict_type(
244
250
  *,
245
251
  list_separator: str = LIST_SEPARATOR,
246
252
  pair_separator: str = PAIR_SEPARATOR,
253
+ brackets: Iterable[tuple[str, str]] | None = BRACKETS,
247
254
  head: bool = False,
248
255
  case_sensitive: bool = False,
249
256
  extra: ParseObjectExtra | None = None,
@@ -257,6 +264,7 @@ def _parse_object_dict_type(
257
264
  inner_text,
258
265
  list_separator=list_separator,
259
266
  pair_separator=pair_separator,
267
+ brackets=brackets,
260
268
  mapping=True,
261
269
  )
262
270
  keys = (
@@ -265,6 +273,7 @@ def _parse_object_dict_type(
265
273
  k,
266
274
  list_separator=list_separator,
267
275
  pair_separator=pair_separator,
276
+ brackets=brackets,
268
277
  head=head,
269
278
  case_sensitive=case_sensitive,
270
279
  extra=extra,
@@ -277,6 +286,7 @@ def _parse_object_dict_type(
277
286
  v,
278
287
  list_separator=list_separator,
279
288
  pair_separator=pair_separator,
289
+ brackets=brackets,
280
290
  head=head,
281
291
  case_sensitive=case_sensitive,
282
292
  extra=extra,
@@ -296,6 +306,7 @@ def _parse_object_list_type(
296
306
  *,
297
307
  list_separator: str = LIST_SEPARATOR,
298
308
  pair_separator: str = PAIR_SEPARATOR,
309
+ brackets: Iterable[tuple[str, str]] | None = BRACKETS,
299
310
  head: bool = False,
300
311
  case_sensitive: bool = False,
301
312
  extra: ParseObjectExtra | None = None,
@@ -313,6 +324,7 @@ def _parse_object_list_type(
313
324
  t,
314
325
  list_separator=list_separator,
315
326
  pair_separator=pair_separator,
327
+ brackets=brackets,
316
328
  head=head,
317
329
  case_sensitive=case_sensitive,
318
330
  extra=extra,
@@ -330,6 +342,7 @@ def _parse_object_set_type(
330
342
  *,
331
343
  list_separator: str = LIST_SEPARATOR,
332
344
  pair_separator: str = PAIR_SEPARATOR,
345
+ brackets: Iterable[tuple[str, str]] | None = BRACKETS,
333
346
  head: bool = False,
334
347
  case_sensitive: bool = False,
335
348
  extra: ParseObjectExtra | None = None,
@@ -347,6 +360,7 @@ def _parse_object_set_type(
347
360
  t,
348
361
  list_separator=list_separator,
349
362
  pair_separator=pair_separator,
363
+ brackets=brackets,
350
364
  head=head,
351
365
  case_sensitive=case_sensitive,
352
366
  extra=extra,
@@ -389,6 +403,7 @@ def _parse_object_tuple_type(
389
403
  *,
390
404
  list_separator: str = LIST_SEPARATOR,
391
405
  pair_separator: str = PAIR_SEPARATOR,
406
+ brackets: Iterable[tuple[str, str]] | None = BRACKETS,
392
407
  head: bool = False,
393
408
  case_sensitive: bool = False,
394
409
  extra: ParseObjectExtra | None = None,
@@ -408,6 +423,7 @@ def _parse_object_tuple_type(
408
423
  text,
409
424
  list_separator=list_separator,
410
425
  pair_separator=pair_separator,
426
+ brackets=brackets,
411
427
  head=head,
412
428
  case_sensitive=case_sensitive,
413
429
  extra=extra,
@@ -569,4 +585,4 @@ def _serialize_object_tuple(
569
585
  return f"({joined})"
570
586
 
571
587
 
572
- __all__ = ["LIST_SEPARATOR", "PAIR_SEPARATOR", "parse_object", "serialize_object"]
588
+ __all__ = ["parse_object", "serialize_object"]
utilities/text.py CHANGED
@@ -17,6 +17,12 @@ if TYPE_CHECKING:
17
17
  from utilities.types import StrStrMapping
18
18
 
19
19
 
20
+ DEFAULT_SEPARATOR = ","
21
+
22
+
23
+ ##
24
+
25
+
20
26
  def parse_bool(text: str, /) -> bool:
21
27
  """Parse text into a boolean value."""
22
28
  if text == "0" or search("false", text, flags=IGNORECASE):
@@ -88,13 +94,19 @@ def _snake_case_title(match: Match[str], /) -> str:
88
94
  ##
89
95
 
90
96
 
97
+ LIST_SEPARATOR = DEFAULT_SEPARATOR
98
+ PAIR_SEPARATOR = "="
99
+ BRACKETS = [("(", ")"), ("[", "]"), ("{", "}")]
100
+
101
+
91
102
  @overload
92
103
  def split_key_value_pairs(
93
104
  text: str,
94
105
  /,
95
106
  *,
96
- list_separator: str = ",",
97
- pair_separator: str = "=",
107
+ list_separator: str = DEFAULT_SEPARATOR,
108
+ pair_separator: str = PAIR_SEPARATOR,
109
+ brackets: Iterable[tuple[str, str]] | None = BRACKETS,
98
110
  mapping: Literal[True],
99
111
  ) -> StrStrMapping: ...
100
112
  @overload
@@ -102,8 +114,9 @@ def split_key_value_pairs(
102
114
  text: str,
103
115
  /,
104
116
  *,
105
- list_separator: str = ",",
106
- pair_separator: str = "=",
117
+ list_separator: str = DEFAULT_SEPARATOR,
118
+ pair_separator: str = PAIR_SEPARATOR,
119
+ brackets: Iterable[tuple[str, str]] | None = BRACKETS,
107
120
  mapping: Literal[False] = False,
108
121
  ) -> Sequence[tuple[str, str]]: ...
109
122
  @overload
@@ -111,24 +124,27 @@ def split_key_value_pairs(
111
124
  text: str,
112
125
  /,
113
126
  *,
114
- list_separator: str = ",",
115
- pair_separator: str = "=",
127
+ list_separator: str = DEFAULT_SEPARATOR,
128
+ pair_separator: str = PAIR_SEPARATOR,
129
+ brackets: Iterable[tuple[str, str]] | None = BRACKETS,
116
130
  mapping: bool = False,
117
131
  ) -> Sequence[tuple[str, str]] | StrStrMapping: ...
118
132
  def split_key_value_pairs(
119
133
  text: str,
120
134
  /,
121
135
  *,
122
- list_separator: str = ",",
123
- pair_separator: str = "=",
136
+ list_separator: str = DEFAULT_SEPARATOR,
137
+ pair_separator: str = PAIR_SEPARATOR,
138
+ brackets: Iterable[tuple[str, str]] | None = BRACKETS,
124
139
  mapping: bool = False,
125
140
  ) -> Sequence[tuple[str, str]] | StrStrMapping:
126
141
  """Split a string into key-value pairs."""
127
142
  try:
128
- pairs = [
129
- split_str(text_i, separator=pair_separator, n=2)
130
- for text_i in split_str(text, separator=list_separator)
131
- ]
143
+ texts = split_str(text, separator=list_separator, brackets=brackets)
144
+ except SplitStrError as error:
145
+ raise _SplitKeyValuePairsSplitError(text=text, inner=error.text) from None
146
+ try:
147
+ pairs = [split_str(text_i, separator=pair_separator, n=2) for text_i in texts]
132
148
  except SplitStrError as error:
133
149
  raise _SplitKeyValuePairsSplitError(text=text, inner=error.text) from None
134
150
  if not mapping:
@@ -153,7 +169,7 @@ class _SplitKeyValuePairsSplitError(SplitKeyValuePairsError):
153
169
 
154
170
  @override
155
171
  def __str__(self) -> str:
156
- return f"Unable to split {self.text!r} into key-value pairs; got {self.inner!r}"
172
+ return f"Unable to split {self.text!r} into key-value pairs"
157
173
 
158
174
 
159
175
  @dataclass(kw_only=True, slots=True)
@@ -173,7 +189,7 @@ def split_str(
173
189
  text: str,
174
190
  /,
175
191
  *,
176
- separator: str = ",",
192
+ separator: str = DEFAULT_SEPARATOR,
177
193
  brackets: Iterable[tuple[str, str]] | None = None,
178
194
  n: Literal[1],
179
195
  ) -> tuple[str]: ...
@@ -182,7 +198,7 @@ def split_str(
182
198
  text: str,
183
199
  /,
184
200
  *,
185
- separator: str = ",",
201
+ separator: str = DEFAULT_SEPARATOR,
186
202
  brackets: Iterable[tuple[str, str]] | None = None,
187
203
  n: Literal[2],
188
204
  ) -> tuple[str, str]: ...
@@ -191,7 +207,7 @@ def split_str(
191
207
  text: str,
192
208
  /,
193
209
  *,
194
- separator: str = ",",
210
+ separator: str = DEFAULT_SEPARATOR,
195
211
  brackets: Iterable[tuple[str, str]] | None = None,
196
212
  n: Literal[3],
197
213
  ) -> tuple[str, str, str]: ...
@@ -200,7 +216,7 @@ def split_str(
200
216
  text: str,
201
217
  /,
202
218
  *,
203
- separator: str = ",",
219
+ separator: str = DEFAULT_SEPARATOR,
204
220
  brackets: Iterable[tuple[str, str]] | None = None,
205
221
  n: Literal[4],
206
222
  ) -> tuple[str, str, str, str]: ...
@@ -209,7 +225,7 @@ def split_str(
209
225
  text: str,
210
226
  /,
211
227
  *,
212
- separator: str = ",",
228
+ separator: str = DEFAULT_SEPARATOR,
213
229
  brackets: Iterable[tuple[str, str]] | None = None,
214
230
  n: Literal[5],
215
231
  ) -> tuple[str, str, str, str, str]: ...
@@ -218,7 +234,7 @@ def split_str(
218
234
  text: str,
219
235
  /,
220
236
  *,
221
- separator: str = ",",
237
+ separator: str = DEFAULT_SEPARATOR,
222
238
  brackets: Iterable[tuple[str, str]] | None = None,
223
239
  n: int | None = None,
224
240
  ) -> Sequence[str]: ...
@@ -226,7 +242,7 @@ def split_str(
226
242
  text: str,
227
243
  /,
228
244
  *,
229
- separator: str = ",",
245
+ separator: str = DEFAULT_SEPARATOR,
230
246
  brackets: Iterable[tuple[str, str]] | None = None,
231
247
  n: int | None = None,
232
248
  ) -> Sequence[str]:
@@ -247,7 +263,11 @@ def split_str(
247
263
 
248
264
 
249
265
  def _split_str_brackets(
250
- text: str, brackets: Iterable[tuple[str, str]], /, *, separator: str = ","
266
+ text: str,
267
+ brackets: Iterable[tuple[str, str]],
268
+ /,
269
+ *,
270
+ separator: str = DEFAULT_SEPARATOR,
251
271
  ) -> Sequence[str]:
252
272
  brackets = list(brackets)
253
273
  opens, closes = transpose(brackets)
@@ -338,7 +358,7 @@ class _SplitStrOpeningBracketUnmatchedError(SplitStrError):
338
358
 
339
359
 
340
360
  def join_strs(
341
- texts: Iterable[str], /, *, sort: bool = False, separator: str = ","
361
+ texts: Iterable[str], /, *, sort: bool = False, separator: str = DEFAULT_SEPARATOR
342
362
  ) -> str:
343
363
  """Join a collection of strings, with a special provision for the empty list."""
344
364
  texts = list(texts)
@@ -351,7 +371,7 @@ def join_strs(
351
371
  return separator.join(texts)
352
372
 
353
373
 
354
- def _escape_separator(*, separator: str = ",") -> str:
374
+ def _escape_separator(*, separator: str = DEFAULT_SEPARATOR) -> str:
355
375
  return f"\\{separator}"
356
376
 
357
377
 
@@ -373,6 +393,10 @@ def strip_and_dedent(text: str, /, *, trailing: bool = False) -> str:
373
393
 
374
394
 
375
395
  __all__ = [
396
+ "BRACKETS",
397
+ "DEFAULT_SEPARATOR",
398
+ "LIST_SEPARATOR",
399
+ "PAIR_SEPARATOR",
376
400
  "ParseBoolError",
377
401
  "ParseNoneError",
378
402
  "SplitKeyValuePairsError",