dycw-utilities 0.131.14__py3-none-any.whl → 0.131.15__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.14
3
+ Version: 0.131.15
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=NYq6mGcB8IGMU4RPF-m9jjQGEJiGNJEcMMoXW81ZW3E,61
1
+ utilities/__init__.py,sha256=TF72KRTntycdsGaFpyLS49_hW9qrELSmZAvg2kQ0BrA,61
2
2
  utilities/aiolimiter.py,sha256=mD0wEiqMgwpty4XTbawFpnkkmJS6R4JRsVXFUaoitSU,628
3
3
  utilities/altair.py,sha256=HeZBVUocjkrTNwwKrClppsIqgNFF-ykv05HfZSoHYno,9104
4
4
  utilities/asyncio.py,sha256=yfKvAIDCRrWdyQMVZMo4DJQx4nVrXoAcqwhNuF95Ryo,38186
@@ -33,7 +33,7 @@ utilities/jupyter.py,sha256=ft5JA7fBxXKzP-L9W8f2-wbF0QeYc_2uLQNFDVk4Z-M,2917
33
33
  utilities/libcst.py,sha256=Jto5ppzRzsxn4AD32IS8n0lbgLYXwsVJB6EY8giNZyY,4974
34
34
  utilities/lightweight_charts.py,sha256=JrkrAZMo6JID2Eoc9QCc05Y_pK4l2zsApIhmii1z2Ig,2764
35
35
  utilities/logging.py,sha256=zm5k0Cduxtx2H2o7odxUTJtPNkJS85mqHYN1cS5Kc1w,17863
36
- utilities/luigi.py,sha256=fpH9MbxJDuo6-k9iCXRayFRtiVbUtibCJKugf7ygpv0,5988
36
+ utilities/luigi.py,sha256=UAt4TDMtinLAN7sipX0jSvH-aZzHUTQbHB3Rwtbq994,4840
37
37
  utilities/math.py,sha256=_6vrDyjtaqE_OFE-F2DNWrDG_J_kMl3nFAJsok9v_bY,26862
38
38
  utilities/memory_profiler.py,sha256=tf2C51P2lCujPGvRt2Rfc7VEw5LDXmVPCG3z_AvBmbU,962
39
39
  utilities/modules.py,sha256=iuvLluJya-hvl1Q25-Jk3dLgx2Es3ck4SjJiEkAlVTs,3195
@@ -92,7 +92,7 @@ utilities/whenever.py,sha256=2NQ-0SnLNW2kFpefP9dVE8H0RbaeusXYLPmv282Jpto,16755
92
92
  utilities/whenever2.py,sha256=iFVL4CjuIOpzsDU6li5smHnDEqam30-FtTgXWeHuWiE,7510
93
93
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
94
94
  utilities/zoneinfo.py,sha256=gJPr9l7V8s3Y7TXpCGYEM1S81Rplb9e4MoV9Nvy2VU8,1852
95
- dycw_utilities-0.131.14.dist-info/METADATA,sha256=jRiyVj2uOFSRzUZjiKEZHtOXb9Z-uGw3f62yd-FWWb0,1585
96
- dycw_utilities-0.131.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
97
- dycw_utilities-0.131.14.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
98
- dycw_utilities-0.131.14.dist-info/RECORD,,
95
+ dycw_utilities-0.131.15.dist-info/METADATA,sha256=Aztn9G7ACPHL_tGTOBayxzN6aPT_8gmKwsTUcieAoUA,1585
96
+ dycw_utilities-0.131.15.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
97
+ dycw_utilities-0.131.15.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
98
+ dycw_utilities-0.131.15.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.131.14"
3
+ __version__ = "0.131.15"
utilities/luigi.py CHANGED
@@ -2,121 +2,91 @@ from __future__ import annotations
2
2
 
3
3
  from abc import ABC, abstractmethod
4
4
  from pathlib import Path
5
- from typing import TYPE_CHECKING, Any, Literal, cast, overload, override
5
+ from typing import (
6
+ TYPE_CHECKING,
7
+ Any,
8
+ Literal,
9
+ TypeVar,
10
+ assert_never,
11
+ cast,
12
+ overload,
13
+ override,
14
+ )
6
15
 
7
16
  import luigi
8
17
  from luigi import Parameter, PathParameter, Target, Task
9
18
  from luigi import build as _build
10
-
11
- from utilities.datetime import EPOCH_UTC
19
+ from luigi.parameter import ParameterVisibility, _no_value
20
+ from whenever import ZonedDateTime
12
21
 
13
22
  if TYPE_CHECKING:
14
- import datetime as dt
15
- from collections.abc import Iterable
23
+ from collections.abc import Callable, Iterable
16
24
 
17
25
  from luigi.execution_summary import LuigiRunResult
18
26
 
