dycw-utilities 0.117.1__py3-none-any.whl → 0.119.0__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.117.1
3
+ Version: 0.119.0
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -26,7 +26,7 @@ Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-altair'
26
26
  Requires-Dist: img2pdf<0.7,>=0.6.0; extra == 'zzz-test-altair'
27
27
  Requires-Dist: polars-lts-cpu<1.30,>=1.29.0; extra == 'zzz-test-altair'
28
28
  Requires-Dist: vl-convert-python<1.8,>=1.7.0; extra == 'zzz-test-altair'
29
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-altair'
29
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-altair'
30
30
  Provides-Extra: zzz-test-astor
31
31
  Requires-Dist: astor<0.9,>=0.8.1; extra == 'zzz-test-astor'
32
32
  Provides-Extra: zzz-test-asyncio
@@ -39,20 +39,20 @@ Requires-Dist: cachetools<5.6,>=5.5.2; extra == 'zzz-test-cachetools'
39
39
  Provides-Extra: zzz-test-click
40
40
  Requires-Dist: click<8.3,>=8.2.0; extra == 'zzz-test-click'
41
41
  Requires-Dist: sqlalchemy<2.1,>=2.0.41; extra == 'zzz-test-click'
42
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-click'
42
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-click'
43
43
  Provides-Extra: zzz-test-contextlib
44
44
  Provides-Extra: zzz-test-contextvars
45
45
  Provides-Extra: zzz-test-cryptography
46
- Requires-Dist: cryptography<46.0,>=45.0.2; extra == 'zzz-test-cryptography'
46
+ Requires-Dist: cryptography<45.1,>=45.0.2; extra == 'zzz-test-cryptography'
47
47
  Provides-Extra: zzz-test-cvxpy
48
48
  Requires-Dist: cvxpy<1.7,>=1.6.5; extra == 'zzz-test-cvxpy'
49
49
  Provides-Extra: zzz-test-dataclasses
50
50
  Requires-Dist: orjson<3.11,>=3.10.15; extra == 'zzz-test-dataclasses'
51
51
  Requires-Dist: polars-lts-cpu<1.30,>=1.29.0; extra == 'zzz-test-dataclasses'
52
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-dataclasses'
52
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-dataclasses'
53
53
  Provides-Extra: zzz-test-datetime
54
54
  Requires-Dist: tzlocal<5.4,>=5.3.1; extra == 'zzz-test-datetime'
55
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-datetime'
55
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-datetime'
56
56
  Provides-Extra: zzz-test-enum
57
57
  Provides-Extra: zzz-test-errors
58
58
  Provides-Extra: zzz-test-eventkit
@@ -71,29 +71,29 @@ Provides-Extra: zzz-test-git
71
71
  Provides-Extra: zzz-test-hashlib
72
72
  Requires-Dist: orjson<3.11,>=3.10.15; extra == 'zzz-test-hashlib'
73
73
  Requires-Dist: polars-lts-cpu<1.30,>=1.29.0; extra == 'zzz-test-hashlib'
74
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-hashlib'
74
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-hashlib'
75
75
  Provides-Extra: zzz-test-http
76
76
  Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-http'
77
77
  Requires-Dist: orjson<3.11,>=3.10.18; extra == 'zzz-test-http'
78
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-http'
78
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-http'
79
79
  Provides-Extra: zzz-test-hypothesis
80
80
  Requires-Dist: aiosqlite<0.22,>=0.21.0; extra == 'zzz-test-hypothesis'
81
81
  Requires-Dist: asyncpg<0.31,>=0.30.0; extra == 'zzz-test-hypothesis'
82
82
  Requires-Dist: greenlet<3.3,>=3.2.0; extra == 'zzz-test-hypothesis'
83
83
  Requires-Dist: hypothesis<6.132,>=6.131.19; extra == 'zzz-test-hypothesis'
84
84
  Requires-Dist: luigi<3.7,>=3.6.0; extra == 'zzz-test-hypothesis'
85
- Requires-Dist: numpy<2.3,>=2.2.5; extra == 'zzz-test-hypothesis'
85
+ Requires-Dist: numpy<2.3,>=2.2.6; extra == 'zzz-test-hypothesis'
86
86
  Requires-Dist: pathvalidate<3.3,>=3.2.3; extra == 'zzz-test-hypothesis'
87
87
  Requires-Dist: redis<6.2,>=6.1.0; extra == 'zzz-test-hypothesis'
88
88
  Requires-Dist: sqlalchemy<2.1,>=2.0.41; extra == 'zzz-test-hypothesis'
89
89
  Requires-Dist: tenacity<9.0,>=8.5.0; extra == 'zzz-test-hypothesis'
90
90
  Requires-Dist: tzlocal<5.4,>=5.3.1; extra == 'zzz-test-hypothesis'
91
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-hypothesis'
91
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-hypothesis'
92
92
  Provides-Extra: zzz-test-ipython
93
93
  Requires-Dist: ipython<9.1,>=9.0.1; extra == 'zzz-test-ipython'
94
94
  Provides-Extra: zzz-test-iterables
