dycw-utilities 0.112.2__py3-none-any.whl → 0.112.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.112.2
3
+ Version: 0.112.4
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -24,7 +24,7 @@ Provides-Extra: zzz-test-altair
24
24
  Requires-Dist: altair<5.6,>=5.5.0; extra == 'zzz-test-altair'
25
25
  Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-altair'
26
26
  Requires-Dist: img2pdf<0.7,>=0.6.0; extra == 'zzz-test-altair'
27
- Requires-Dist: polars-lts-cpu<1.28,>=1.27.1; extra == 'zzz-test-altair'
27
+ Requires-Dist: polars-lts-cpu<1.29,>=1.28.1; extra == 'zzz-test-altair'
28
28
  Requires-Dist: vl-convert-python<1.8,>=1.7.0; extra == 'zzz-test-altair'
29
29
  Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-altair'
30
30
  Provides-Extra: zzz-test-astor
@@ -48,7 +48,7 @@ Provides-Extra: zzz-test-cvxpy
48
48
  Requires-Dist: cvxpy<1.7,>=1.6.5; extra == 'zzz-test-cvxpy'
49
49
  Provides-Extra: zzz-test-dataclasses
50
50
  Requires-Dist: orjson<3.11,>=3.10.15; extra == 'zzz-test-dataclasses'
51
- Requires-Dist: polars-lts-cpu<1.28,>=1.27.1; extra == 'zzz-test-dataclasses'
51
+ Requires-Dist: polars-lts-cpu<1.29,>=1.28.1; extra == 'zzz-test-dataclasses'
52
52
  Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-dataclasses'
53
53
  Provides-Extra: zzz-test-datetime
54
54
  Requires-Dist: tzlocal<5.4,>=5.3.1; extra == 'zzz-test-datetime'
@@ -70,7 +70,7 @@ Provides-Extra: zzz-test-getpass
70
70
  Provides-Extra: zzz-test-git
71
71
  Provides-Extra: zzz-test-hashlib
72
72
  Requires-Dist: orjson<3.11,>=3.10.15; extra == 'zzz-test-hashlib'
73
- Requires-Dist: polars-lts-cpu<1.28,>=1.27.1; extra == 'zzz-test-hashlib'
73
+ Requires-Dist: polars-lts-cpu<1.29,>=1.28.1; extra == 'zzz-test-hashlib'
74
74
  Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-hashlib'
75
75
  Provides-Extra: zzz-test-http
76
76
  Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-http'
@@ -92,12 +92,12 @@ Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-hypothesis'
92
92
  Provides-Extra: zzz-test-ipython
93
93
  Requires-Dist: ipython<9.1,>=9.0.1; extra == 'zzz-test-ipython'
94
94
  Provides-Extra: zzz-test-iterables
95
- Requires-Dist: polars-lts-cpu<1.28,>=1.27.1; extra == 'zzz-test-iterables'
95
+ Requires-Dist: polars-lts-cpu<1.29,>=1.28.1; extra == 'zzz-test-iterables'
96
96
  Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-iterables'
97
97
  Provides-Extra: zzz-test-jupyter
98
98
  Requires-Dist: jupyterlab<4.3,>=4.2.0; extra == 'zzz-test-jupyter'
99
99
  Requires-Dist: pandas<2.3,>=2.2.2; extra == 'zzz-test-jupyter'
100
- Requires-Dist: polars-lts-cpu<1.28,>=1.27.1; extra == 'zzz-test-jupyter'
100
+ Requires-Dist: polars-lts-cpu<1.29,>=1.28.1; extra == 'zzz-test-jupyter'
101
101
  Provides-Extra: zzz-test-logging
102
102
  Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-logging'
103
103
  Requires-Dist: coloredlogs<15.1,>=15.0.1; extra == 'zzz-test-logging'
@@ -121,13 +121,13 @@ Requires-Dist: more-itertools<10.8,>=10.7.0; extra == 'zzz-test-more-itertools'
121
121
  Provides-Extra: zzz-test-numpy
122
122
  Requires-Dist: numpy<2.3,>=2.2.5; extra == 'zzz-test-numpy'
