dycw-utilities 0.131.4__py3-none-any.whl → 0.131.6__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.131.4
3
+ Version: 0.131.6
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=6MeObidroGzMXdelH1o-Q03DJm25qrn666UYjWfDbG4,60
1
+ utilities/__init__.py,sha256=IYqBm-WAwWhDKdOqlSq4UGAvQ_vBiK8qzv2Mq0YUuRo,60
2
2
  utilities/aiolimiter.py,sha256=mD0wEiqMgwpty4XTbawFpnkkmJS6R4JRsVXFUaoitSU,628
3
3
  utilities/altair.py,sha256=HeZBVUocjkrTNwwKrClppsIqgNFF-ykv05HfZSoHYno,9104
4
4
  utilities/asyncio.py,sha256=lvdgBhuMtxq0dpiwF9g2WMMrit3kqXibN1V5NZ4xdbo,38046
@@ -24,7 +24,7 @@ utilities/getpass.py,sha256=DfN5UgMAtFCqS3dSfFHUfqIMZX2shXvwphOz_6J6f6A,103
24
24
  utilities/git.py,sha256=oi7-_l5e9haSANSCvQw25ufYGoNahuUPHAZ6114s3JQ,1191
25
25
  utilities/hashlib.py,sha256=SVTgtguur0P4elppvzOBbLEjVM3Pea0eWB61yg2ilxo,309
26
26
  utilities/http.py,sha256=WcahTcKYRtZ04WXQoWt5EGCgFPcyHD3EJdlMfxvDt-0,946
27
- utilities/hypothesis.py,sha256=Wpw_jX9TVAXAI13JuPkYbMYlLod9_o7V51x79hhZabU,47332
27
+ utilities/hypothesis.py,sha256=kTxXlZJyBauO3jurT7nIFWXhhmlamUvsNf65OQFEpEc,48084
28
28
  utilities/importlib.py,sha256=mV1xT_O_zt_GnZZ36tl3xOmMaN_3jErDWY54fX39F6Y,429
29
29
  utilities/inflect.py,sha256=DbqB5Q9FbRGJ1NbvEiZBirRMxCxgrz91zy5jCO9ZIs0,347
30
30
  utilities/ipython.py,sha256=V2oMYHvEKvlNBzxDXdLvKi48oUq2SclRg5xasjaXStw,763
@@ -88,10 +88,10 @@ utilities/uuid.py,sha256=jJTFxz-CWgltqNuzmythB7iEQ-Q1mCwPevUfKthZT3c,611
88
88
  utilities/version.py,sha256=ufhJMmI6KPs1-3wBI71aj5wCukd3sP_m11usLe88DNA,5117
89
89
  utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
90
90
  utilities/whenever.py,sha256=jS31ZAY5OMxFxLja_Yo5Fidi87Pd-GoVZ7Vi_teqVDA,16743
91
- utilities/whenever2.py,sha256=aba0RN9GX_XnRsvmZNbHwkD15NmV4l00VFZ3HTK8vT8,3511
91
+ utilities/whenever2.py,sha256=XxiAEp4onJNhIi6G7L2HuzkMJZGA3j-I_fuXxmb5vtY,5432
92
92
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
93
93
  utilities/zoneinfo.py,sha256=tvcgu3QzDxe2suTexi2QzRGpin7VK1TjHa0JYYxT69I,1862
94
- dycw_utilities-0.131.4.dist-info/METADATA,sha256=NwQBlP-SQr8P_EyKBWdHHYaoV1zpC1lsmk4VtSG0s4E,1584
95
- dycw_utilities-0.131.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
96
- dycw_utilities-0.131.4.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
97
- dycw_utilities-0.131.4.dist-info/RECORD,,
94
+ dycw_utilities-0.131.6.dist-info/METADATA,sha256=zhPwLa5dVaZ2tcdTMMoh-HOc348fcu3Q5_pgsCsb40A,1584
95
+ dycw_utilities-0.131.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
96
+ dycw_utilities-0.131.6.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
97
+ dycw_utilities-0.131.6.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.131.4"
3
+ __version__ = "0.131.6"
utilities/hypothesis.py CHANGED
@@ -47,7 +47,7 @@ from hypothesis.strategies import (
47
47
  uuids,
48
48
  )
49
49
  from hypothesis.utils.conventions import not_set
50
- from whenever import Date, DateDelta, PlainDateTime
50
+ from whenever import Date, DateDelta
51
51
 