95
95
  Requires-Dist: polars-lts-cpu<1.30,>=1.29.0; extra == 'zzz-test-iterables'
96
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-iterables'
96
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-iterables'
97
97
  Provides-Extra: zzz-test-jupyter
98
98
  Requires-Dist: jupyterlab<4.3,>=4.2.0; extra == 'zzz-test-jupyter'
99
99
  Requires-Dist: pandas<2.3,>=2.2.2; extra == 'zzz-test-jupyter'
@@ -105,24 +105,24 @@ Requires-Dist: concurrent-log-handler<0.10,>=0.9.26; extra == 'zzz-test-logging'
105
105
  Requires-Dist: rich<14.1,>=14.0.0; extra == 'zzz-test-logging'
106
106
  Requires-Dist: tomlkit<0.14,>=0.13.2; extra == 'zzz-test-logging'
107
107
  Requires-Dist: tzlocal<5.4,>=5.3.1; extra == 'zzz-test-logging'
108
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-logging'
108
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-logging'
109
109
  Provides-Extra: zzz-test-loguru
110
110
  Requires-Dist: loguru<0.8,>=0.7.3; extra == 'zzz-test-loguru'
111
111
  Provides-Extra: zzz-test-luigi
112
112
  Requires-Dist: luigi<3.7,>=3.6.0; extra == 'zzz-test-luigi'
113
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-luigi'
113
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-luigi'
114
114
  Provides-Extra: zzz-test-math
115
- Requires-Dist: numpy<2.3,>=2.2.5; extra == 'zzz-test-math'
115
+ Requires-Dist: numpy<2.3,>=2.2.6; extra == 'zzz-test-math'
116
116
  Provides-Extra: zzz-test-memory-profiler
117
117
  Requires-Dist: memory-profiler<0.62,>=0.61.0; extra == 'zzz-test-memory-profiler'
118
118
  Provides-Extra: zzz-test-modules
119
119
  Provides-Extra: zzz-test-more-itertools
120
120
  Requires-Dist: more-itertools<10.8,>=10.7.0; extra == 'zzz-test-more-itertools'
121
121
  Provides-Extra: zzz-test-numpy
122
- Requires-Dist: numpy<2.3,>=2.2.5; extra == 'zzz-test-numpy'
122
+ Requires-Dist: numpy<2.3,>=2.2.6; extra == 'zzz-test-numpy'
123
123
  Provides-Extra: zzz-test-operator
124
124
  Requires-Dist: polars-lts-cpu<1.30,>=1.29.0; extra == 'zzz-test-operator'
125
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-operator'
125
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-operator'
126
126
  Provides-Extra: zzz-test-optuna
127
127
  Requires-Dist: optuna<4.4,>=4.3.0; extra == 'zzz-test-optuna'
128
128
  Provides-Extra: zzz-test-orjson
@@ -130,7 +130,7 @@ Requires-Dist: orjson<3.11,>=3.10.15; extra == 'zzz-test-orjson'
130
130
  Requires-Dist: polars-lts-cpu<1.30,>=1.29.0; extra == 'zzz-test-orjson'
131
131
  Requires-Dist: rich<14.1,>=14.0.0; extra == 'zzz-test-orjson'
132
132
  Requires-Dist: tzlocal<5.4,>=5.3.1; extra == 'zzz-test-orjson'
133
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-orjson'
133
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-orjson'
134
134
  Provides-Extra: zzz-test-os
135
135
  Provides-Extra: zzz-test-pathlib
136
136
  Provides-Extra: zzz-test-pickle
@@ -138,7 +138,7 @@ Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-pickle'
138
138
  Provides-Extra: zzz-test-platform
139
139
  Provides-Extra: zzz-test-polars
140
140
  Requires-Dist: polars-lts-cpu<1.30,>=1.29.0; extra == 'zzz-test-polars'
141
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-polars'
141
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-polars'
142
142
  Provides-Extra: zzz-test-pqdm
143
143
  Requires-Dist: pqdm<0.3,>=0.2.0; extra == 'zzz-test-pqdm'
144
144
  Provides-Extra: zzz-test-pydantic
@@ -153,12 +153,12 @@ Requires-Dist: pyrsistent<0.21,>=0.20.0; extra == 'zzz-test-pyrsistent'
153
153
  Provides-Extra: zzz-test-pytest
154
154
  Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-pytest'
155
155
  Requires-Dist: orjson<3.11,>=3.10.18; extra == 'zzz-test-pytest'
156
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-pytest'
156
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-pytest'
157
157
  Provides-Extra: zzz-test-pytest-regressions
158
158
  Requires-Dist: pytest-regressions<2.8,>=2.7.0; extra == 'zzz-test-pytest-regressions'
159
159
  Provides-Extra: zzz-test-python-dotenv
160
160
  Requires-Dist: python-dotenv<1.2,>=1.1.0; extra == 'zzz-test-python-dotenv'
161
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-python-dotenv'
161
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-python-dotenv'
162
162
  Provides-Extra: zzz-test-random
163
163
  Provides-Extra: zzz-test-re