123
123
  Provides-Extra: zzz-test-operator
124
- Requires-Dist: polars-lts-cpu<1.28,>=1.27.1; extra == 'zzz-test-operator'
124
+ Requires-Dist: polars-lts-cpu<1.29,>=1.28.1; extra == 'zzz-test-operator'
125
125
  Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-operator'
126
126
  Provides-Extra: zzz-test-optuna
127
127
  Requires-Dist: optuna<4.4,>=4.3.0; extra == 'zzz-test-optuna'
128
128
  Provides-Extra: zzz-test-orjson
129
129
  Requires-Dist: orjson<3.11,>=3.10.15; extra == 'zzz-test-orjson'
130
- Requires-Dist: polars-lts-cpu<1.28,>=1.27.1; extra == 'zzz-test-orjson'
130
+ Requires-Dist: polars-lts-cpu<1.29,>=1.28.1; extra == 'zzz-test-orjson'
131
131
  Requires-Dist: rich<14.1,>=14.0.0; extra == 'zzz-test-orjson'
132
132
  Requires-Dist: tzlocal<5.4,>=5.3.1; extra == 'zzz-test-orjson'
133
133
  Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-orjson'
@@ -138,7 +138,7 @@ Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-pickle'
138
138
  Provides-Extra: zzz-test-platform
139
139
  Provides-Extra: zzz-test-polars
140
140
  Requires-Dist: dacite<1.10,>=1.9.2; extra == 'zzz-test-polars'
141
- Requires-Dist: polars-lts-cpu<1.28,>=1.27.1; extra == 'zzz-test-polars'
141
+ Requires-Dist: polars-lts-cpu<1.29,>=1.28.1; extra == 'zzz-test-polars'
142
142
  Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-polars'
143
143
  Provides-Extra: zzz-test-pqdm
144
144
  Requires-Dist: pqdm<0.3,>=0.2.0; extra == 'zzz-test-pqdm'
@@ -164,7 +164,7 @@ Provides-Extra: zzz-test-random
164
164
  Provides-Extra: zzz-test-re
165
165
  Provides-Extra: zzz-test-redis
166
166
  Requires-Dist: orjson<3.11,>=3.10.15; extra == 'zzz-test-redis'
167
- Requires-Dist: polars-lts-cpu<1.28,>=1.27.1; extra == 'zzz-test-redis'
167
+ Requires-Dist: polars-lts-cpu<1.29,>=1.28.1; extra == 'zzz-test-redis'
168
168
  Requires-Dist: redis<5.3,>=5.2.1; extra == 'zzz-test-redis'
169
169
  Requires-Dist: rich<14.1,>=14.0.0; extra == 'zzz-test-redis'
170
170
  Requires-Dist: tenacity<9.0,>=8.5.0; extra == 'zzz-test-redis'
@@ -192,7 +192,7 @@ Requires-Dist: aiosqlite<0.22,>=0.21.0; extra == 'zzz-test-sqlalchemy-polars'
192
192
  Requires-Dist: asyncpg<0.31,>=0.30.0; extra == 'zzz-test-sqlalchemy-polars'
193
193
  Requires-Dist: greenlet<3.3,>=3.2.0; extra == 'zzz-test-sqlalchemy-polars'
194
194
  Requires-Dist: nest-asyncio<1.7,>=1.6.0; extra == 'zzz-test-sqlalchemy-polars'
195
- Requires-Dist: polars-lts-cpu<1.28,>=1.27.1; extra == 'zzz-test-sqlalchemy-polars'
195
+ Requires-Dist: polars-lts-cpu<1.29,>=1.28.1; extra == 'zzz-test-sqlalchemy-polars'
196
196
  Requires-Dist: sqlalchemy<2.1,>=2.0.40; extra == 'zzz-test-sqlalchemy-polars'
197
197
  Requires-Dist: tenacity<9.0,>=8.5.0; extra == 'zzz-test-sqlalchemy-polars'
198
198
  Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-sqlalchemy-polars'
