dycw-utilities 0.131.6__py3-none-any.whl → 0.131.8__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.131.6.dist-info → dycw_utilities-0.131.8.dist-info}/METADATA +1 -1
- {dycw_utilities-0.131.6.dist-info → dycw_utilities-0.131.8.dist-info}/RECORD +9 -9
- utilities/__init__.py +1 -1
- utilities/asyncio.py +6 -2
- utilities/hypothesis.py +89 -15
- utilities/timer.py +31 -65
- utilities/whenever2.py +1 -1
- {dycw_utilities-0.131.6.dist-info → dycw_utilities-0.131.8.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.131.6.dist-info → dycw_utilities-0.131.8.dist-info}/licenses/LICENSE +0 -0
@@ -1,7 +1,7 @@
|
|
1
|
-
utilities/__init__.py,sha256=
|
1
|
+
utilities/__init__.py,sha256=7GFnOq-ksc-RNtwI9lMII4eofdNt78J6EbkJmHRGm6E,60
|
2
2
|
utilities/aiolimiter.py,sha256=mD0wEiqMgwpty4XTbawFpnkkmJS6R4JRsVXFUaoitSU,628
|
3
3
|
utilities/altair.py,sha256=HeZBVUocjkrTNwwKrClppsIqgNFF-ykv05HfZSoHYno,9104
|
4
|
-
utilities/asyncio.py,sha256=
|
4
|
+
utilities/asyncio.py,sha256=yfKvAIDCRrWdyQMVZMo4DJQx4nVrXoAcqwhNuF95Ryo,38186
|
5
5
|
utilities/atomicwrites.py,sha256=geFjn9Pwn-tTrtoGjDDxWli9NqbYfy3gGL6ZBctiqSo,5393
|
6
6
|
utilities/atools.py,sha256=IYMuFSFGSKyuQmqD6v5IUtDlz8PPw0Sr87Cub_gRU3M,1168
|
7
7
|
utilities/cachetools.py,sha256=C1zqOg7BYz0IfQFK8e3qaDDgEZxDpo47F15RTfJM37Q,2910
|
@@ -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
|
27
|
+
utilities/hypothesis.py,sha256=-m9YWVgDkKdBfPkZHJ4-vCOGORVHqgtDhbXllfPrr7o,49873
|
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
|
@@ -78,7 +78,7 @@ utilities/tempfile.py,sha256=VqmZJAhTJ1OaVywFzk5eqROV8iJbW9XQ_QYAV0bpdRo,1384
|
|
78
78
|
utilities/tenacity.py,sha256=1PUvODiBVgeqIh7G5TRt5WWMSqjLYkEqP53itT97WQc,4914
|
79
79
|
utilities/text.py,sha256=ymBFlP_cA8OgNnZRVNs7FAh7OG8HxE6YkiLEMZv5g_A,11297
|
80
80
|
utilities/threading.py,sha256=GvBOp4CyhHfN90wGXZuA2VKe9fGzMaEa7oCl4f3nnPU,1009
|
81
|
-
utilities/timer.py,sha256=
|
81
|
+
utilities/timer.py,sha256=VeSl3ot8-f4D1d3HjjSsgKvjxHJGXd_sW4KcTExOR64,2475
|
82
82
|
utilities/traceback.py,sha256=l9onlqDdW5GCSIFbU_-htBE7KlsvsJdNtGrK6-k0RCQ,8759
|
83
83
|
utilities/types.py,sha256=gP04CcCOyFrG7BgblVCsrrChiuO2x842NDVW-GF7odo,18370
|
84
84
|
utilities/typing.py,sha256=kQWywPcRbFBKmvQBELmgbiqSHsnlo_D0ru53vl6KDeY,13846
|
@@ -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=
|
91
|
+
utilities/whenever2.py,sha256=JHixGl6KibK8GUF13GeBjvWMYsFHRDSXixSo0xMSJFM,5437
|
92
92
|
utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
|
93
93
|
utilities/zoneinfo.py,sha256=tvcgu3QzDxe2suTexi2QzRGpin7VK1TjHa0JYYxT69I,1862
|
94
|
-
dycw_utilities-0.131.
|
95
|
-
dycw_utilities-0.131.
|
96
|
-
dycw_utilities-0.131.
|
97
|
-
dycw_utilities-0.131.
|
94
|
+
dycw_utilities-0.131.8.dist-info/METADATA,sha256=R5VRnHIlEDPgRLMdPF6PWrQ7VwJmzeWBUNpSVIrPTqA,1584
|
95
|
+
dycw_utilities-0.131.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
96
|
+
dycw_utilities-0.131.8.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
|
97
|
+
dycw_utilities-0.131.8.dist-info/RECORD,,
|
utilities/__init__.py
CHANGED
utilities/asyncio.py
CHANGED
@@ -43,6 +43,7 @@ from typing import (
|
|
43
43
|
)
|
44
44
|
|
45
45
|
from typing_extensions import deprecated
|
46
|
+
from whenever import TimeDelta
|
46
47
|
|
47
48
|
from utilities.dataclasses import replace_non_sentinel
|
48
49
|
from utilities.datetime import (
|
@@ -961,11 +962,14 @@ def put_items_nowait(items: Iterable[_T], queue: Queue[_T], /) -> None:
|
|
961
962
|
##
|
962
963
|
|
963
964
|
|
964
|
-
async def sleep_dur(*, duration: Duration | None = None) -> None:
|
965
|
+
async def sleep_dur(*, duration: Duration | TimeDelta | None = None) -> None:
|
965
966
|
"""Sleep which accepts durations."""
|
966
967
|
if duration is None:
|
967
968
|
return
|
968
|
-
|
969
|
+
if isinstance(duration, TimeDelta):
|
970
|
+
await sleep(duration.in_seconds())
|
971
|
+
else:
|
972
|
+
await sleep(datetime_duration_to_float(duration))
|
969
973
|
|
970
974
|
|
971
975
|
##
|
utilities/hypothesis.py
CHANGED
@@ -24,6 +24,7 @@ from typing import (
|
|
24
24
|
override,
|
25
25
|
)
|
26
26
|
|
27
|
+
import hypothesis.strategies
|
27
28
|
from hypothesis import HealthCheck, Phase, Verbosity, assume, settings
|
28
29
|
from hypothesis.errors import InvalidArgument
|
29
30
|
from hypothesis.strategies import (
|
@@ -47,7 +48,7 @@ from hypothesis.strategies import (
|
|
47
48
|
uuids,
|
48
49
|
)
|
49
50
|
from hypothesis.utils.conventions import not_set
|
50
|
-
from whenever import Date, DateDelta
|
51
|
+
from whenever import Date, DateDelta, PlainDateTime, Time, TimeDelta
|
51
52
|
|
52
53
|
from utilities.datetime import (
|
53
54
|
DATETIME_MAX_NAIVE,
|
@@ -89,6 +90,20 @@ from utilities.platform import IS_WINDOWS
|
|
89
90
|
from utilities.sentinel import Sentinel, sentinel
|
90
91
|
from utilities.tempfile import TEMP_DIR, TemporaryDirectory
|
91
92
|
from utilities.version import Version
|
93
|
+
from utilities.whenever2 import (
|
94
|
+
DATE_DELTA_MAX,
|
95
|
+
DATE_DELTA_MIN,
|
96
|
+
DATE_DELTA_PARSABLE_MAX,
|
97
|
+
DATE_DELTA_PARSABLE_MIN,
|
98
|
+
DATE_MAX,
|
99
|
+
DATE_MIN,
|
100
|
+
PLAIN_DATE_TIME_MAX,
|
101
|
+
PLAIN_DATE_TIME_MIN,
|
102
|
+
TIME_DELTA_MAX,
|
103
|
+
TIME_DELTA_MIN,
|
104
|
+
TIME_MAX,
|
105
|
+
TIME_MIN,
|
106
|
+
)
|
92
107
|
from utilities.zoneinfo import UTC, ensure_time_zone
|
93
108
|
|
94
109
|
if TYPE_CHECKING:
|
@@ -97,7 +112,7 @@ if TYPE_CHECKING:
|
|
97
112
|
|
98
113
|
from hypothesis.database import ExampleDatabase
|
99
114
|
from numpy.random import RandomState
|
100
|
-
from whenever import
|
115
|
+
from whenever import ZonedDateTime
|
101
116
|
|
102
117
|
from utilities.numpy import NDArrayB, NDArrayF, NDArrayI, NDArrayO
|
103
118
|
from utilities.types import Duration, Number, RoundMode, TimeZoneLike
|
@@ -170,13 +185,6 @@ def date_deltas_whenever(
|
|
170
185
|
parsable: MaybeSearchStrategy[bool] = False,
|
171
186
|
) -> DateDelta:
|
172
187
|
"""Strategy for generating date deltas."""
|
173
|
-
from utilities.whenever2 import (
|
174
|
-
DATE_DELTA_MAX,
|
175
|
-
DATE_DELTA_MIN,
|
176
|
-
DATE_DELTA_PARSABLE_MAX,
|
177
|
-
DATE_DELTA_PARSABLE_MIN,
|
178
|
-
)
|
179
|
-
|
180
188
|
min_value_, max_value_ = [draw2(draw, v) for v in [min_value, max_value]]
|
181
189
|
match min_value_:
|
182
190
|
case None:
|
@@ -307,8 +315,6 @@ def dates_whenever(
|
|
307
315
|
max_value: MaybeSearchStrategy[Date | None] = None,
|
308
316
|
) -> Date:
|
309
317
|
"""Strategy for generating dates."""
|
310
|
-
from utilities.whenever2 import DATE_MAX, DATE_MIN
|
311
|
-
|
312
318
|
min_value_, max_value_ = [draw2(draw, v) for v in [min_value, max_value]]
|
313
319
|
match min_value_:
|
314
320
|
case None:
|
@@ -1069,10 +1075,6 @@ def plain_datetimes_whenever(
|
|
1069
1075
|
max_value: MaybeSearchStrategy[PlainDateTime | None] = None,
|
1070
1076
|
) -> PlainDateTime:
|
1071
1077
|
"""Strategy for generating plain datetimes."""
|
1072
|
-
from whenever import PlainDateTime
|
1073
|
-
|
1074
|
-
from utilities.whenever2 import PLAIN_DATE_TIME_MAX, PLAIN_DATE_TIME_MIN
|
1075
|
-
|
1076
1078
|
min_value_, max_value_ = [draw2(draw, v) for v in [min_value, max_value]]
|
1077
1079
|
match min_value_:
|
1078
1080
|
case None:
|
@@ -1405,6 +1407,41 @@ def text_printable(
|
|
1405
1407
|
##
|
1406
1408
|
|
1407
1409
|
|
1410
|
+
@composite
|
1411
|
+
def time_deltas_whenever(
|
1412
|
+
draw: DrawFn,
|
1413
|
+
/,
|
1414
|
+
*,
|
1415
|
+
min_value: MaybeSearchStrategy[TimeDelta | None] = None,
|
1416
|
+
max_value: MaybeSearchStrategy[TimeDelta | None] = None,
|
1417
|
+
) -> TimeDelta:
|
1418
|
+
"""Strategy for generating time deltas."""
|
1419
|
+
min_value_, max_value_ = [draw2(draw, v) for v in [min_value, max_value]]
|
1420
|
+
match min_value_:
|
1421
|
+
case None:
|
1422
|
+
min_value_ = TIME_DELTA_MIN
|
1423
|
+
case TimeDelta():
|
1424
|
+
...
|
1425
|
+
case _ as never:
|
1426
|
+
assert_never(never)
|
1427
|
+
match max_value_:
|
1428
|
+
case None:
|
1429
|
+
max_value_ = TIME_DELTA_MAX
|
1430
|
+
case TimeDelta():
|
1431
|
+
...
|
1432
|
+
case _ as never:
|
1433
|
+
assert_never(never)
|
1434
|
+
py_time = draw(
|
1435
|
+
hypothesis.strategies.timedeltas(
|
1436
|
+
min_value=min_value_.py_timedelta(), max_value=max_value_.py_timedelta()
|
1437
|
+
)
|
1438
|
+
)
|
1439
|
+
return TimeDelta.from_py_timedelta(py_time)
|
1440
|
+
|
1441
|
+
|
1442
|
+
##
|
1443
|
+
|
1444
|
+
|
1408
1445
|
@composite
|
1409
1446
|
def timedeltas_2w(
|
1410
1447
|
draw: DrawFn,
|
@@ -1431,6 +1468,41 @@ def timedeltas_2w(
|
|
1431
1468
|
##
|
1432
1469
|
|
1433
1470
|
|
1471
|
+
@composite
|
1472
|
+
def times_whenever(
|
1473
|
+
draw: DrawFn,
|
1474
|
+
/,
|
1475
|
+
*,
|
1476
|
+
min_value: MaybeSearchStrategy[Time | None] = None,
|
1477
|
+
max_value: MaybeSearchStrategy[Time | None] = None,
|
1478
|
+
) -> Time:
|
1479
|
+
"""Strategy for generating times."""
|
1480
|
+
min_value_, max_value_ = [draw2(draw, v) for v in [min_value, max_value]]
|
1481
|
+
match min_value_:
|
1482
|
+
case None:
|
1483
|
+
min_value_ = TIME_MIN
|
1484
|
+
case Time():
|
1485
|
+
...
|
1486
|
+
case _ as never:
|
1487
|
+
assert_never(never)
|
1488
|
+
match max_value_:
|
1489
|
+
case None:
|
1490
|
+
max_value_ = TIME_MAX
|
1491
|
+
case Time():
|
1492
|
+
...
|
1493
|
+
case _ as never:
|
1494
|
+
assert_never(never)
|
1495
|
+
py_time = draw(
|
1496
|
+
hypothesis.strategies.times(
|
1497
|
+
min_value=min_value_.py_time(), max_value=max_value_.py_time()
|
1498
|
+
)
|
1499
|
+
)
|
1500
|
+
return Time.from_py_time(py_time)
|
1501
|
+
|
1502
|
+
|
1503
|
+
##
|
1504
|
+
|
1505
|
+
|
1434
1506
|
def triples(
|
1435
1507
|
strategy: SearchStrategy[_T],
|
1436
1508
|
/,
|
@@ -1651,7 +1723,9 @@ __all__ = [
|
|
1651
1723
|
"text_clean",
|
1652
1724
|
"text_digits",
|
1653
1725
|
"text_printable",
|
1726
|
+
"time_deltas_whenever",
|
1654
1727
|
"timedeltas_2w",
|
1728
|
+
"times_whenever",
|
1655
1729
|
"triples",
|
1656
1730
|
"uint32s",
|
1657
1731
|
"uint64s",
|
utilities/timer.py
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
import datetime as dt
|
4
3
|
from operator import add, eq, ge, gt, le, lt, mul, ne, sub, truediv
|
5
|
-
from
|
6
|
-
|
4
|
+
from typing import TYPE_CHECKING, Any, Self, override
|
5
|
+
|
6
|
+
from utilities.whenever2 import get_now_local
|
7
7
|
|
8
8
|
if TYPE_CHECKING:
|
9
9
|
from collections.abc import Callable
|
10
10
|
|
11
|
-
from
|
11
|
+
from whenever import TimeDelta, ZonedDateTime
|
12
12
|
|
13
13
|
|
14
14
|
class Timer:
|
@@ -16,116 +16,82 @@ class Timer:
|
|
16
16
|
|
17
17
|
def __init__(self) -> None:
|
18
18
|
super().__init__()
|
19
|
-
self._start =
|
20
|
-
self._end:
|
19
|
+
self._start: ZonedDateTime = get_now_local()
|
20
|
+
self._end: ZonedDateTime | None = None
|
21
21
|
|
22
22
|
# arithmetic
|
23
23
|
|
24
|
-
def __add__(self, other: Any) ->
|
25
|
-
|
26
|
-
return dt.timedelta(seconds=self._apply_op(add, other))
|
27
|
-
if isinstance(other, dt.timedelta | Timer):
|
28
|
-
return self._apply_op(add, other)
|
29
|
-
return NotImplemented
|
24
|
+
def __add__(self, other: Any) -> TimeDelta:
|
25
|
+
return self._apply_op(add, other)
|
30
26
|
|
31
27
|
def __float__(self) -> float:
|
32
|
-
|
33
|
-
|
28
|
+
return self.timedelta.in_seconds()
|
29
|
+
|
30
|
+
def __sub__(self, other: Any) -> TimeDelta:
|
31
|
+
return self._apply_op(sub, other)
|
34
32
|
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
return NotImplemented
|
41
|
-
|
42
|
-
def __mul__(self, other: Any) -> dt.timedelta:
|
43
|
-
if isinstance(other, int | float):
|
44
|
-
return dt.timedelta(seconds=self._apply_op(mul, other))
|
45
|
-
return NotImplemented
|
46
|
-
|
47
|
-
@overload
|
48
|
-
def __truediv__(self, other: Number) -> dt.timedelta: ...
|
49
|
-
@overload
|
50
|
-
def __truediv__(self, other: dt.timedelta | Timer) -> float: ...
|
51
|
-
def __truediv__(self, other: Any) -> dt.timedelta | float:
|
52
|
-
if isinstance(other, int | float):
|
53
|
-
return dt.timedelta(seconds=self._apply_op(truediv, other))
|
54
|
-
if isinstance(other, dt.timedelta | Timer):
|
55
|
-
return self._apply_op(truediv, other)
|
56
|
-
return NotImplemented
|
33
|
+
def __mul__(self, other: Any) -> TimeDelta:
|
34
|
+
return self._apply_op(mul, other)
|
35
|
+
|
36
|
+
def __truediv__(self, other: Any) -> TimeDelta:
|
37
|
+
return self._apply_op(truediv, other)
|
57
38
|
|
58
39
|
# context manager
|
59
40
|
|
60
41
|
def __enter__(self) -> Self:
|
61
|
-
self._start =
|
42
|
+
self._start = get_now_local()
|
62
43
|
return self
|
63
44
|
|
64
45
|
def __exit__(self, *_: object) -> bool:
|
65
|
-
self._end =
|
46
|
+
self._end = get_now_local()
|
66
47
|
return False
|
67
48
|
|
68
49
|
# repr
|
69
50
|
|
70
51
|
@override
|
71
52
|
def __repr__(self) -> str:
|
72
|
-
return
|
53
|
+
return self.timedelta.format_common_iso()
|
73
54
|
|
74
55
|
@override
|
75
56
|
def __str__(self) -> str:
|
76
|
-
return
|
57
|
+
return self.timedelta.format_common_iso()
|
77
58
|
|
78
59
|
# comparison
|
79
60
|
|
80
61
|
@override
|
81
62
|
def __eq__(self, other: object) -> bool:
|
82
|
-
|
83
|
-
return self._apply_op(eq, other)
|
84
|
-
return False
|
63
|
+
return self._apply_op(eq, other)
|
85
64
|
|
86
65
|
def __ge__(self, other: Any) -> bool:
|
87
|
-
|
88
|
-
return self._apply_op(ge, other)
|
89
|
-
return NotImplemented
|
66
|
+
return self._apply_op(ge, other)
|
90
67
|
|
91
68
|
def __gt__(self, other: Any) -> bool:
|
92
|
-
|
93
|
-
return self._apply_op(gt, other)
|
94
|
-
return NotImplemented
|
69
|
+
return self._apply_op(gt, other)
|
95
70
|
|
96
71
|
def __le__(self, other: Any) -> bool:
|
97
|
-
|
98
|
-
return self._apply_op(le, other)
|
99
|
-
return NotImplemented
|
72
|
+
return self._apply_op(le, other)
|
100
73
|
|
101
74
|
def __lt__(self, other: Any) -> bool:
|
102
|
-
|
103
|
-
return self._apply_op(lt, other)
|
104
|
-
return NotImplemented
|
75
|
+
return self._apply_op(lt, other)
|
105
76
|
|
106
77
|
@override
|
107
78
|
def __ne__(self, other: object) -> bool:
|
108
|
-
|
109
|
-
return self._apply_op(ne, other)
|
110
|
-
return True
|
79
|
+
return self._apply_op(ne, other)
|
111
80
|
|
112
81
|
# properties
|
113
82
|
|
114
83
|
@property
|
115
|
-
def timedelta(self) ->
|
84
|
+
def timedelta(self) -> TimeDelta:
|
116
85
|
"""The elapsed time, as a `timedelta` object."""
|
117
|
-
|
86
|
+
end_use = get_now_local() if (end := self._end) is None else end
|
87
|
+
return end_use - self._start
|
118
88
|
|
119
89
|
# private
|
120
90
|
|
121
91
|
def _apply_op(self, op: Callable[[Any, Any], Any], other: Any, /) -> Any:
|
122
|
-
if isinstance(other, int | float):
|
123
|
-
return op(float(self), other)
|
124
92
|
if isinstance(other, Timer):
|
125
93
|
return op(self.timedelta, other.timedelta)
|
126
|
-
|
127
|
-
return op(self.timedelta, other)
|
128
|
-
return NotImplemented # pragma: no cover
|
94
|
+
return op(self.timedelta, other)
|
129
95
|
|
130
96
|
|
131
97
|
__all__ = ["Timer"]
|
utilities/whenever2.py
CHANGED
File without changes
|
File without changes
|