dycw-utilities 0.151.8__py3-none-any.whl → 0.151.9__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.151.8
3
+ Version: 0.151.9
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=4kiNe54mu65BdlIWO3fy88xeEWBui4WvuRPhgdV-gOA,60
1
+ utilities/__init__.py,sha256=xYjUasgFTCrlivo087SIUYd7dVnOiwjr_foo_yzYoXU,60
2
2
  utilities/altair.py,sha256=92E2lCdyHY4Zb-vCw6rEJIsWdKipuu-Tu2ab1ufUfAk,9079
3
3
  utilities/asyncio.py,sha256=2m2a2C-Qgc6OHTTHL332-t66A7xDITt_SORT7a1DJWo,16792
4
4
  utilities/atomicwrites.py,sha256=tPo6r-Rypd9u99u66B9z86YBPpnLrlHtwox_8Z7T34Y,5790
@@ -23,7 +23,7 @@ utilities/getpass.py,sha256=DfN5UgMAtFCqS3dSfFHUfqIMZX2shXvwphOz_6J6f6A,103
23
23
  utilities/gzip.py,sha256=fkGP3KdsBfXlstodT4wtlp-PwNyUsogpbDCVVVGdsm4,781
24
24
  utilities/hashlib.py,sha256=SVTgtguur0P4elppvzOBbLEjVM3Pea0eWB61yg2ilxo,309
25
25
  utilities/http.py,sha256=TsavEfHlRtlLaeV21Z6KZh0qbPw-kvD1zsQdZ7Kep5Q,977
26
- utilities/hypothesis.py,sha256=muEtgWd8ZR7z4Iv-demKK3dBJY6dC26FYIzNcDd0ViE,40267
26
+ utilities/hypothesis.py,sha256=TDuNreKDwc_7iTJVhhzppJPgdenX0mxBqxofR58jwWE,40446
27
27
  utilities/importlib.py,sha256=mV1xT_O_zt_GnZZ36tl3xOmMaN_3jErDWY54fX39F6Y,429
28
28
  utilities/inflect.py,sha256=v7YkOWSu8NAmVghPcf4F3YBZQoJCS47_DLf9jbfWIs0,581
29
29
  utilities/ipython.py,sha256=V2oMYHvEKvlNBzxDXdLvKi48oUq2SclRg5xasjaXStw,763
@@ -44,7 +44,7 @@ utilities/orjson.py,sha256=Gzxn-s55pGFKV8DdsYXpp-Gr3r-5KdacYUd_GHMBogM,40088
44
44
  utilities/os.py,sha256=mFvjydySvjtSXpk7tLStUJcndauAoujxUUmj_CO7LWY,3778
45
45
  utilities/parse.py,sha256=JcJn5yXKhIWXBCwgBdPsyu7Hvcuw6kyEdqvaebCaI9k,17951
46
46
  utilities/pathlib.py,sha256=77wT9naY2Nnrbar8nJiIYd2r3MfabMQM9VguuuivrdQ,8481
47
- utilities/period.py,sha256=LMN6gIo4QpkXpYnuXMItWzNqjkb6R47FHV1B-5Rndc0,10117
47
+ utilities/period.py,sha256=SpgccCm1vsM5ESHj26upVHRERxELzri8No9XU60H_H8,12201
48
48
  utilities/pickle.py,sha256=MBT2xZCsv0pH868IXLGKnlcqNx2IRVKYNpRcqiQQqxw,653
49
49
  utilities/platform.py,sha256=pTn7gw6N4T6LdKrf0virwarof_mze9WtoQlrGMzhGVI,2798
50
50
  utilities/polars.py,sha256=x4x3i08ldcDyKVEa8rcyAyacHKjok30K2v79yhoIn2Y,73243
@@ -89,8 +89,8 @@ utilities/zoneinfo.py,sha256=FBMcUQ4662Aq8SsuCL1OAhDQiyANmVjtb-C30DRrWoE,1966
89
89
  utilities/pytest_plugins/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
90
90
  utilities/pytest_plugins/pytest_randomly.py,sha256=NXzCcGKbpgYouz5yehKb4jmxmi2SexKKpgF4M65bi10,414
91
91
  utilities/pytest_plugins/pytest_regressions.py,sha256=Iwhfv_OJH7UCPZCfoh7ugZ2Xjqjil-BBBsOb8sDwiGI,1471