52
52
  from utilities.datetime import (
53
53
  DATETIME_MAX_NAIVE,
@@ -97,7 +97,7 @@ if TYPE_CHECKING:
97
97
 
98
98
  from hypothesis.database import ExampleDatabase
99
99
  from numpy.random import RandomState
100
- from whenever import ZonedDateTime
100
+ from whenever import PlainDateTime, ZonedDateTime
101
101
 
102
102
  from utilities.numpy import NDArrayB, NDArrayF, NDArrayI, NDArrayO
103
103
  from utilities.types import Duration, Number, RoundMode, TimeZoneLike
@@ -167,9 +167,15 @@ def date_deltas_whenever(
167
167
  *,
168
168
  min_value: MaybeSearchStrategy[DateDelta | None] = None,
169
169
  max_value: MaybeSearchStrategy[DateDelta | None] = None,
170
+ parsable: MaybeSearchStrategy[bool] = False,
170
171
  ) -> DateDelta:
171
172
  """Strategy for generating date deltas."""
172
- from utilities.whenever2 import DATE_DELTA_MAX, DATE_DELTA_MIN
173
+ from utilities.whenever2 import (
174
+ DATE_DELTA_MAX,
175
+ DATE_DELTA_MIN,
176
+ DATE_DELTA_PARSABLE_MAX,
177
+ DATE_DELTA_PARSABLE_MIN,
178
+ )
173
179
 
174
180
  min_value_, max_value_ = [draw2(draw, v) for v in [min_value, max_value]]
175
181
  match min_value_:
@@ -192,6 +198,19 @@ def date_deltas_whenever(
192
198
  max_years, max_months, max_days = max_value_.in_years_months_days()
193
199
  assert max_years == 0
194
200
  assert max_months == 0
201
+ if draw2(draw, parsable):
202
+ parsable_min_years, parsable_min_months, parsable_min_days = (
203
+ DATE_DELTA_PARSABLE_MIN.in_years_months_days()
204
+ )
205
+ assert parsable_min_years == 0
206
+ assert parsable_min_months == 0
207
+ min_days = max(min_days, parsable_min_days)
208
+ parsable_max_years, parsable_max_months, parsable_max_days = (
209
+ DATE_DELTA_PARSABLE_MAX.in_years_months_days()
210
+ )
211
+ assert parsable_max_years == 0
212
+ assert parsable_max_months == 0
213
+ max_days = min(max_days, parsable_max_days)
195
214
  days = draw(integers(min_value=min_days, max_value=max_days))
196
215
  return DateDelta(days=days)
197
216
 
@@ -1050,6 +1069,8 @@ def plain_datetimes_whenever(
1050
1069
  max_value: MaybeSearchStrategy[PlainDateTime | None] = None,
1051
1070
  ) -> PlainDateTime:
1052
1071
  """Strategy for generating plain datetimes."""
1072
+ from whenever import PlainDateTime
1073
+
1053
1074
  from utilities.whenever2 import PLAIN_DATE_TIME_MAX, PLAIN_DATE_TIME_MIN
1054
1075
 
1055
1076
  min_value_, max_value_ = [draw2(draw, v) for v in [min_value, max_value]]
utilities/whenever2.py CHANGED
@@ -5,17 +5,33 @@ from functools import cache
5
5
  from logging import LogRecord
6
6
  from typing import TYPE_CHECKING, Any, override
7
7
 
8
- from whenever import Date, DateTimeDelta, PlainDateTime, ZonedDateTime
8
+ from whenever import (
9
+ Date,
10
+ DateDelta,
11
+ DateTimeDelta,
12
+ PlainDateTime,
13
+ Time,
14
+ TimeDelta,
15
+ ZonedDateTime,
16
+ )
9
17
 
10
- from utilities.tzlocal import LOCAL_TIME_ZONE
11
18
  from utilities.zoneinfo import UTC, get_time_zone_name
12
19
 
13
20
  if TYPE_CHECKING:
21
+ from zoneinfo import ZoneInfo
22
+
14
23
  from utilities.types import TimeZoneLike
15
24
 
16
25
 
26
+ ## bounds
27
+
28
+
17
29
  DATE_MIN = Date.from_py_date(dt.date.min)
18
30
  DATE_MAX = Date.from_py_date(dt.date.max)
31
+ TIME_MIN = Time.from_py_time(dt.time.min)
32
+ TIME_MAX = Time.from_py_time(dt.time.max)
33
+
34
+
19
35
  PLAIN_DATE_TIME_MIN = PlainDateTime.from_py_datetime(dt.datetime.min) # noqa: DTZ901
20
36
  PLAIN_DATE_TIME_MAX = PlainDateTime.from_py_datetime(dt.datetime.max) # noqa: DTZ901
21
37
  ZONED_DATE_TIME_MIN = PLAIN_DATE_TIME_MIN.assume_tz(UTC.key)
@@ -28,6 +44,25 @@ TIME_DELTA_MIN = DATE_TIME_DELTA_MIN.time_part()
28
44
  TIME_DELTA_MAX = DATE_TIME_DELTA_MAX.time_part()
29
45
 
30
46
 
47
+ DATE_TIME_DELTA_PARSABLE_MIN = DateTimeDelta(days=-999999, seconds=-316192377600)
48
+ DATE_TIME_DELTA_PARSABLE_MAX = DateTimeDelta(days=999999, seconds=316192377600)
49
+ DATE_DELTA_PARSABLE_MIN = DateDelta(days=-999999)
50
+ DATE_DELTA_PARSABLE_MAX = DateDelta(days=999999)
51
+
52
+
53
+ ## common constants
54
+
55
+
56
+ ZERO_TIME = Time()
57
+ MICROSECOND = TimeDelta(microseconds=1)
58
+ MILLISECOND = TimeDelta(milliseconds=1)
59
+ SECOND = TimeDelta(seconds=1)
60
+ MINUTE = TimeDelta(minutes=1)
61
+ HOUR = TimeDelta(hours=1)
62
+ DAY = DateDelta(days=1)
63
+ WEEK = DateDelta(weeks=1)
64
+
65
+
31
66
  ##
32
67
 
33
68
 
@@ -62,6 +97,28 @@ def get_now_local() -> ZonedDateTime:
62
97
  return get_now(time_zone="local")
63
98
 
64
99
 
100
+ NOW_LOCAL = get_now_local()
101
+
102
+
103
+ ##
104
+
105
+
106
+ def get_today(*, time_zone: TimeZoneLike = UTC) -> Date:
107
+ """Get the current, timezone-aware local date."""
108
+ return get_now(time_zone=time_zone).date()
109
+
110
+
111
+ TODAY_UTC = get_today(time_zone=UTC)
112
+
113
+
114
+ def get_today_local() -> Date:
115
+ """Get the current, timezone-aware local date."""
116
+ return get_today(time_zone="local")
117
+
118
+
119
+ TODAY_LOCAL = get_today_local()
120
+
121
+
65
122
  ##
66
123
 
67
124
 
@@ -88,7 +145,24 @@ class WheneverLogRecord(LogRecord):
88
145
  )
89
146
  length = self._get_length()
90
147
  plain = format(get_now_local().to_plain().format_common_iso(), f"{length}s")
91
- self.zoned_datetime = f"{plain}[{LOCAL_TIME_ZONE.key}]"
148
+ time_zone = self._get_time_zone_key()
149
+ self.zoned_datetime = f"{plain}[{time_zone}]"
150
+
151
+ @classmethod
152
+ @cache
153
+ def _get_time_zone(cls) -> ZoneInfo:
154
+ """Get the local timezone."""
155
+ try:
156
+ from utilities.tzlocal import get_local_time_zone
157
+ except ModuleNotFoundError: # pragma: no cover
158
+ return UTC
159
+ return get_local_time_zone()
160
+
161
+ @classmethod
162
+ @cache
163
+ def _get_time_zone_key(cls) -> str:
164
+ """Get the local timezone as a string."""
165
+ return cls._get_time_zone().key
92
166
 
93
167
  @classmethod
94
168
  @cache
@@ -101,14 +175,31 @@ class WheneverLogRecord(LogRecord):
101
175
  __all__ = [
102
176
  "DATE_DELTA_MAX",
103
177
  "DATE_DELTA_MIN",
178
+ "DATE_DELTA_PARSABLE_MAX",
179
+ "DATE_DELTA_PARSABLE_MIN",
104
180
  "DATE_MAX",
105
181
  "DATE_MIN",
106
182
  "DATE_TIME_DELTA_MAX",
107
183
  "DATE_TIME_DELTA_MIN",
184
+ "DATE_TIME_DELTA_PARSABLE_MAX",
185
+ "DATE_TIME_DELTA_PARSABLE_MIN",
186
+ "DAY",
187
+ "HOUR",
188
+ "MICROSECOND",
189
+ "MILLISECOND",
190
+ "MINUTE",
191
+ "NOW_LOCAL",
108
192
  "PLAIN_DATE_TIME_MAX",
109
193
  "PLAIN_DATE_TIME_MIN",
194
+ "SECOND",
110
195
  "TIME_DELTA_MAX",
111
196
  "TIME_DELTA_MIN",
197
+ "TIME_MAX",
198
+ "TIME_MIN",
199
+ "TODAY_LOCAL",
200
+ "TODAY_UTC",
201
+ "WEEK",
202
+ "ZERO_TIME",
112
203
  "ZONED_DATE_TIME_MAX",
113
204
  "ZONED_DATE_TIME_MIN",
114
205
  "WheneverLogRecord",
@@ -116,6 +207,7 @@ __all__ = [
116
207
  "from_timestamp_millis",
117
208
  "from_timestamp_nanos",
118
209
  "get_now",
119
- "get_now",
120
210
  "get_now_local",
211
+ "get_today",
212
+ "get_today_local",
121
213
  ]