dycw-utilities 0.132.3__py3-none-any.whl → 0.132.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.132.3
3
+ Version: 0.132.4
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -1,11 +1,11 @@
1
- utilities/__init__.py,sha256=9NsY4uZT1cOp7_D5RHpPZYyj4cpKLbQLR7K0gu5KJfU,60
1
+ utilities/__init__.py,sha256=XNt4jtceKkZ5SzTlJ0nWpgaWnxz3PNjWlzmzu1iXOtI,60
2
2
  utilities/aiolimiter.py,sha256=mD0wEiqMgwpty4XTbawFpnkkmJS6R4JRsVXFUaoitSU,628
3
3
  utilities/altair.py,sha256=HeZBVUocjkrTNwwKrClppsIqgNFF-ykv05HfZSoHYno,9104
4
4
  utilities/asyncio.py,sha256=USWMMrHqPVRr20vlIn_n5JLimyqa-5xLhuqDYWJed8A,37586
5
5
  utilities/atomicwrites.py,sha256=geFjn9Pwn-tTrtoGjDDxWli9NqbYfy3gGL6ZBctiqSo,5393
6
6
  utilities/atools.py,sha256=-bFGIrwYMFR7xl39j02DZMsO_u5x5_Ph7bRlBUFVYyw,1048
7
7
  utilities/cachetools.py,sha256=uBtEv4hD-TuCPX_cQy1lOpLF-QqfwnYGSf0o4Soqydc,2826
8
- utilities/click.py,sha256=jLyep_czA3k-3XWHWrKFEEN79ZbMhVT2H7TGnTa8i44,13314
8
+ utilities/click.py,sha256=DI8yJFlpBpRvnc90Xc0kfLKGQRpFCvj797oOJiaE4k8,14998
9
9
  utilities/concurrent.py,sha256=s2scTEd2AhXVTW4hpASU2qxV_DiVLALfms55cCQzCvM,2886
10
10
  utilities/contextlib.py,sha256=lpaLJBy3X0UGLWjM98jkQZZq8so4fRmoK-Bheq0uOW4,1027
11
11
  utilities/contextvars.py,sha256=RsSGGrbQqqZ67rOydnM7WWIsM2lIE31UHJLejnHJPWY,505
@@ -42,7 +42,7 @@ utilities/operator.py,sha256=DuiWdkmK0D-ddvFqOayDkazTQE1Ysvtl6-UiBN5gns8,3857
42
42
  utilities/optuna.py,sha256=loyJGWTzljgdJaoLhP09PT8Jz6o_pwBOwehY33lHkhw,1923
43
43
  utilities/orjson.py,sha256=y5ynSGhQjX7vikfvsHh_AklLnH7gjvsSkIC3h5tnx98,36474
44
44
  utilities/os.py,sha256=D_FyyT-6TtqiN9KSS7c9g1fnUtgxmyMtzAjmYLkk46A,3587
45
- utilities/parse.py,sha256=YE2VWYKDm9WYf5wcOWrOxVfM6UWvhkSxSkwdxRQNsA0,17633
45
+ utilities/parse.py,sha256=PCy73pBmXgFzjxV54BC7TzHVhV3caDQvdvfXYqE_UUQ,17642
46
46
  utilities/pathlib.py,sha256=PK41rf1c9Wqv7h8f5R7H3_Lhq_gQZTUJD5tu3gMHVaU,3247
47
47
  utilities/period.py,sha256=opqpBevBGSGXbA7NYfRJjtthi1JPxdMaZ7QV3xosnTc,4774
48
48
  utilities/pickle.py,sha256=MBT2xZCsv0pH868IXLGKnlcqNx2IRVKYNpRcqiQQqxw,653
@@ -78,7 +78,7 @@ utilities/threading.py,sha256=GvBOp4CyhHfN90wGXZuA2VKe9fGzMaEa7oCl4f3nnPU,1009
78
78
  utilities/timer.py,sha256=oYqRQ-G-DMOOHB6a4yP5-PJDVimLnbNkMnkOj_jUmFg,2474
79
79
  utilities/traceback.py,sha256=i-790AQbTrDA8MiYyOcYPFpm48I558VR_kL_7x4ypfY,8503
