dycw-utilities 0.150.10__py3-none-any.whl → 0.150.12__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.150.10.dist-info → dycw_utilities-0.150.12.dist-info}/METADATA +2 -2
- {dycw_utilities-0.150.10.dist-info → dycw_utilities-0.150.12.dist-info}/RECORD +7 -7
- utilities/__init__.py +1 -1
- utilities/period.py +57 -5
- {dycw_utilities-0.150.10.dist-info → dycw_utilities-0.150.12.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.150.10.dist-info → dycw_utilities-0.150.12.dist-info}/entry_points.txt +0 -0
- {dycw_utilities-0.150.10.dist-info → dycw_utilities-0.150.12.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: dycw-utilities
|
3
|
-
Version: 0.150.
|
3
|
+
Version: 0.150.12
|
4
4
|
Author-email: Derek Wan <d.wan@icloud.com>
|
5
5
|
License-File: LICENSE
|
6
6
|
Requires-Python: >=3.12
|
@@ -12,7 +12,7 @@ Provides-Extra: logging
|
|
12
12
|
Requires-Dist: coloredlogs<15.1,>=15.0.1; extra == 'logging'
|
13
13
|
Provides-Extra: test
|
14
14
|
Requires-Dist: dycw-pytest-only<2.2,>=2.1.1; extra == 'test'
|
15
|
-
Requires-Dist: hypothesis<6.137,>=6.136.
|
15
|
+
Requires-Dist: hypothesis<6.137,>=6.136.1; extra == 'test'
|
16
16
|
Requires-Dist: pudb<2025.2,>=2025.1; extra == 'test'
|
17
17
|
Requires-Dist: pytest-asyncio<1.2,>=1.1.0; extra == 'test'
|
18
18
|
Requires-Dist: pytest-cov<6.3,>=6.2.1; extra == 'test'
|
@@ -1,4 +1,4 @@
|
|
1
|
-
utilities/__init__.py,sha256=
|
1
|
+
utilities/__init__.py,sha256=f0cXpht3DHjUGXeay5K4fSvNR_jeHgGWtdP8z2h1Hws,61
|
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=xcOWenTBRS0oat3kg7Sqe51AohNThMQ2ixPL7QCG8hw,5795
|
@@ -44,7 +44,7 @@ utilities/orjson.py,sha256=iJho5gCkTlT2KWSXqopvi24WCxEhM5_fiz17mbNvkGg,40113
|
|
44
44
|
utilities/os.py,sha256=y25oqJoyrkdQ7aU5ShePPXKk6YTwd97x6yEx4UcRYu4,3788
|
45
45
|
utilities/parse.py,sha256=JcJn5yXKhIWXBCwgBdPsyu7Hvcuw6kyEdqvaebCaI9k,17951
|
46
46
|
utilities/pathlib.py,sha256=FnteXeVeMOSc6QTN7oF6UrobjOX9gXv_5tG1slg83W8,8496
|
47
|
-
utilities/period.py,sha256=
|
47
|
+
utilities/period.py,sha256=hsHdAKAstfMzB2Ar5EbxjkbMff3CA-B5wtYNVZOXVXI,10127
|
48
48
|
utilities/pickle.py,sha256=MBT2xZCsv0pH868IXLGKnlcqNx2IRVKYNpRcqiQQqxw,653
|
49
49
|
utilities/platform.py,sha256=Ue9LSxYvg9yUXGKuz5aZoy_qkUEXde-v6B09exgSctU,2813
|
50
50
|
utilities/polars.py,sha256=BgiDryAVOapi41ddfJqN0wYh_sDj8BNEYtPB36LaHdo,71824
|
@@ -89,8 +89,8 @@ utilities/zoneinfo.py,sha256=oEH-nL3t4h9uawyZqWDtNtDAl6M-CLpLYGI_nI6DulM,1971
|
|
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.150.
|
93
|
-
dycw_utilities-0.150.
|
94
|
-
dycw_utilities-0.150.
|
95
|
-
dycw_utilities-0.150.
|
96
|
-
dycw_utilities-0.150.
|
92
|
+
dycw_utilities-0.150.12.dist-info/METADATA,sha256=y8XRkRo0g6VjLy7bzDQOl0cu0H6547VnzBxSAaso5yA,1697
|
93
|
+
dycw_utilities-0.150.12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
94
|
+
dycw_utilities-0.150.12.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
|
95
|
+
dycw_utilities-0.150.12.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
|
96
|
+
dycw_utilities-0.150.12.dist-info/RECORD,,
|
utilities/__init__.py
CHANGED
utilities/period.py
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from typing import TYPE_CHECKING, Any, Self, TypedDict, overload, override
|
4
|
+
from typing import TYPE_CHECKING, Any, Self, TypedDict, assert_never, overload, override
|
5
5
|
from zoneinfo import ZoneInfo
|
6
6
|
|
7
|
-
from whenever import Date, DateDelta, PlainDateTime, TimeDelta, ZonedDateTime
|
7
|
+
from whenever import Date, DateDelta, PlainDateTime, Time, TimeDelta, ZonedDateTime
|
8
8
|
|
9
9
|
from utilities.dataclasses import replace_non_sentinel
|
10
10
|
from utilities.functions import get_class_name
|
11
11
|
from utilities.sentinel import Sentinel, sentinel
|
12
12
|
from utilities.whenever import format_compact
|
13
|
-
from utilities.zoneinfo import get_time_zone_name
|
13
|
+
from utilities.zoneinfo import UTC, ensure_time_zone, get_time_zone_name
|
14
14
|
|
15
15
|
if TYPE_CHECKING:
|
16
16
|
from utilities.types import TimeZoneLike
|
17
17
|
|
18
18
|
|
19
|
-
class _PeriodAsDict[T: (Date, ZonedDateTime)](TypedDict):
|
19
|
+
class _PeriodAsDict[T: (Date, Time, ZonedDateTime)](TypedDict):
|
20
20
|
start: T
|
21
21
|
end: T
|
22
22
|
|
@@ -49,6 +49,22 @@ class DatePeriod:
|
|
49
49
|
"""Offset the period."""
|
50
50
|
return self.replace(start=self.start - other, end=self.end - other)
|
51
51
|
|
52
|
+
def at(
|
53
|
+
self, obj: Time | tuple[Time, Time], /, *, time_zone: TimeZoneLike = UTC
|
54
|
+
) -> ZonedDateTimePeriod:
|
55
|
+
"""Combine a date with a time to create a datetime."""
|
56
|
+
match obj:
|
57
|
+
case Time() as time:
|
58
|
+
start = end = time
|
59
|
+
case Time() as start, Time() as end:
|
60
|
+
...
|
61
|
+
case _ as never:
|
62
|
+
assert_never(never)
|
63
|
+
tz = ensure_time_zone(time_zone).key
|
64
|
+
return ZonedDateTimePeriod(
|
65
|
+
self.start.at(start).assume_tz(tz), self.end.at(end).assume_tz(tz)
|
66
|
+
)
|
67
|
+
|
52
68
|
@property
|
53
69
|
def delta(self) -> DateDelta:
|
54
70
|
"""The delta of the period."""
|
@@ -76,6 +92,42 @@ class DatePeriod:
|
|
76
92
|
return _PeriodAsDict(start=self.start, end=self.end)
|
77
93
|
|
78
94
|
|
95
|
+
@dataclass(repr=False, order=True, unsafe_hash=True, kw_only=False)
|
96
|
+
class TimePeriod:
|
97
|
+
"""A period of times."""
|
98
|
+
|
99
|
+
start: Time
|
100
|
+
end: Time
|
101
|
+
|
102
|
+
@override
|
103
|
+
def __repr__(self) -> str:
|
104
|
+
cls = get_class_name(self)
|
105
|
+
return f"{cls}({self.start}, {self.end})"
|
106
|
+
|
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
|
+
def at(
|
114
|
+
self, obj: Date | tuple[Date, Date], /, *, time_zone: TimeZoneLike = UTC
|
115
|
+
) -> ZonedDateTimePeriod:
|
116
|
+
"""Combine a date with a time to create a datetime."""
|
117
|
+
match obj:
|
118
|
+
case Date() as date:
|
119
|
+
start = end = date
|
120
|
+
case Date() as start, Date() as end:
|
121
|
+
...
|
122
|
+
case _ as never:
|
123
|
+
assert_never(never)
|
124
|
+
return DatePeriod(start, end).at((self.start, self.end), time_zone=time_zone)
|
125
|
+
|
126
|
+
def to_dict(self) -> _PeriodAsDict[Time]:
|
127
|
+
"""Convert the period to a dictionary."""
|
128
|
+
return _PeriodAsDict(start=self.start, end=self.end)
|
129
|
+
|
130
|
+
|
79
131
|
@dataclass(repr=False, order=True, unsafe_hash=True, kw_only=False)
|
80
132
|
class ZonedDateTimePeriod:
|
81
133
|
"""A period of time."""
|
@@ -234,4 +286,4 @@ class _PeriodExactEqArgumentsError(PeriodError):
|
|
234
286
|
return f"Invalid arguments; got {self.args}"
|
235
287
|
|
236
288
|
|
237
|
-
__all__ = ["DatePeriod", "PeriodError", "ZonedDateTimePeriod"]
|
289
|
+
__all__ = ["DatePeriod", "PeriodError", "TimePeriod", "ZonedDateTimePeriod"]
|
File without changes
|
File without changes
|
File without changes
|