dycw-utilities 0.112.1__py3-none-any.whl → 0.112.2__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.112.1.dist-info → dycw_utilities-0.112.2.dist-info}/METADATA +1 -1
- {dycw_utilities-0.112.1.dist-info → dycw_utilities-0.112.2.dist-info}/RECORD +9 -9
- utilities/__init__.py +1 -1
- utilities/polars.py +7 -6
- utilities/sentinel.py +1 -1
- utilities/text.py +3 -3
- utilities/typing.py +59 -11
- {dycw_utilities-0.112.1.dist-info → dycw_utilities-0.112.2.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.112.1.dist-info → dycw_utilities-0.112.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
utilities/__init__.py,sha256=
|
1
|
+
utilities/__init__.py,sha256=YIZTcfeQmna9ccW7NIqZzcDB03vFiy0xoZl-xVKVNg4,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
|
@@ -46,7 +46,7 @@ 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
|
48
48
|
utilities/platform.py,sha256=NU7ycTvAXAG-fdYmDXaM1m4EOml2cGiaYwaUzfzSqyU,1767
|
49
|
-
utilities/polars.py,sha256=
|
49
|
+
utilities/polars.py,sha256=q8a2hTX9tyPxtxUarIm2BxlnckIwF1RCpcJz03OoIoY,58458
|
50
50
|
utilities/polars_ols.py,sha256=efhXf0gjrHUpQrvS6a7g8yJQJWf_ATKtJnqqF2inCOU,5680
|
51
51
|
utilities/pqdm.py,sha256=foRytQybmOQ05pjt5LF7ANyzrIa--4ScDE3T2wd31a4,3118
|
52
52
|
utilities/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -62,7 +62,7 @@ utilities/redis.py,sha256=fAUbfOlCmxcxhh47PXQX63w0CU5iOFKfdUJ7jDn9ntM,22096
|
|
62
62
|
utilities/reprlib.py,sha256=Re9bk3n-kC__9DxQmRlevqFA86pE6TtVfWjUgpbVOv0,1849
|
63
63
|
utilities/rich.py,sha256=t50MwwVBsoOLxzmeVFSVpjno4OW6Ufum32skXbV8-Bs,1911
|
64
64
|
utilities/scipy.py,sha256=X6ROnHwiUhAmPhM0jkfEh0-Fd9iRvwiqtCQMOLmOQF8,945
|
65
|
-
utilities/sentinel.py,sha256=
|
65
|
+
utilities/sentinel.py,sha256=3jIwgpMekWgDAxPDA_hXMP2St43cPhciKN3LWiZ7kv0,1248
|
66
66
|
utilities/shelve.py,sha256=HZsMwK4tcIfg3sh0gApx4-yjQnrY4o3V3ZRimvRhoW0,738
|
67
67
|
utilities/slack_sdk.py,sha256=SeDNMh24IPiEBWoGMdgvrflUaFa9TGlTS03H9-NKaQw,4132
|
68
68
|
utilities/socket.py,sha256=K77vfREvzoVTrpYKo6MZakol0EYu2q1sWJnnZqL0So0,118
|
@@ -73,12 +73,12 @@ 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=c65sonE-vMJtBR8-LIntXUqku7wDQC6p4z69DOSur7o,10947
|
77
77
|
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=
|
81
|
+
utilities/typing.py,sha256=i_Ajb8UAOplnhrezb2zk4JaXtUyE0nUyaPR5o9j4YNc,12869
|
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.
|
91
|
-
dycw_utilities-0.112.
|
92
|
-
dycw_utilities-0.112.
|
93
|
-
dycw_utilities-0.112.
|
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,,
|
utilities/__init__.py
CHANGED
utilities/polars.py
CHANGED
@@ -941,10 +941,9 @@ def dataclass_to_schema(
|
|
941
941
|
dtype = struct_dtype(**dtypes)
|
942
942
|
elif field.type_ is dt.datetime:
|
943
943
|
dtype = _dataclass_to_schema_datetime(field)
|
944
|
-
elif is_union_type(field.type_) and set(
|
945
|
-
|
946
|
-
|
947
|
-
}:
|
944
|
+
elif is_union_type(field.type_) and set(
|
945
|
+
get_args(field.type_, optional_drop_none=True)
|
946
|
+
) == {dt.date, dt.datetime}:
|
948
947
|
if is_instance_gen(field.value, dt.date):
|
949
948
|
dtype = Date
|
950
949
|
else:
|
@@ -1002,7 +1001,7 @@ def _dataclass_to_schema_one(
|
|
1002
1001
|
if is_literal_type(obj):
|
1003
1002
|
return pl.Enum(get_args(obj))
|
1004
1003
|
if is_optional_type(obj):
|
1005
|
-
inner_type = one(get_args(obj))
|
1004
|
+
inner_type = one(get_args(obj, optional_drop_none=True))
|
1006
1005
|
return _dataclass_to_schema_one(inner_type, globalns=globalns, localns=localns)
|
1007
1006
|
msg = f"{obj=}"
|
1008
1007
|
raise NotImplementedError(msg)
|
@@ -1732,7 +1731,9 @@ def _struct_from_dataclass_one(
|
|
1732
1731
|
):
|
1733
1732
|
return String
|
1734
1733
|
if is_optional_type(ann):
|
1735
|
-
return _struct_from_dataclass_one(
|
1734
|
+
return _struct_from_dataclass_one(
|
1735
|
+
one(get_args(ann, optional_drop_none=True)), time_zone=time_zone
|
1736
|
+
)
|
1736
1737
|
if is_frozenset_type(ann) or is_list_type(ann) or is_set_type(ann):
|
1737
1738
|
return List(_struct_from_dataclass_one(one(get_args(ann)), time_zone=time_zone))
|
1738
1739
|
raise _StructFromDataClassTypeError(ann=ann)
|
utilities/sentinel.py
CHANGED
@@ -40,7 +40,7 @@ sentinel = Sentinel()
|
|
40
40
|
|
41
41
|
def parse_sentinel(text: str, /) -> Sentinel:
|
42
42
|
"""Parse text into the Sentinel value."""
|
43
|
-
if
|
43
|
+
if search("^(|sentinel|<sentinel>)$", text, flags=IGNORECASE):
|
44
44
|
return sentinel
|
45
45
|
raise ParseSentinelError(text=text)
|
46
46
|
|
utilities/text.py
CHANGED
@@ -25,9 +25,9 @@ DEFAULT_SEPARATOR = ","
|
|
25
25
|
|
26
26
|
def parse_bool(text: str, /) -> bool:
|
27
27
|
"""Parse text into a boolean value."""
|
28
|
-
if
|
28
|
+
if search(r"^(0|False)$", text, flags=IGNORECASE):
|
29
29
|
return False
|
30
|
-
if
|
30
|
+
if search(r"^(1|True)$", text, flags=IGNORECASE):
|
31
31
|
return True
|
32
32
|
raise ParseBoolError(text=text)
|
33
33
|
|
@@ -46,7 +46,7 @@ class ParseBoolError(Exception):
|
|
46
46
|
|
47
47
|
def parse_none(text: str, /) -> None:
|
48
48
|
"""Parse text into the None value."""
|
49
|
-
if
|
49
|
+
if search(r"^(|None)$", text, flags=IGNORECASE):
|
50
50
|
return
|
51
51
|
raise ParseNoneError(text=text)
|
52
52
|
|
utilities/typing.py
CHANGED
@@ -48,14 +48,14 @@ def contains_self(obj: Any, /) -> bool:
|
|
48
48
|
##
|
49
49
|
|
50
50
|
|
51
|
-
def get_args(obj: Any,
|
51
|
+
def get_args(obj: Any, /, *, optional_drop_none: bool = False) -> tuple[Any, ...]:
|
52
52
|
"""Get the arguments of an annotation."""
|
53
53
|
if isinstance(obj, TypeAliasType):
|
54
54
|
return get_args(obj.__value__)
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
return
|
55
|
+
args = _get_args(obj)
|
56
|
+
if is_optional_type(obj) and optional_drop_none:
|
57
|
+
args = tuple(a for a in args if a is not NoneType)
|
58
|
+
return args
|
59
59
|
|
60
60
|
|
61
61
|
##
|
@@ -230,10 +230,24 @@ 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
|
-
|
233
|
+
if isinstance(obj, tuple) and isinstance(type_, tuple):
|
234
|
+
return _is_instance_gen_tuple(obj, type_)
|
235
|
+
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_))
|
234
238
|
|
235
239
|
|
236
|
-
def
|
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_)
|
248
|
+
|
249
|
+
|
250
|
+
def _is_instance_gen_type(obj: Any, type_: type[_T], /) -> TypeGuard[_T]:
|
237
251
|
return (
|
238
252
|
isinstance(obj, type_)
|
239
253
|
and not (
|
@@ -350,13 +364,23 @@ def is_subclass_gen(
|
|
350
364
|
/,
|
351
365
|
) -> TypeGuard[type[_T1 | _T2 | _T3 | _T4 | _T5]]: ...
|
352
366
|
@overload
|
353
|
-
def is_subclass_gen(cls:
|
354
|
-
def is_subclass_gen(cls:
|
367
|
+
def is_subclass_gen(cls: Any, parent: Any, /) -> bool: ...
|
368
|
+
def is_subclass_gen(cls: Any, parent: Any, /) -> bool:
|
355
369
|
"""Generalized `issubclass`."""
|
356
|
-
|
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
|
376
|
+
if is_union_type(cls):
|
377
|
+
return _is_subclass_gen_union(cls, parent)
|
378
|
+
if isinstance(cls, type):
|
379
|
+
return any(_is_subclass_gen_type(cls, p) for p in get_type_classes(parent))
|
380
|
+
raise IsSubclassGenError(cls=cls)
|
357
381
|
|
358
382
|
|
359
|
-
def
|
383
|
+
def _is_subclass_gen_type(cls: type[Any], parent: type[_T], /) -> TypeGuard[type[_T]]:
|
360
384
|
return (
|
361
385
|
issubclass(cls, parent)
|
362
386
|
and not (
|
@@ -372,6 +396,29 @@ def _is_subclass_gen_one(cls: type[Any], parent: type[_T], /) -> TypeGuard[type[
|
|
372
396
|
)
|
373
397
|
|
374
398
|
|
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
|
+
@dataclass(kw_only=True, slots=True)
|
414
|
+
class IsSubclassGenError(Exception):
|
415
|
+
cls: Any
|
416
|
+
|
417
|
+
@override
|
418
|
+
def __str__(self) -> str:
|
419
|
+
return f"Argument must be a class; got {self.cls!r}"
|
420
|
+
|
421
|
+
|
375
422
|
##
|
376
423
|
|
377
424
|
|
@@ -402,6 +449,7 @@ def _is_annotation_of_type(obj: Any, origin: Any, /) -> bool:
|
|
402
449
|
__all__ = [
|
403
450
|
"GetTypeClassesError",
|
404
451
|
"GetUnionTypeClassesError",
|
452
|
+
"IsSubclassGenError",
|
405
453
|
"contains_self",
|
406
454
|
"get_literal_elements",
|
407
455
|
"get_type_classes",
|
File without changes
|
File without changes
|