164
164
  Provides-Extra: zzz-test-redis
@@ -168,7 +168,7 @@ Requires-Dist: redis<6.2,>=6.1.0; extra == 'zzz-test-redis'
168
168
  Requires-Dist: rich<14.1,>=14.0.0; extra == 'zzz-test-redis'
169
169
  Requires-Dist: tenacity<9.0,>=8.5.0; extra == 'zzz-test-redis'
170
170
  Requires-Dist: tzlocal<5.4,>=5.3.1; extra == 'zzz-test-redis'
171
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-redis'
171
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-redis'
172
172
  Provides-Extra: zzz-test-rich
173
173
  Requires-Dist: rich<14.1,>=14.0.0; extra == 'zzz-test-rich'
174
174
  Provides-Extra: zzz-test-scipy
@@ -194,7 +194,7 @@ Requires-Dist: nest-asyncio<1.7,>=1.6.0; extra == 'zzz-test-sqlalchemy-polars'
194
194
  Requires-Dist: polars-lts-cpu<1.30,>=1.29.0; extra == 'zzz-test-sqlalchemy-polars'
195
195
  Requires-Dist: sqlalchemy<2.1,>=2.0.41; extra == 'zzz-test-sqlalchemy-polars'
196
196
  Requires-Dist: tenacity<9.0,>=8.5.0; extra == 'zzz-test-sqlalchemy-polars'
197
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-sqlalchemy-polars'
197
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-sqlalchemy-polars'
198
198
  Provides-Extra: zzz-test-streamlit
199
199
  Requires-Dist: streamlit<1.46,>=1.45.0; extra == 'zzz-test-streamlit'
200
200
  Provides-Extra: zzz-test-sys
@@ -202,7 +202,7 @@ Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-sys'
202
202
  Requires-Dist: rich<14.1,>=14.0.0; extra == 'zzz-test-sys'
203
203
  Requires-Dist: tomlkit<0.14,>=0.13.2; extra == 'zzz-test-sys'
204
204
  Requires-Dist: tzlocal<5.4,>=5.3.1; extra == 'zzz-test-sys'
205
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-sys'
205
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-sys'
206
206
  Provides-Extra: zzz-test-tempfile
207
207
  Provides-Extra: zzz-test-tenacity
208
208
  Requires-Dist: tenacity<9.0,>=8.5.0; extra == 'zzz-test-tenacity'
@@ -213,11 +213,11 @@ Provides-Extra: zzz-test-traceback
213
213
  Requires-Dist: rich<14.1,>=14.0.0; extra == 'zzz-test-traceback'
214
214
  Requires-Dist: tomlkit<0.14,>=0.13.2; extra == 'zzz-test-traceback'
215
215
  Requires-Dist: tzlocal<5.4,>=5.3.1; extra == 'zzz-test-traceback'
216
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-traceback'
216
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-traceback'
217
217
  Provides-Extra: zzz-test-types
218
218
  Provides-Extra: zzz-test-typing
219
219
  Requires-Dist: polars-lts-cpu<1.30,>=1.29.0; extra == 'zzz-test-typing'
220
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-typing'
220
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-typing'
221
221
  Provides-Extra: zzz-test-tzlocal
222
222
  Requires-Dist: tzlocal<5.4,>=5.3.1; extra == 'zzz-test-tzlocal'
223
223
  Provides-Extra: zzz-test-uuid
@@ -225,11 +225,11 @@ Provides-Extra: zzz-test-version
225
225
  Requires-Dist: tomlkit<0.14,>=0.13.2; extra == 'zzz-test-version'
226
226
  Provides-Extra: zzz-test-warnings
227
227
  Provides-Extra: zzz-test-whenever
228
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-whenever'
228
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-whenever'
229
229
  Provides-Extra: zzz-test-zipfile
230
230
  Provides-Extra: zzz-test-zoneinfo
231
231
  Requires-Dist: tzdata<2025.3,>=2025.2; extra == 'zzz-test-zoneinfo'
232
- Requires-Dist: whenever<0.8,>=0.7.3; extra == 'zzz-test-zoneinfo'
232
+ Requires-Dist: whenever<0.9,>=0.8.0; extra == 'zzz-test-zoneinfo'
233
233
  Description-Content-Type: text/markdown
234
234
 