80
80
  utilities/typed_settings.py,sha256=DqJsJjSit9wd_OA3KyMDpx2zatKIi5QhuARI9TPl3rk,3701
81
- utilities/types.py,sha256=fuJQiVjKYKL9g3F5H7oW_98Xm1-R5Xq4t4kU-aHxW0M,18826
81
+ utilities/types.py,sha256=ZkTndROqNbpgUa_MX4pYlkfmU9E8prMqr4UvASruhsE,19013
82
82
  utilities/typing.py,sha256=kVWK6ciV8T0MKxnFQcMSEr_XlRisspH5aBTTosMUh30,13872
83
83
  utilities/tzdata.py,sha256=fgNVj66yUbCSI_-vrRVzSD3gtf-L_8IEJEPjP_Jel5Y,266
84
84
  utilities/tzlocal.py,sha256=KyCXEgCTjqGFx-389JdTuhMRUaT06U1RCMdWoED-qro,728
@@ -88,7 +88,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
88
88
  utilities/whenever.py,sha256=tArX9unVEKhRYdvbUFa83e4hrzdtMKKCEN4QWTaYd8c,19524
89
89
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
90
90
  utilities/zoneinfo.py,sha256=oEH-nL3t4h9uawyZqWDtNtDAl6M-CLpLYGI_nI6DulM,1971
91
- dycw_utilities-0.132.3.dist-info/METADATA,sha256=zfgSgg9oCTc9xP-C8UDS_9rET8qgWp9M5dOW9aZzhI0,1522
92
- dycw_utilities-0.132.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
- dycw_utilities-0.132.3.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
94
- dycw_utilities-0.132.3.dist-info/RECORD,,
91
+ dycw_utilities-0.132.4.dist-info/METADATA,sha256=_AReviYgS7sJRlfoEv0VV19ABmMgXnFz2uWE0Rq3JNI,1522
92
+ dycw_utilities-0.132.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
+ dycw_utilities-0.132.4.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
94
+ dycw_utilities-0.132.4.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.132.3"
3
+ __version__ = "0.132.4"
utilities/click.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import ipaddress
3
4
  import pathlib
4
5
  from typing import TYPE_CHECKING, Generic, TypedDict, TypeVar, assert_never, override
5
6
 
@@ -12,12 +13,15 @@ import utilities.whenever
12
13
  from utilities.enum import EnsureEnumError, ensure_enum
13
14
  from utilities.functions import EnsureStrError, ensure_str, get_class_name
14
15
  from utilities.iterables import is_iterable_not_str
16
+ from utilities.parse import ParseObjectError, parse_object
15
17
  from utilities.text import split_str