92
- dycw_utilities-0.151.8.dist-info/METADATA,sha256=_O8sp46Zj82B4X3XXMKjrRoSPcCxTj-uG_ulUBEaXKc,1696
93
- dycw_utilities-0.151.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
94
- dycw_utilities-0.151.8.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
95
- dycw_utilities-0.151.8.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
96
- dycw_utilities-0.151.8.dist-info/RECORD,,
92
+ dycw_utilities-0.151.9.dist-info/METADATA,sha256=dbrFNuXXcxn1bt2hKwHMXEJZYmmCXNrkQGc4RmKyKhU,1696
93
+ dycw_utilities-0.151.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
94
+ dycw_utilities-0.151.9.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
95
+ dycw_utilities-0.151.9.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
96
+ dycw_utilities-0.151.9.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.151.8"
3
+ __version__ = "0.151.9"
utilities/hypothesis.py CHANGED
@@ -1415,6 +1415,11 @@ def zoned_datetimes(
1415
1415
  return zoned
1416
1416
 
1417
1417
 
1418
+ zoned_datetimes_2000 = zoned_datetimes(
1419
+ min_value=ZonedDateTime(2000, 1, 1, tz=UTC.key),
1420
+ max_value=ZonedDateTime(2000, 12, 31, tz=UTC.key),
1421
+ )
1422
+
1418
1423
  __all__ = [
1419
1424
  "Draw2Error",
1420
1425
  "MaybeSearchStrategy",
@@ -1468,4 +1473,5 @@ __all__ = [
1468
1473
  "versions",
1469
1474
  "year_months",
1470
1475
  "zoned_datetimes",
1476
+ "zoned_datetimes_2000",
1471
1477
  ]
utilities/period.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import datetime as dt
3
4
  from dataclasses import dataclass
4
5
  from typing import TYPE_CHECKING, Any, Self, TypedDict, assert_never, overload, override
5
6
  from zoneinfo import ZoneInfo
@@ -16,7 +17,9 @@ if TYPE_CHECKING:
16
17
  from utilities.types import TimeZoneLike
17
18
 
18
19
 
19
- class _PeriodAsDict[T: (Date, Time, ZonedDateTime)](TypedDict):
20
+ class _PeriodAsDict[T: Date | Time | ZonedDateTime | dt.date | dt.time | dt.datetime](
21
+ TypedDict
22
+ ):
20
23
  start: T
21
24
  end: T
22
25
 
@@ -81,6 +84,25 @@ class DatePeriod:
81
84
  return f"{fc(start)}-{fc(end, fmt='%m%d')}"
82
85
  return f"{fc(start)}-{fc(end)}"
83
86
 
87
+ @classmethod
88
+ def from_dict(cls, mapping: _PeriodAsDict[Date | dt.date], /) -> Self:
89
+ """Convert the dictionary to a period."""
90
+ match mapping["start"]:
91
+ case Date() as start:
92
+ ...
93
+ case dt.date() as py_date:
94
+ start = Date.from_py_date(py_date)
95
+ case never:
96
+ assert_never(never)
97
+ match mapping["end"]:
98
+ case Date() as end:
99
+ ...
100
+ case dt.date() as py_date:
101
+ end = Date.from_py_date(py_date)
102
+ case never:
103
+ assert_never(never)
104
+ return cls(start=start, end=end)
105
+
84
106
  def replace(
85
107
  self, *, start: Date | Sentinel = sentinel, end: Date | Sentinel = sentinel
86
108
  ) -> Self:
@@ -104,12 +126,6 @@ class TimePeriod:
104
126
  cls = get_class_name(self)
105
127
  return f"{cls}({self.start}, {self.end})"
106
128
 
107
- def replace(
108
- self, *, start: Time | Sentinel = sentinel, end: Time | Sentinel = sentinel
109
- ) -> Self:
110
- """Replace elements of the period."""
111
- return replace_non_sentinel(self, start=start, end=end)
112
-
113
129
  def at(
114
130
  self, obj: Date | tuple[Date, Date], /, *, time_zone: TimeZoneLike = UTC
115
131
  ) -> ZonedDateTimePeriod:
@@ -123,6 +139,31 @@ class TimePeriod:
123
139
  assert_never(never)
124
140
  return DatePeriod(start, end).at((self.start, self.end), time_zone=time_zone)
125
141
 
142
+ @classmethod
143
+ def from_dict(cls, mapping: _PeriodAsDict[Time | dt.time], /) -> Self:
144
+ """Convert the dictionary to a period."""
145
+ match mapping["start"]:
146
+ case Time() as start:
147
+ ...
148
+ case dt.time() as py_time:
149
+ start = Time.from_py_time(py_time)
150
+ case never:
151
+ assert_never(never)
152
+ match mapping["end"]:
153
+ case Time() as end:
154
+ ...
155
+ case dt.time() as py_time:
156
+ end = Time.from_py_time(py_time)
157
+ case never:
158
+ assert_never(never)
159
+ return cls(start=start, end=end)
160
+
161
+ def replace(
162
+ self, *, start: Time | Sentinel = sentinel, end: Time | Sentinel = sentinel
163
+ ) -> Self:
164
+ """Replace elements of the period."""
165
+ return replace_non_sentinel(self, start=start, end=end)
166
+
126
167
  def to_dict(self) -> _PeriodAsDict[Time]:
127
168
  """Convert the period to a dictionary."""
128
169
  return _PeriodAsDict(start=self.start, end=self.end)
@@ -229,6 +270,25 @@ class ZonedDateTimePeriod:
229
270
  return f"{fc(start.to_plain())}-{fc(end, fmt='%Y%m%dT%H%M')}"
230
271
  return f"{fc(start.to_plain())}-{fc(end, fmt='%Y%m%dT%H')}"
231
272
 
273
+ @classmethod
274
+ def from_dict(cls, mapping: _PeriodAsDict[ZonedDateTime | dt.datetime], /) -> Self:
275
+ """Convert the dictionary to a period."""
276
+ match mapping["start"]:
277
+ case ZonedDateTime() as start:
278
+ ...
279
+ case dt.date() as py_datetime:
280
+ start = ZonedDateTime.from_py_datetime(py_datetime)
281
+ case never:
282
+ assert_never(never)
283
+ match mapping["end"]:
284
+ case ZonedDateTime() as end:
285
+ ...
286
+ case dt.date() as py_datetime:
287
+ end = ZonedDateTime.from_py_datetime(py_datetime)
288
+ case never:
289
+ assert_never(never)
290
+ return cls(start=start, end=end)
291
+
232
292
  def replace(
233
293
  self,
234
294
  *,
@@ -258,7 +318,7 @@ class PeriodError(Exception): ...
258
318
 
259
319
 
260
320
  @dataclass(kw_only=True, slots=True)
261
- class _PeriodInvalidError[T: (Date, ZonedDateTime)](PeriodError):
321
+ class _PeriodInvalidError[T: Date | ZonedDateTime](PeriodError):
262
322
  start: T
263
323
  end: T
264
324