dycw-utilities 0.112.4__py3-none-any.whl → 0.112.6__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.112.4
3
+ Version: 0.112.6
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=oC8D3yQOhG08zuNGgWDntjiYZO1Ow4YdrihVPBjmoiI,60
1
+ utilities/__init__.py,sha256=d0j_69nmkoIKyb6X7hdJ8nRV6_SJJNH1dwhdMB_yAA8,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=Q197PVnE_vUMn_SNnqJBCo4eRy4bdHtgMHWRbSJPtFk,26670
14
+ utilities/dataclasses.py,sha256=EG2lZRPU_rmkP3KWR7J5J43r8hr68s9uchSvevxpoZI,27433
15
15
  utilities/datetime.py,sha256=OF7jZE702UecnwAbq9D3N-GINpp9gSGoidki1RhimCE,35752
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=DBm2zPP04kcHpY3l1etL24ksNynu-R3duFyx3U-RjqQ,36948
43
43
  utilities/os.py,sha256=D_FyyT-6TtqiN9KSS7c9g1fnUtgxmyMtzAjmYLkk46A,3587
44
- utilities/parse.py,sha256=cdOKqsT9c0dgFuNWzb1E-dqLDJ8kES9YWvPNpQDLySA,18844
44
+ utilities/parse.py,sha256=Qr8hw14v0Bfxnc0TjFfjZtmYk6FrdVoqLnszb7R27BA,18982
45
45
  utilities/pathlib.py,sha256=31WPMXdLIyXgYOMMl_HOI2wlo66MGSE-cgeelk-Lias,1410
46
46
  utilities/period.py,sha256=RWfcNVoNlW07RNdU47g_zuLZMKbtgfK4bE6G-9tVjY8,11024
47
47
  utilities/pickle.py,sha256=Bhvd7cZl-zQKQDFjUerqGuSKlHvnW1K2QXeU5UZibtg,657
@@ -78,7 +78,7 @@ utilities/threading.py,sha256=GvBOp4CyhHfN90wGXZuA2VKe9fGzMaEa7oCl4f3nnPU,1009
78
78
  utilities/timer.py,sha256=Rkc49KSpHuC8s7vUxGO9DU55U9I6yDKnchsQqrUCVBs,4075
79
79
  utilities/traceback.py,sha256=secexUnBsecfWV4ZuqP1W4pGF3prOeO1CRyJK-8zQDU,27402
80
80
  utilities/types.py,sha256=kVY71hZkcnyYNIlYSse0mLm8yeP3OBkzhDPMME6jXxo,18126
81
- utilities/typing.py,sha256=Tppx84LCtZFX8oOzDb2PeUIv9tjNqFWQLuMadN_rAes,13514
81
+ utilities/typing.py,sha256=H6ysJkI830aRwLsMKz0SZIw4cpcsm7d6KhQOwr-SDh0,13817
82
82
  utilities/tzdata.py,sha256=yCf70NICwAeazN3_JcXhWvRqCy06XJNQ42j7r6gw3HY,1217
83
83
  utilities/tzlocal.py,sha256=3upDNFBvGh1l9njmLR2z2S6K6VxQSb7QizYGUbAH3JU,960
84
84
  utilities/uuid.py,sha256=jJTFxz-CWgltqNuzmythB7iEQ-Q1mCwPevUfKthZT3c,611
@@ -87,7 +87,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
87
87
  utilities/whenever.py,sha256=iLRP_-8CZtBpHKbGZGu-kjSMg1ZubJ-VSmgSy7Eudxw,17787
88
88
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
89
89
  utilities/zoneinfo.py,sha256=-Xm57PMMwDTYpxJdkiJG13wnbwK--I7XItBh5WVhD-o,1874
90
- dycw_utilities-0.112.4.dist-info/METADATA,sha256=kt63WFyIE1e7dsPDAxgJfbPryHlzRYSPo_nsFUp8EiI,13004
91
- dycw_utilities-0.112.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
- dycw_utilities-0.112.4.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
93
- dycw_utilities-0.112.4.dist-info/RECORD,,
90
+ dycw_utilities-0.112.6.dist-info/METADATA,sha256=nVSss8zVsLAitA6xDEcurQtsusPov5dkkpgrD9Q-SBI,13004
91
+ dycw_utilities-0.112.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
+ dycw_utilities-0.112.6.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
93
+ dycw_utilities-0.112.6.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.112.4"
3
+ __version__ = "0.112.6"
utilities/dataclasses.py CHANGED
@@ -22,7 +22,12 @@ from utilities.functions import (
22
22
  )