16
18
  from utilities.types import (
17
19
  DateDeltaLike,
18
20
  DateLike,
19
21
  DateTimeDeltaLike,
20
22
  EnumLike,
23
+ IPv4AddressLike,
24
+ IPv6AddressLike,
21
25
  MaybeStr,
22
26
  PlainDateTimeLike,
23
27
  TEnum,
@@ -173,6 +177,58 @@ class Enum(ParamType, Generic[TEnum]):
173
177
  return _make_metavar(param, desc)
174
178
 
175
179
 
180
+ class IPv4Address(ParamType):
181
+ """An IPv4 address-valued parameter."""
182
+
183
+ name = "ipv4 address"
184
+
185
+ @override
186
+ def __repr__(self) -> str:
187
+ return self.name.upper()
188
+
189
+ @override
190
+ def convert(
191
+ self, value: IPv4AddressLike, param: Parameter | None, ctx: Context | None
192
+ ) -> ipaddress.IPv4Address:
193
+ """Convert a value into the `IPv4Address` type."""
194
+ match value:
195
+ case ipaddress.IPv4Address():
196
+ return value
197
+ case str():
198
+ try:
199
+ return parse_object(ipaddress.IPv4Address, value)
200
+ except ParseObjectError as error:
201
+ self.fail(str(error), param, ctx)
202
+ case _ as never:
203
+ assert_never(never)
204
+
205
+
206
+ class IPv6Address(ParamType):
207
+ """An IPv6 address-valued parameter."""
208
+
209
+ name = "ipv6 address"
210
+
211
+ @override
212
+ def __repr__(self) -> str:
213
+ return self.name.upper()
214
+
215
+ @override
216
+ def convert(
217
+ self, value: IPv6AddressLike, param: Parameter | None, ctx: Context | None
218
+ ) -> ipaddress.IPv6Address:
219
+ """Convert a value into the `IPv6Address` type."""
220
+ match value:
221
+ case ipaddress.IPv6Address():
222
+ return value
223
+ case str():
224
+ try:
225
+ return parse_object(ipaddress.IPv6Address, value)
226
+ except ParseObjectError as error:
227
+ self.fail(str(error), param, ctx)
228
+ case _ as never:
229
+ assert_never(never)
230
+
231
+
176
232
  class Month(ParamType):
177
233
  """A month-valued parameter."""
178
234
 
@@ -467,6 +523,8 @@ __all__ = [
467
523
  "FrozenSetEnums",
468
524
  "FrozenSetParameter",
469
525
  "FrozenSetStrs",
526
+ "IPv4Address",
527
+ "IPv6Address",
470
528
  "ListEnums",
471
529
  "ListParameter",
472
530
  "ListStrs",
utilities/parse.py CHANGED
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  from contextlib import suppress
4
4
  from dataclasses import dataclass
5
5
  from enum import Enum
6
+ from ipaddress import IPv4Address, IPv6Address
6
7
  from pathlib import Path
7
8
  from re import DOTALL
8
9
  from types import NoneType
@@ -176,14 +177,9 @@ def _parse_object_type(
176
177
  return parse_bool(text)
177
178
  except ParseBoolError:
178
179
  raise _ParseObjectParseError(type_=cls, text=text) from None
179
- if is_subclass_gen(cls, int):
180
+ if is_subclass_gen(cls, int | float | IPv4Address | IPv6Address):
180
181
  try:
181
- return int(text)
182
- except ValueError:
183
- raise _ParseObjectParseError(type_=cls, text=text) from None
184
- if issubclass(cls, float):
185
- try:
186
- return float(text)
182
+ return cls(text)
187
183
  except ValueError:
188
184
  raise _ParseObjectParseError(type_=cls, text=text) from None
189
185
  if issubclass(cls, Enum):
@@ -443,7 +439,16 @@ def serialize_object(
443
439
  with suppress(_SerializeObjectSerializeError):
444
440
  return _serialize_object_extra(obj, extra)
445
441
  if (obj is None) or isinstance(
446
- obj, bool | int | float | str | Path | Sentinel | Version
442
+ obj,
443
+ bool
444
+ | int
445
+ | float
446
+ | str
447
+ | IPv4Address
448
+ | IPv6Address
449
+ | Path
450
+ | Sentinel
451
+ | Version,
447
452
  ):
448
453
  return str(obj)
449
454
  if isinstance(
utilities/types.py CHANGED
@@ -4,6 +4,7 @@ import datetime as dt
4
4
  from asyncio import Event
5
5
  from collections.abc import Awaitable, Callable, Coroutine, Hashable, Iterable, Mapping
6
6
  from enum import Enum
7
+ from ipaddress import IPv4Address, IPv6Address
7
8
  from logging import Logger
8
9
  from pathlib import Path
9
10
  from random import Random
@@ -112,6 +113,11 @@ THashable1 = TypeVar("THashable1", bound=Hashable)
112
113
  THashable2 = TypeVar("THashable2", bound=Hashable)
113
114
 
114
115
 
116
+ # ipaddress
117
+ IPv4AddressLike = MaybeStr[IPv4Address]
118
+ IPv6AddressLike = MaybeStr[IPv6Address]
119
+
120
+
115
121
  # iterables
116
122
  type MaybeIterable[_T] = _T | Iterable[_T]
117
123
  type IterableHashable[_THashable: Hashable] = (
@@ -295,6 +301,8 @@ __all__ = [
295
301
  "DateTimeRoundUnit",
296
302
  "EnumLike",
297
303
  "ExcInfo",
304
+ "IPv4AddressLike",
305
+ "IPv6AddressLike",
298
306
  "IterableHashable",
299
307
  "LogLevel",
300
308
  "LoggerOrName",