dycw-utilities 0.112.2__py3-none-any.whl → 0.112.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.112.2
3
+ Version: 0.112.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=YIZTcfeQmna9ccW7NIqZzcDB03vFiy0xoZl-xVKVNg4,60
1
+ utilities/__init__.py,sha256=z7R-tij8PUsszk8bX9FviCXCNFWurmc0egXzyuNqIdY,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.3.dist-info/METADATA,sha256=t7BNtV2r3OiHx0TWQ9JFxwyrFWjwRWFsAZOMD8HKIDA,13004
91
+ dycw_utilities-0.112.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
+ dycw_utilities-0.112.3.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
93
+ dycw_utilities-0.112.3.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.3"
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",