@@ -217,7 +217,7 @@ Requires-Dist: tzlocal<5.4,>=5.3.1; extra == 'zzz-test-traceback'
217
217
  Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-traceback'
218
218
  Provides-Extra: zzz-test-types
219
219
  Provides-Extra: zzz-test-typing
220
- Requires-Dist: polars-lts-cpu<1.28,>=1.27.1; extra == 'zzz-test-typing'
220
+ Requires-Dist: polars-lts-cpu<1.29,>=1.28.1; extra == 'zzz-test-typing'
221
221
  Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-typing'
222
222
  Provides-Extra: zzz-test-tzlocal
223
223
  Requires-Dist: tzlocal<5.4,>=5.3.1; extra == 'zzz-test-tzlocal'
@@ -1,4 +1,4 @@
1
- utilities/__init__.py,sha256=YIZTcfeQmna9ccW7NIqZzcDB03vFiy0xoZl-xVKVNg4,60
1
+ utilities/__init__.py,sha256=oC8D3yQOhG08zuNGgWDntjiYZO1Ow4YdrihVPBjmoiI,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
@@ -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=i_Ajb8UAOplnhrezb2zk4JaXtUyE0nUyaPR5o9j4YNc,12869
81
+ utilities/typing.py,sha256=Tppx84LCtZFX8oOzDb2PeUIv9tjNqFWQLuMadN_rAes,13514
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.2.dist-info/METADATA,sha256=QmNVwMJdLQtljfZmV0Mg0zLgFYogVdVymaaF1QuOxrc,13004
91
- dycw_utilities-0.112.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
- dycw_utilities-0.112.2.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
93
- dycw_utilities-0.112.2.dist-info/RECORD,,
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,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.112.2"
3
+ __version__ = "0.112.4"
utilities/typing.py CHANGED
@@ -230,21 +230,23 @@ def is_instance_gen(
230
230
  def is_instance_gen(obj: Any, type_: Any, /) -> bool: ...
231
231
  def is_instance_gen(obj: Any, type_: Any, /) -> bool:
232
232
  """Check if an instance relationship holds, except bool<int."""
233
- if isinstance(obj, tuple) and isinstance(type_, tuple):
234
- return _is_instance_gen_tuple(obj, type_)
233
+ # parent
234
+ if isinstance(type_, tuple):
235
+ return any(is_instance_gen(obj, t) for t in type_)
235
236
  if is_literal_type(type_):
236
- return _is_instance_gen_literal(obj, type_)
237
- return any(_is_instance_gen_type(obj, t) for t in get_type_classes(type_))
238
-
239
-
240
- def _is_instance_gen_tuple(obj: tuple[Any, ...], type_: tuple[Any, ...], /) -> bool:
241
- return (len(obj) == len(type_)) and all(
242
- is_instance_gen(o, t) for o, t in zip(obj, type_, strict=True)
243
- )
244
-
245
-
246
- def _is_instance_gen_literal(obj: Any, type_: type[_T], /) -> TypeGuard[_T]:
247
- return obj in get_args(type_)
237
+ return obj in get_args(type_)
238
+ if is_union_type(type_):
239
+ return any(is_instance_gen(obj, t) for t in get_args(type_))
240
+ # tuple vs tuple
241
+ if isinstance(obj, tuple) and is_tuple_type(type_):
242
+ type_args = get_args(type_)
243
+ return (len(obj) == len(type_args)) and all(
244
+ is_instance_gen(o, t) for o, t in zip(obj, type_args, strict=True)
245
+ )
246
+ # basic
247
+ if isinstance(type_, type):
248
+ return any(_is_instance_gen_type(obj, t) for t in get_type_classes(type_))
249
+ raise IsInstanceGenError(obj=obj, type_=type_)
248
250
 
249
251
 
250
252
  def _is_instance_gen_type(obj: Any, type_: type[_T], /) -> TypeGuard[_T]:
@@ -263,6 +265,16 @@ def _is_instance_gen_type(obj: Any, type_: type[_T], /) -> TypeGuard[_T]:
263
265
  )
264
266
 
265
267
 