23
23
  from utilities.iterables import OneStrEmptyError, OneStrNonUniqueError, one_str
24
24
  from utilities.operator import is_equal
25
- from utilities.parse import ParseObjectError, parse_object, serialize_object
25
+ from utilities.parse import (
26
+ _ParseObjectExtraNonUniqueError,
27
+ _ParseObjectParseError,
28
+ parse_object,
29
+ serialize_object,
30
+ )
26
31
  from utilities.re import ExtractGroupError, extract_group
27
32
  from utilities.sentinel import Sentinel, sentinel
28
33
  from utilities.text import (
@@ -570,8 +575,12 @@ def _parse_dataclass_parse_text(
570
575
  case_sensitive=case_sensitive,
571
576
  extra=extra,
572
577
  )
573
- except ParseObjectError:
574
- raise _ParseDataClassParseValueError(cls=cls, field=field, text=text) from None
578
+ except _ParseObjectParseError:
579
+ raise _ParseDataClassTextParseError(cls=cls, field=field, text=text) from None
580
+ except _ParseObjectExtraNonUniqueError as error:
581
+ raise _ParseDataClassTextExtraNonUniqueError(
582
+ cls=cls, field=field, text=text, first=error.first, second=error.second
583
+ ) from None
575
584
 
576
585
 
577
586
  @dataclass(kw_only=True, slots=True)
@@ -597,12 +606,23 @@ class _ParseDataClassSplitKeyValuePairsDuplicateKeysError(ParseDataClassError):
597
606
 
598
607
 
599
608
  @dataclass(kw_only=True, slots=True)
600
- class _ParseDataClassParseValueError(ParseDataClassError[TDataclass]):
609
+ class _ParseDataClassTextParseError(ParseDataClassError[TDataclass]):
610
+ field: _YieldFieldsClass[Any]
611
+
612
+ @override
613
+ def __str__(self) -> str:
614
+ return f"Unable to construct {get_class_name(self.cls)!r} since the field {self.field.name!r} of type {self.field.type_!r} could not be parsed; got {self.text!r}"
615
+
616
+
617
+ @dataclass(kw_only=True, slots=True)
618
+ class _ParseDataClassTextExtraNonUniqueError(ParseDataClassError[TDataclass]):
601
619
  field: _YieldFieldsClass[Any]
620
+ first: type[Any]
621
+ second: type[Any]
602
622
 
603
623
  @override
604
624
  def __str__(self) -> str:
605
- return f"Unable to construct {get_class_name(self.cls)!r}; unable to parse field {self.field.name!r} of type {self.field.type_!r}; got {self.text!r}"
625
+ return f"Unable to construct {get_class_name(self.cls)!r} since the field {self.field.name!r} of type {self.field.type_!r} must contain exactly one parent class in `extra`; got {self.first!r}, {self.second!r} and perhaps more"
606
626
 
607
627
 
608
628
  ##
utilities/parse.py CHANGED
@@ -283,17 +283,19 @@ def _parse_object_dict_type(
283
283
 
284
284
  def _parse_object_extra(cls: Any, text: str, extra: ParseObjectExtra, /) -> Any:
285
285
  try:
286
- parser = one(
287
- p for c, p in extra.items() if (cls is c) or is_subclass_gen(cls, c)
288
- )
289
- except (OneEmptyError, TypeError):
290
- raise _ParseObjectParseError(type_=cls, text=text) from None
291
- except OneNonUniqueError as error:
292
- raise _ParseObjectExtraNonUniqueError(
293
- type_=cls, text=text, first=error.first, second=error.second
294
- ) from None
295
- else:
296
- return parser(text)
286
+ parser = extra[cls]
287
+ except KeyError:
288
+ try:
289
+ parser = one(
290
+ p for c, p in extra.items() if (cls is c) or is_subclass_gen(cls, c)
291
+ )
292
+ except (OneEmptyError, TypeError):
293
+ raise _ParseObjectParseError(type_=cls, text=text) from None
294
+ except OneNonUniqueError as error:
295
+ raise _ParseObjectExtraNonUniqueError(
296
+ type_=cls, text=text, first=error.first, second=error.second
297
+ ) from None
298
+ return parser(text)
297
299
 
298
300
 
299
301
  def _parse_object_list_type(
@@ -600,7 +602,7 @@ class SerializeObjectError(Exception):
600
602
  class _SerializeObjectSerializeError(SerializeObjectError):
601
603
  @override
602
604
  def __str__(self) -> str:
603
- return f"Unable to serialize object {self.obj!r}"
605
+ return f"Unable to serialize object {self.obj!r} of type {type(self.obj)!r}"
604
606
 
605
607
 
606
608
  @dataclass
@@ -610,7 +612,7 @@ class _SerializeObjectExtraNonUniqueError(SerializeObjectError):
610
612
 
611
613
  @override
612
614
  def __str__(self) -> str:
613
- return f"Unable to serialize object {self.obj!r} since `extra` must contain exactly one parent class; got {self.first!r}, {self.second!r} and perhaps more"
615
+ return f"Unable to serialize object {self.obj!r} of type {type(self.obj)!r} since `extra` must contain exactly one parent class; got {self.first!r}, {self.second!r} and perhaps more"
614
616
 
615
617
 
616
618
  __all__ = ["parse_object", "serialize_object"]
utilities/typing.py CHANGED
@@ -108,7 +108,7 @@ class GetTypeClassesError(Exception):
108
108
  class _GetTypeClassesTypeError(GetTypeClassesError):
109
109
  @override
110
110
  def __str__(self) -> str:
111
- return f"Object must be a type, tuple or Union type; got {self.obj}"
111
+ return f"Object must be a type, tuple or Union type; got {self.obj!r} of type {type(self.obj)!r}"
112
112
 
113
113
 
114
114
  @dataclass(kw_only=True, slots=True)
@@ -117,7 +117,7 @@ class _GetTypeClassesTupleError(GetTypeClassesError):
117
117
 
118
118
  @override
119
119
  def __str__(self) -> str:
120
- return f"Tuple must contain types, tuples or Union types only; got {self.inner}"
120
+ return f"Tuple must contain types, tuples or Union types only; got {self.inner} of type {type(self.inner)!r}"
121
121
 
122
122
 
123
123
  ##
@@ -177,7 +177,9 @@ class GetUnionTypeClassesError(Exception):
177
177
  class _GetUnionTypeClassesUnionTypeError(GetUnionTypeClassesError):
178
178
  @override
179
179
  def __str__(self) -> str:
180
- return f"Object must be a Union type; got {self.obj}"
180
+ return (
181
+ f"Object must be a Union type; got {self.obj!r} of type {type(self.obj)!r}"
182
+ )
181
183
 
182
184
 
183
185
  @dataclass(kw_only=True, slots=True)
@@ -186,7 +188,7 @@ class _GetUnionTypeClassesInternalTypeError(GetUnionTypeClassesError):
186
188
 
187
189
  @override
188
190
  def __str__(self) -> str:
189
- return f"Union type must contain types only; got {self.inner}"
191
+ return f"Union type must contain types only; got {self.inner} of type {type(self.inner)!r}"
190
192
 
191
193
 
192
194
  ##
@@ -243,6 +245,8 @@ def is_instance_gen(obj: Any, type_: Any, /) -> bool:
243
245
  return (len(obj) == len(type_args)) and all(
244
246
  is_instance_gen(o, t) for o, t in zip(obj, type_args, strict=True)
245
247
  )
248
+ if isinstance(obj, tuple) is not is_tuple_type(type_):
249
+ return False
246
250
  # basic
247
251
  if isinstance(type_, type):
248
252
  return any(_is_instance_gen_type(obj, t) for t in get_type_classes(type_))
@@ -272,7 +276,7 @@ class IsInstanceGenError(Exception):
272
276
 
273
277
  @override
274
278
  def __str__(self) -> str:
275
- return f"Invalid arguments; got {self.obj!r} and {self.type_!r}"
279
+ return f"Invalid arguments; got {self.obj!r} of type {type(self.obj)!r} and {self.type_!r} of type {type(self.type_)!r}"
276
280
 
277
281
 
278
282
  ##
@@ -432,7 +436,7 @@ class IsSubclassGenError(Exception):
432
436
 
433
437
  @override
434
438
  def __str__(self) -> str:
435
- return f"Argument must be a class; got {self.cls!r}"
439
+ return f"Argument must be a class; got {self.cls!r} of type {type(self.cls)!r}"
436
440
 
437
441
 
438
442
  ##