19
- from utilities.types import LogLevel, MaybeStr, PathLike
20
-
21
-
22
- # parameters
23
-
24
-
25
- class DateHourParameter(luigi.DateHourParameter):
26
- """A parameter which takes the value of an hourly `dt.datetime`."""
27
-
28
- def __init__(self, interval: int = 1, **kwargs: Any) -> None:
29
- super().__init__(interval, EPOCH_UTC, **kwargs)
30
-
31
- @override
32
- def normalize(self, dt: MaybeStr[dt.datetime]) -> dt.datetime:
33
- from utilities.whenever import ensure_zoned_datetime
34
-
35
- return ensure_zoned_datetime(dt)
36
-
37
- @override
38
- def parse(self, s: str) -> dt.datetime:
39
- from utilities.whenever import parse_zoned_datetime
40
-
41
- return parse_zoned_datetime(s)
42
-
43
- @override
44
- def serialize(self, dt: dt.datetime) -> str:
45
- from utilities.whenever import serialize_zoned_datetime
46
-
47
- return serialize_zoned_datetime(dt)
48
-
49
-
50
- class DateMinuteParameter(luigi.DateMinuteParameter):
51
- """A parameter which takes the value of a minutely `dt.datetime`."""
52
-
53
- def __init__(self, interval: int = 1, **kwargs: Any) -> None:
54
- super().__init__(interval=interval, start=EPOCH_UTC, **kwargs)
55
-
56
- @override
57
- def normalize(self, dt: MaybeStr[dt.datetime]) -> dt.datetime:
58
- from utilities.whenever import ensure_zoned_datetime
59
-
60
- return ensure_zoned_datetime(dt)
61
-
62
- @override
63
- def parse(self, s: str) -> dt.datetime:
64
- from utilities.whenever import parse_zoned_datetime
65
-
66
- return parse_zoned_datetime(s)
67
-
68
- @override
69
- def serialize(self, dt: dt.datetime) -> str:
70
- from utilities.whenever import serialize_zoned_datetime
71
-
72
- return serialize_zoned_datetime(dt)
73
-
27
+ from utilities.types import DateTimeRoundUnit, LogLevel, PathLike, ZonedDateTimeLike
74
28
 
75
- class DateSecondParameter(luigi.DateSecondParameter):
76
- """A parameter which takes the value of a secondly `dt.datetime`."""
77
29
 
78
- def __init__(self, interval: int = 1, **kwargs: Any) -> None:
79
- super().__init__(interval, EPOCH_UTC, **kwargs)
30
+ _T = TypeVar("_T")
80
31
 
81
- @override
82
- def normalize(self, dt: MaybeStr[dt.datetime]) -> dt.datetime:
83
- from utilities.whenever import ensure_zoned_datetime
84
-
85
- return ensure_zoned_datetime(dt)
86
-
87
- @override
88
- def parse(self, s: str) -> dt.datetime:
89
- from utilities.whenever import parse_zoned_datetime
90
-
91
- return parse_zoned_datetime(s)
92
32
 
93
- @override
94
- def serialize(self, dt: dt.datetime) -> str:
95
- from utilities.whenever import serialize_zoned_datetime
96
-
97
- return serialize_zoned_datetime(dt)
98
-
99
-
100
- class TimeParameter(Parameter):
101
- """A parameter which takes the value of a `dt.time`."""
102
-
103
- @override
104
- def normalize(self, x: MaybeStr[dt.time]) -> dt.time:
105
- from utilities.whenever import ensure_time
106
-
107
- return ensure_time(x)
108
-
109
- @override
110
- def parse(self, x: str) -> dt.time:
111
- from utilities.whenever import parse_time
112
-
113
- return parse_time(x)
33
+ # parameters
114
34
 
115
- @override
116
- def serialize(self, x: dt.time) -> str:
117
- from utilities.whenever import serialize_time
118
35
 
119
- return serialize_time(x)
36
+ class ZonedDateTimeParameter(Parameter):
37
+ """A parameter which takes the value of a zoned datetime."""
38
+
39
+ _unit: DateTimeRoundUnit
40
+ _increment: int
41
+
42
+ @override
43
+ def __init__(
44
+ self,
45
+ default: Any = _no_value,
46
+ is_global: bool = False,
47
+ significant: bool = True,
48
+ description: str | None = None,
49
+ config_path: None = None,
50
+ positional: bool = True,
51
+ always_in_help: bool = False,
52
+ batch_method: Callable[[Iterable[_T]], _T] | None = None,
53
+ visibility: ParameterVisibility = ParameterVisibility.PUBLIC,
54
+ *,
55
+ unit: DateTimeRoundUnit = "second",
56
+ increment: int = 1,
57
+ ) -> None:
58
+ super().__init__(
59
+ default,
60
+ is_global,
61
+ significant,
62
+ description,
63
+ config_path,
64
+ positional,
65
+ always_in_help,
66
+ batch_method,
67
+ visibility,
68
+ )
69
+ self._unit = unit
70
+ self._increment = increment
71
+
72
+ @override
73
+ def normalize(self, x: ZonedDateTimeLike) -> ZonedDateTime:
74
+ match x:
75
+ case ZonedDateTime() as date_time:
76
+ ...
77
+ case str() as text:
78
+ date_time = ZonedDateTime.parse_common_iso(text)
79
+ case _ as never:
80
+ assert_never(never)
81
+ return date_time.round(self._unit, increment=self._increment, mode="floor")
82
+
83
+ @override
84
+ def parse(self, x: str) -> ZonedDateTime:
85
+ return ZonedDateTime.parse_common_iso(x)
86
+
87
+ @override
88
+ def serialize(self, x: ZonedDateTime) -> str:
89
+ return x.format_common_iso()
120
90
 
121
91
 
122
92
  # targets
@@ -217,12 +187,9 @@ def build(
217
187
 
218
188
 
219
189
  __all__ = [
220
- "DateHourParameter",
221
- "DateMinuteParameter",
222
- "DateSecondParameter",
223
190
  "ExternalFile",
224
191
  "ExternalTask",
225
192
  "PathTarget",
226
- "TimeParameter",
193
+ "ZonedDateTimeParameter",
227
194
  "build",
228
195
  ]