268
+ @dataclass(kw_only=True, slots=True)
269
+ class IsInstanceGenError(Exception):
270
+ obj: Any
271
+ type_: Any
272
+
273
+ @override
274
+ def __str__(self) -> str:
275
+ return f"Invalid arguments; got {self.obj!r} and {self.type_!r}"
276
+
277
+
266
278
  ##
267
279
 
268
280
 
@@ -367,14 +379,32 @@ def is_subclass_gen(
367
379
  def is_subclass_gen(cls: Any, parent: Any, /) -> bool: ...
368
380
  def is_subclass_gen(cls: Any, parent: Any, /) -> bool:
369
381
  """Generalized `issubclass`."""
370
- if isinstance(cls, tuple) and isinstance(parent, tuple):
371
- return _is_subclass_gen_tuple(cls, parent)
372
- if is_literal_type(cls) and is_literal_type(parent):
373
- return _is_subclass_gen_literal(cls, parent)
374
- if is_literal_type(cls) is not is_literal_type(parent):
375
- return False
382
+ # child
383
+ if isinstance(cls, tuple):
384
+ return all(is_subclass_gen(c, parent) for c in cls)
385
+ if is_literal_type(cls):
386
+ types = tuple(map(type, get_args(cls)))
387
+ return (
388
+ is_literal_type(parent) and set(get_args(cls)).issubset(get_args(parent))
389
+ ) or is_subclass_gen(types, parent)
376
390
  if is_union_type(cls):
377
- return _is_subclass_gen_union(cls, parent)
391
+ return all(is_subclass_gen(c, parent) for c in get_args(cls))
392
+ # parent
393
+ if isinstance(parent, tuple):
394
+ return any(is_subclass_gen(cls, p) for p in parent)
395
+ if is_literal_type(parent):
396
+ return is_literal_type(cls) and set(get_args(cls)).issubset(get_args(parent))
397
+ if is_union_type(parent):
398
+ return any(is_subclass_gen(cls, p) for p in get_args(parent))
399
+ # tuple vs tuple
400
+ if is_tuple_type(cls) and is_tuple_type(parent):
401
+ cls_args, parent_args = get_args(cls), get_args(parent)
402
+ return (len(cls_args) == len(parent_args)) and all(
403
+ is_subclass_gen(c, p) for c, p in zip(cls_args, parent_args, strict=True)
404
+ )
405
+ if is_tuple_type(cls) is not is_tuple_type(parent):
406
+ return False
407
+ # basic
378
408
  if isinstance(cls, type):
379
409
  return any(_is_subclass_gen_type(cls, p) for p in get_type_classes(parent))
380
410
  raise IsSubclassGenError(cls=cls)
@@ -396,20 +426,6 @@ def _is_subclass_gen_type(cls: type[Any], parent: type[_T], /) -> TypeGuard[type
396
426
  )
397
427
 
398
428
 
399
- def _is_subclass_gen_tuple(cls: tuple[Any, ...], parent: tuple[Any, ...], /) -> bool:
400
- return (len(cls) == len(parent)) and all(
401
- is_subclass_gen(c, p) for c, p in zip(cls, parent, strict=True)
402
- )
403
-
404
-
405
- def _is_subclass_gen_literal(cls: Any, parent: Any, /) -> bool:
406
- return set(get_args(cls)).issubset(get_args(parent))
407
-
408
-
409
- def _is_subclass_gen_union(cls: Any, parent: Any, /) -> bool:
410
- return all(is_subclass_gen(a, parent) for a in get_args(cls))
411
-
412
-
413
429
  @dataclass(kw_only=True, slots=True)
414
430
  class IsSubclassGenError(Exception):
415
431
  cls: Any
@@ -449,6 +465,7 @@ def _is_annotation_of_type(obj: Any, origin: Any, /) -> bool:
449
465
  __all__ = [
450
466
  "GetTypeClassesError",
451
467
  "GetUnionTypeClassesError",
468
+ "IsInstanceGenError",
452
469
  "IsSubclassGenError",
453
470
  "contains_self",
454
471
  "get_literal_elements",