235
235
  [![PyPI version](https://badge.fury.io/py/dycw-utilities.svg)](https://badge.fury.io/py/dycw-utilities)
@@ -1,22 +1,22 @@
1
- utilities/__init__.py,sha256=3AZFp33-B-_k917jGyOdDiXXC3IjJevPa1TRWy9GCgs,60
1
+ utilities/__init__.py,sha256=ayFWZ1qOKB0Lqd63WRIXSBg4vZDal1xvPPVJr5LEPEA,60
2
2
  utilities/altair.py,sha256=Gpja-flOo-Db0PIPJLJsgzAlXWoKUjPU1qY-DQ829ek,9156
3
3
  utilities/astor.py,sha256=xuDUkjq0-b6fhtwjhbnebzbqQZAjMSHR1IIS5uOodVg,777
4
- utilities/asyncio.py,sha256=R_UJvKhbhjUKxzotJUoFiE05pVy5Y6rQqwJodAjFMHY,25443
4
+ utilities/asyncio.py,sha256=HGX79AKzpQbbDBW3paxAXrhWYeudcJjiO1ETU40d_-8,18463
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
8
- utilities/click.py,sha256=Jzm7DOI3rH-WLOTh1UHOfxkFhHU4_GJH60seLV0A-OI,14311
8
+ utilities/click.py,sha256=SRVkUkWxyO_7AaYvvDl0hNCzdpneX04lf1O97i9MfPw,14311
9
9
  utilities/concurrent.py,sha256=s2scTEd2AhXVTW4hpASU2qxV_DiVLALfms55cCQzCvM,2886
10
10
  utilities/contextlib.py,sha256=OOIIEa5lXKGzFAnauaul40nlQnQko6Na4ryiMJcHkIg,478
11
11
  utilities/contextvars.py,sha256=RsSGGrbQqqZ67rOydnM7WWIsM2lIE31UHJLejnHJPWY,505
12
12
  utilities/cryptography.py,sha256=_CiK_K6c_-uQuUhsUNjNjTL-nqxAh4_1zTfS11Xe120,972
13
13
  utilities/cvxpy.py,sha256=Rv1-fD-XYerosCavRF8Pohop2DBkU3AlFaGTfD8AEAA,13776
14
14
  utilities/dataclasses.py,sha256=iiC1wpGXWhaocIikzwBt8bbLWyImoUlOlcDZJGejaIg,33011
15
- utilities/datetime.py,sha256=VOwjPibw63Myv-CRYhT2eEHpz277GqUiEDEaI7p-nQw,38985
15
+ utilities/datetime.py,sha256=uYoaOi_C1YtNXGfTN9xlTrW62Re2b1_4Skuv14_MeYQ,38985
16
16
  utilities/enum.py,sha256=HoRwVCWzsnH0vpO9ZEcAAIZLMv0Sn2vJxxA4sYMQgDs,5793
17
17
  utilities/errors.py,sha256=gxsaa7eq7jbYl41Of40-ivjXqJB5gt4QAcJ0smZZMJE,829
18
18
  utilities/eventkit.py,sha256=6M5Xu1SzN-juk9PqBHwy5dS-ta7T0qA6SMpDsakOJ0E,13039
19
- utilities/fastapi.py,sha256=y-35at3005jzlNx2wJoiSvB1Ch5bMo30wgU_so3IDdI,2467
19
+ utilities/fastapi.py,sha256=eiisloI6kQVCkPfDpBzlLrDZDi8yJ0VmrSPlJ2k84Mo,2334
20
20
  utilities/fpdf2.py,sha256=y1NGXR5chWqLXWpewGV3hlRGMr_5yV1lVRkPBhPEgJI,1843
21
21
  utilities/functions.py,sha256=jgt592voaHNtX56qX0SRvFveVCRmSIxCZmqvpLZCnY8,27305
22
22
  utilities/functools.py,sha256=WrpHt7NLNWSUn9A1Q_ZIWlNaYZOEI4IFKyBG9HO3BC4,1643
@@ -24,7 +24,7 @@ utilities/getpass.py,sha256=DfN5UgMAtFCqS3dSfFHUfqIMZX2shXvwphOz_6J6f6A,103
24
24
  utilities/git.py,sha256=wpt5dZ5Oi5931pN24_VLZYaQOvmR0OcQuVtgHzFUN1k,2359
25
25
  utilities/hashlib.py,sha256=SVTgtguur0P4elppvzOBbLEjVM3Pea0eWB61yg2ilxo,309
26
26
  utilities/http.py,sha256=WcahTcKYRtZ04WXQoWt5EGCgFPcyHD3EJdlMfxvDt-0,946
27
- utilities/hypothesis.py,sha256=OpZhPdPmsYWvqMytFDc-G196eODosUzxQSuo-LfMYmM,46262
27
+ utilities/hypothesis.py,sha256=a75izXg9aCBhhDkj_ZgK3TDzlzk38evP8TO7JbYYQvg,46264
28
28
  utilities/importlib.py,sha256=ueY3R39hWrUtrVXs39utM2xDig-eyJfYn1FBVxWb3_w,368
29
29
  utilities/ipython.py,sha256=V2oMYHvEKvlNBzxDXdLvKi48oUq2SclRg5xasjaXStw,763
30
30
  utilities/iterables.py,sha256=prKXBdF5QfLTGC-q4567DwO8xzUng_Z-2a4wBkMqyDo,45360
@@ -40,11 +40,11 @@ utilities/more_itertools.py,sha256=6T0225gBFZtv47-B0JRFOKMz836Wg3Hct79ePPLGpuo,5
40
40
  utilities/numpy.py,sha256=Xn23sA2ZbVNqwUYEgNJD3XBYH6IbCri_WkHSNhg3NkY,26122
41
41
  utilities/operator.py,sha256=0M2yZJ0PODH47ogFEnkGMBe_cfxwZR02T_92LZVZvHo,3715
42
42
  utilities/optuna.py,sha256=loyJGWTzljgdJaoLhP09PT8Jz6o_pwBOwehY33lHkhw,1923
43
- utilities/orjson.py,sha256=DBm2zPP04kcHpY3l1etL24ksNynu-R3duFyx3U-RjqQ,36948
43
+ utilities/orjson.py,sha256=AvPFxzJdxC-3PBID3cqdiMyN8FeC7aW9QUgGwbvKuAM,36948
44
44
  utilities/os.py,sha256=D_FyyT-6TtqiN9KSS7c9g1fnUtgxmyMtzAjmYLkk46A,3587
45
45
  utilities/parse.py,sha256=vsZ2jf_ceSI_Kta9titixufysJaVXh0Whjz1T4awJZw,18938
46
46
  utilities/pathlib.py,sha256=31WPMXdLIyXgYOMMl_HOI2wlo66MGSE-cgeelk-Lias,1410
47
- utilities/period.py,sha256=RWfcNVoNlW07RNdU47g_zuLZMKbtgfK4bE6G-9tVjY8,11024
47
+ utilities/period.py,sha256=o4wXYEXVlFomop4-Ra4L0yRP4i99NZFjIe_fa7NdZck,11024
48
48
  utilities/pickle.py,sha256=Bhvd7cZl-zQKQDFjUerqGuSKlHvnW1K2QXeU5UZibtg,657
49
49
  utilities/platform.py,sha256=NU7ycTvAXAG-fdYmDXaM1m4EOml2cGiaYwaUzfzSqyU,1767
50
50
  utilities/polars.py,sha256=fxfSm4xVHwKvRxu50IhYNKCKOagp12FdwsVf04ARKpk,63692
@@ -59,15 +59,15 @@ utilities/pytest_regressions.py,sha256=-SVT9647Dg6-JcdsiaDKXe3NdOmmrvGevLKWwGjxq
59
59
  utilities/python_dotenv.py,sha256=iWcnpXbH7S6RoXHiLlGgyuH6udCupAcPd_gQ0eAenQ0,3190
60
60
  utilities/random.py,sha256=lYdjgxB7GCfU_fwFVl5U-BIM_HV3q6_urL9byjrwDM8,4157
61
61
  utilities/re.py,sha256=5J4d8VwIPFVrX2Eb8zfoxImDv7IwiN_U7mJ07wR2Wvs,3958
62
- utilities/redis.py,sha256=P766qKT2SkDeKa9PpPEZIPCnAc2QDIi35ow2EEHGd20,27225
62
+ utilities/redis.py,sha256=OHw3J2dBA5QssDluKXAG1zIAK2mJJTd6uBuf_1YQuAE,26646
63
63
  utilities/reprlib.py,sha256=Re9bk3n-kC__9DxQmRlevqFA86pE6TtVfWjUgpbVOv0,1849
64
64
  utilities/rich.py,sha256=t50MwwVBsoOLxzmeVFSVpjno4OW6Ufum32skXbV8-Bs,1911
65
65
  utilities/scipy.py,sha256=X6ROnHwiUhAmPhM0jkfEh0-Fd9iRvwiqtCQMOLmOQF8,945
66
66
  utilities/sentinel.py,sha256=3jIwgpMekWgDAxPDA_hXMP2St43cPhciKN3LWiZ7kv0,1248
67
67
  utilities/shelve.py,sha256=HZsMwK4tcIfg3sh0gApx4-yjQnrY4o3V3ZRimvRhoW0,738
68
- utilities/slack_sdk.py,sha256=wPqn9F5AMXgmkp3zgIrBMllLt2SDCCnBNNyi-ag3yzw,5555
68
+ utilities/slack_sdk.py,sha256=NLHmWYK6wc5bz4CGImugXceaToasNBLSqA5sd5ld2r4,3307
69
69
  utilities/socket.py,sha256=K77vfREvzoVTrpYKo6MZakol0EYu2q1sWJnnZqL0So0,118
70
- utilities/sqlalchemy.py,sha256=585hWuuXVTKTnyn0Pfd9JI6jp-hmKW6pLKGYMjXjytM,36959
70
+ utilities/sqlalchemy.py,sha256=09stMwvmI68zlk-DSy9GDk5_YxcMddLh87RPC8Bs4yY,35469
71
71
  utilities/sqlalchemy_polars.py,sha256=wjJpoUo-yO9E2ujpG_06vV5r2OdvBiQ4yvV6wKCa2Tk,15605
72
72
  utilities/statsmodels.py,sha256=koyiBHvpMcSiBfh99wFUfSggLNx7cuAw3rwyfAhoKpQ,3410
73
73
  utilities/streamlit.py,sha256=U9PJBaKP1IdSykKhPZhIzSPTZsmLsnwbEPZWzNhJPKk,2955
@@ -85,10 +85,10 @@ utilities/tzlocal.py,sha256=3upDNFBvGh1l9njmLR2z2S6K6VxQSb7QizYGUbAH3JU,960
85
85
  utilities/uuid.py,sha256=jJTFxz-CWgltqNuzmythB7iEQ-Q1mCwPevUfKthZT3c,611
86
86
  utilities/version.py,sha256=QFuyEeQA6jI0ruBEcmhqG36f-etg1AEiD1drBBqhQrs,5358
87
87
  utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
88
- utilities/whenever.py,sha256=fC0ZtnO0AyFHsxP4SWj0POI1bf4BIL3Hh4rR51BHfaw,17803
88
+ utilities/whenever.py,sha256=jS31ZAY5OMxFxLja_Yo5Fidi87Pd-GoVZ7Vi_teqVDA,16743
89
89
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
90
- utilities/zoneinfo.py,sha256=-Xm57PMMwDTYpxJdkiJG13wnbwK--I7XItBh5WVhD-o,1874
91
- dycw_utilities-0.117.1.dist-info/METADATA,sha256=jFmm81hWyjNuttvOK52BPLHNdskY53ciWAA7CLMYy_I,12943
92
- dycw_utilities-0.117.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
- dycw_utilities-0.117.1.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
94
- dycw_utilities-0.117.1.dist-info/RECORD,,
90
+ utilities/zoneinfo.py,sha256=-5j7IQ9nb7gR43rdgA7ms05im-XuqhAk9EJnQBXxCoQ,1874
91
+ dycw_utilities-0.119.0.dist-info/METADATA,sha256=XG8mqNyIqDEemm7CPwNSAdYJS_z_rsP8SqlYoT-DEAY,12943
92
+ dycw_utilities-0.119.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
+ dycw_utilities-0.119.0.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
94
+ dycw_utilities-0.119.0.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.117.1"
3
+ __version__ = "0.119.0"
utilities/asyncio.py CHANGED
@@ -3,7 +3,6 @@ from __future__ import annotations
3
3
  import datetime as dt
4
4
  from abc import ABC, abstractmethod
5
5
  from asyncio import (
6
- CancelledError,
7
6
  Event,
8
7
  PriorityQueue,
9
8
  Queue,
@@ -13,17 +12,11 @@ from asyncio import (
13
12
  Task,
14
13
  TaskGroup,
15
14
  create_subprocess_shell,
16
- create_task,
17
15
  sleep,
18
16
  timeout,
19
17
  )
20
18
  from collections.abc import Callable, Hashable, Iterable, Iterator, Mapping
21
- from contextlib import (
22
- AsyncExitStack,
23
- _AsyncGeneratorContextManager,
24
- asynccontextmanager,
25
- suppress,
26
- )
19
+ from contextlib import _AsyncGeneratorContextManager, asynccontextmanager
27
20
  from dataclasses import dataclass, field
28
21
  from io import StringIO
29
22
  from logging import getLogger
@@ -35,7 +28,6 @@ from typing import (
35
28
  Generic,
36
29
  Literal,
37
30
  NoReturn,
38
- Self,
39
31
  TextIO,
40
32
  TypeVar,
41
33
  assert_never,
@@ -44,7 +36,6 @@ from typing import (
44
36
  )
45
37
 
46
38
  from utilities.datetime import (
47
- MILLISECOND,
48
39
  MINUTE,
49
40
  SECOND,
50
41
  datetime_duration_to_float,
@@ -52,7 +43,7 @@ from utilities.datetime import (
52
43
  get_now,
53
44
  round_datetime,
54
45
  )
55
- from utilities.errors import ImpossibleCaseError, repr_error
46
+ from utilities.errors import repr_error
56
47
  from utilities.functions import ensure_int, ensure_not_none, get_class_name
57
48
  from utilities.reprlib import get_repr
58
49
  from utilities.sentinel import Sentinel, sentinel
@@ -69,7 +60,6 @@ if TYPE_CHECKING:
69
60
  from asyncio.subprocess import Process
70
61
  from collections.abc import AsyncIterator, Sequence
71
62
  from contextvars import Context
72
- from types import TracebackType
73
63
 
74
64
  from utilities.types import Duration
75
65
 
@@ -80,120 +70,6 @@ _T = TypeVar("_T")
80
70
  ##
81
71
 
82
72
 
83
- @dataclass(kw_only=True)
84
- class AsyncService(ABC):
85
- """A long-running, asynchronous service."""
86
-
87
- duration: Duration | None = None
88
- _await_upon_aenter: bool = field(default=True, init=False, repr=False)
89
- _event: Event = field(default_factory=Event, init=False, repr=False)
90
- _stack: AsyncExitStack = field(
91
- default_factory=AsyncExitStack, init=False, repr=False
92
- )
93
- _state: bool = field(default=False, init=False, repr=False)
94
- _task: Task[None] | None = field(default=None, init=False, repr=False)
95
- _depth: int = field(default=0, init=False, repr=False)
96
-
97
- async def __aenter__(self) -> Self:
98
- """Context manager entry."""
99
- if (self._task is None) and (self._depth == 0):
100
- _ = await self._stack.__aenter__()
101
- self._task = create_task(self._start_runner())
102
- if self._await_upon_aenter:
103
- with suppress(CancelledError):
104
- await self._task
105
- elif (self._task is not None) and (self._depth >= 1):
106
- ...
107
- else:
108
- raise ImpossibleCaseError( # pragma: no cover
109
- case=[f"{self._task=}", f"{self._depth=}"]
110
- )
111
- self._depth += 1
112
- return self
113
-
114
- async def __aexit__(
115
- self,
116
- exc_type: type[BaseException] | None = None,
117
- exc_value: BaseException | None = None,
118
- traceback: TracebackType | None = None,
119
- ) -> None:
120
- """Context manager exit."""
121
- _ = (exc_type, exc_value, traceback)
122
- if (self._task is None) or (self._depth == 0):
123
- raise ImpossibleCaseError( # pragma: no cover
124
- case=[f"{self._task=}", f"{self._depth=}"]
125
- )
126
- self._state = False
127
- self._depth -= 1
128
- if self._depth == 0:
129
- _ = await self._stack.__aexit__(exc_type, exc_value, traceback)
130
- await self.stop()
131
- with suppress(CancelledError):
132
- await self._task
133
- self._task = None
134
-
135
- @abstractmethod
136
- async def _start(self) -> None:
137
- """Start the service."""
138
-
139
- async def _start_runner(self) -> None:
140
- """Coroutine to start the service."""
141
- if self.duration is None:
142
- _ = await self._start()
143
- _ = await self._event.wait()
144
- else:
145
- try:
146
- async with timeout_dur(duration=self.duration):
147
- _ = await self._start()
148
- except TimeoutError:
149
- await self.stop()
150
-
151
- async def stop(self) -> None:
152
- """Stop the service."""
153
- if self._task is None:
154
- raise ImpossibleCaseError(case=[f"{self._task=}"]) # pragma: no cover
155
- with suppress(CancelledError):
156
- _ = self._task.cancel()
157
-
158
-
159
- ##
160
-
161
-
162
- @dataclass(kw_only=True)
163
- class AsyncLoopingService(AsyncService):
164
- """A long-running, asynchronous service which loops a core function."""
165
-
166
- sleep: Duration = MILLISECOND
167
- _await_upon_aenter: bool = field(default=True, init=False, repr=False)
168
-
169
- @abstractmethod
170
- async def _run(self) -> None:
171
- """Run the core function once."""
172
- raise NotImplementedError # pragma: no cover
173
-
174
- async def _run_failure(self, error: Exception, /) -> None:
175
- """Process the failure."""
176
- raise error
177
-
178
- @override
179
- async def _start(self) -> None:
180
- """Start the service, assuming no task is present."""
181
- while True:
182
- try:
183
- await self._run()
184
- except CancelledError:
185
- await self.stop()
186
- break
187
- except Exception as error: # noqa: BLE001
188
- await self._run_failure(error)
189
- await sleep_dur(duration=self.sleep)
190
- else:
191
- await sleep_dur(duration=self.sleep)
192
-
193
-
194
- ##
195
-
196
-
197
73
  class EnhancedTaskGroup(TaskGroup):
198
74
  """Task group with enhanced features."""
199
75
 
@@ -245,100 +121,6 @@ class EnhancedTaskGroup(TaskGroup):
245
121
  ##
246
122
 
247
123
 
248
- @dataclass(kw_only=True)
249
- class QueueProcessor(AsyncService, Generic[_T]):
250
- """Process a set of items in a queue."""
251
-
252
- queue_type: type[Queue[_T]] = field(default=Queue, repr=False)
253
- queue_max_size: int | None = field(default=None, repr=False)
254
- sleep: Duration = MILLISECOND
255
- _await_upon_aenter: bool = field(default=False, init=False, repr=False)
256
- _queue: Queue[_T] = field(init=False, repr=False)
257
-
258
- def __post_init__(self) -> None:
259
- self._queue = self.queue_type(
260
- maxsize=0 if self.queue_max_size is None else self.queue_max_size
261
- )
262
-
263
- def __len__(self) -> int:
264
- return self._queue.qsize()
265
-
266
- def empty(self) -> bool:
267
- """Check if the queue is empty."""
268
- return self._queue.empty()
269
-
270
- def enqueue(self, *items: _T) -> None:
271
- """Enqueue a set items."""
272
- for item in items:
273
- self._queue.put_nowait(item)
274
-
275
- async def run_until_empty(self) -> None:
276
- """Run the processor until the queue is empty."""
277
- while not self.empty():
278
- await self._run()
279
- await sleep_dur(duration=self.sleep)
280
-
281
- def _get_items_nowait(self, *, max_size: int | None = None) -> Sequence[_T]:
282
- """Get items from the queue; no waiting."""
283
- return get_items_nowait(self._queue, max_size=max_size)
284
-
285
- @abstractmethod
286
- async def _process_item(self, item: _T, /) -> None:
287
- """Process the first item."""
288
- raise NotImplementedError(item) # pragma: no cover
289
-
290
- async def _process_item_failure(self, item: _T, error: Exception, /) -> None:
291
- """Process the failure."""
292
- _ = item
293
- raise error
294
-
295
- async def _run(self) -> None:
296
- """Run the processer."""
297
- try:
298
- (item,) = self._get_items_nowait(max_size=1)
299
- except ValueError:
300
- raise QueueEmpty from None
301
- try:
302
- await self._process_item(item)
303
- except Exception as error: # noqa: BLE001
304
- await self._process_item_failure(item, error)
305
-
306
- @override
307
- async def _start(self) -> None:
308
- """Start the processor."""
309
- while True:
310
- try:
311
- await self._run()
312
- except QueueEmpty:
313
- await sleep_dur(duration=self.sleep)
314
- except CancelledError:
315
- await self.stop()
316
- break
317
- else:
318
- await sleep_dur(duration=self.sleep)
319
-
320
- @override
321
- async def stop(self) -> None:
322
- """Stop the processor."""
323
- await self.run_until_empty()
324
- await super().stop()
325
-
326
-
327
- @dataclass(kw_only=True)
328
- class ExceptionProcessor(QueueProcessor[Exception | type[Exception]]):
329
- """Raise an exception in a queue."""
330
-
331
- queue_max_size: int | None = field(default=1, repr=False)
332
-
333
- @override
334
- async def _process_item(self, item: Exception | type[Exception], /) -> None:
335
- """Run the processor on the first item."""
336
- raise item
337
-
338
-
339
- ##
340
-
341
-
342
124
  type _DurationOrEvery = Duration | tuple[Literal["every"], Duration]
343
125
 
344
126
 
@@ -807,15 +589,11 @@ async def timeout_dur(
807
589
 
808
590
 
809
591
  __all__ = [
810
- "AsyncLoopingService",
811
- "AsyncService",
812
592
  "EnhancedTaskGroup",
813
- "ExceptionProcessor",
814
593
  "InfiniteLooper",
815
594
  "InfiniteLooperError",
816
595
  "InfiniteQueueLooper",
817
596
  "InfiniteQueueLooperError",
818
- "QueueProcessor",
819
597
  "StreamCommandOutput",
820
598
  "UniquePriorityQueue",
821
599
  "UniqueQueue",
utilities/click.py CHANGED
@@ -131,10 +131,10 @@ class Enum(ParamType, Generic[TEnum]):
131
131
  return _make_metavar(param, desc)
132
132
 
133
133
 
134
- class LocalDateTime(ParamType):
135
- """A local-datetime-valued parameter."""
134
+ class Month(ParamType):
135
+ """A month-valued parameter."""
136
136
 
137
- name = "local datetime"
137
+ name = "month"
138
138
 
139
139
  @override
140
140
  def __repr__(self) -> str:
@@ -142,21 +142,19 @@ class LocalDateTime(ParamType):
142
142
 
143
143
  @override
144
144
  def convert(
145
- self, value: DateTimeLike, param: Parameter | None, ctx: Context | None
146
- ) -> dt.date:
147
- """Convert a value into the `LocalDateTime` type."""
148
- from utilities.whenever import EnsureLocalDateTimeError, ensure_local_datetime
149
-
145
+ self, value: MonthLike, param: Parameter | None, ctx: Context | None
146
+ ) -> utilities.datetime.Month:
147
+ """Convert a value into the `Month` type."""
150
148
  try:
151
- return ensure_local_datetime(value)
152
- except EnsureLocalDateTimeError as error:
149
+ return ensure_month(value)
150
+ except EnsureMonthError as error:
153
151
  self.fail(str(error), param, ctx)
154
152
 
155
153
 
156
- class Month(ParamType):
157
- """A month-valued parameter."""
154
+ class PlainDateTime(ParamType):
155
+ """A local-datetime-valued parameter."""
158
156
 
159
- name = "month"
157
+ name = "plain datetime"
160
158
 
161
159
  @override
162
160
  def __repr__(self) -> str:
@@ -164,12 +162,14 @@ class Month(ParamType):
164
162
 
165
163
  @override
166
164
  def convert(
167
- self, value: MonthLike, param: Parameter | None, ctx: Context | None
168
- ) -> utilities.datetime.Month:
169
- """Convert a value into the `Month` type."""
165
+ self, value: DateTimeLike, param: Parameter | None, ctx: Context | None
166
+ ) -> dt.date:
167
+ """Convert a value into the `LocalDateTime` type."""
168
+ from utilities.whenever import EnsurePlainDateTimeError, ensure_plain_datetime
169
+
170
170
  try:
171
- return ensure_month(value)
172
- except EnsureMonthError as error:
171
+ return ensure_plain_datetime(value)
172
+ except EnsurePlainDateTimeError as error:
173
173
  self.fail(str(error), param, ctx)
174
174
 
175
175
 
@@ -506,8 +506,8 @@ __all__ = [
506
506
  "ListParameter",
507
507
  "ListStrs",
508
508
  "ListUUIDs",
509
- "LocalDateTime",
510
509
  "Month",
510
+ "PlainDateTime",
511
511
  "Time",
512
512
  "Timedelta",
513
513
  "ZonedDateTime",