dycw-utilities 0.129.10__py3-none-any.whl → 0.129.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.
@@ -1,13 +1,18 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.129.10
3
+ Version: 0.129.12
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
7
7
  Requires-Dist: typing-extensions<4.15,>=4.14.0
8
+ Provides-Extra: logging
9
+ Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'logging'
10
+ Requires-Dist: coloredlogs<15.1,>=15.0.1; extra == 'logging'
11
+ Requires-Dist: tzlocal<5.4,>=5.3.1; extra == 'logging'
12
+ Requires-Dist: whenever<0.9,>=0.8.4; extra == 'logging'
8
13
  Provides-Extra: test
9
14
  Requires-Dist: dycw-pytest-only<2.2,>=2.1.1; extra == 'test'
10
- Requires-Dist: hypothesis<6.136,>=6.135.0; extra == 'test'
15
+ Requires-Dist: hypothesis<6.136,>=6.135.2; extra == 'test'
11
16
  Requires-Dist: pytest-asyncio<1.1,>=1.0.0; extra == 'test'
12
17
  Requires-Dist: pytest-cov<6.2,>=6.1.1; extra == 'test'
13
18
  Requires-Dist: pytest-instafail<0.6,>=0.5.0; extra == 'test'
@@ -19,6 +24,8 @@ Requires-Dist: pytest-rng<1.1,>=1.0.0; extra == 'test'
19
24
  Requires-Dist: pytest-timeout<2.5,>=2.4.0; extra == 'test'
20
25
  Requires-Dist: pytest-xdist<3.8,>=3.7.0; extra == 'test'
21
26
  Requires-Dist: pytest<8.4,>=8.3.5; extra == 'test'
27
+ Provides-Extra: zzz-test-aiolimiter
28
+ Requires-Dist: aiolimiter<1.3,>=1.2.1; extra == 'zzz-test-aiolimiter'
22
29
  Provides-Extra: zzz-test-altair
23
30
  Requires-Dist: altair<5.6,>=5.5.0; extra == 'zzz-test-altair'
24
31
  Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-altair'
@@ -77,9 +84,9 @@ Provides-Extra: zzz-test-hypothesis
77
84
  Requires-Dist: aiosqlite<0.22,>=0.21.0; extra == 'zzz-test-hypothesis'
78
85
  Requires-Dist: asyncpg<0.31,>=0.30.0; extra == 'zzz-test-hypothesis'
79
86
  Requires-Dist: greenlet<3.3,>=3.2.0; extra == 'zzz-test-hypothesis'
80
- Requires-Dist: hypothesis<6.136,>=6.135.0; extra == 'zzz-test-hypothesis'
87
+ Requires-Dist: hypothesis<6.136,>=6.135.2; extra == 'zzz-test-hypothesis'
81
88
  Requires-Dist: luigi<3.7,>=3.6.0; extra == 'zzz-test-hypothesis'
82
- Requires-Dist: numpy<2.3,>=2.2.6; extra == 'zzz-test-hypothesis'
89
+ Requires-Dist: numpy<2.4,>=2.3.0; extra == 'zzz-test-hypothesis'
83
90
  Requires-Dist: pathvalidate<3.3,>=3.2.3; extra == 'zzz-test-hypothesis'
84
91
  Requires-Dist: redis<6.3,>=6.2.0; extra == 'zzz-test-hypothesis'
85
92
  Requires-Dist: sqlalchemy<2.1,>=2.0.41; extra == 'zzz-test-hypothesis'
@@ -108,14 +115,14 @@ Provides-Extra: zzz-test-luigi
108
115
  Requires-Dist: luigi<3.7,>=3.6.0; extra == 'zzz-test-luigi'
109
116
  Requires-Dist: whenever<0.9,>=0.8.4; extra == 'zzz-test-luigi'
110
117
  Provides-Extra: zzz-test-math
111
- Requires-Dist: numpy<2.3,>=2.2.6; extra == 'zzz-test-math'
118
+ Requires-Dist: numpy<2.4,>=2.3.0; extra == 'zzz-test-math'
112
119
  Provides-Extra: zzz-test-memory-profiler
113
120
  Requires-Dist: memory-profiler<0.62,>=0.61.0; extra == 'zzz-test-memory-profiler'
114
121
  Provides-Extra: zzz-test-modules
115
122
  Provides-Extra: zzz-test-more-itertools
116
123
  Requires-Dist: more-itertools<10.8,>=10.7.0; extra == 'zzz-test-more-itertools'
117
124
  Provides-Extra: zzz-test-numpy
118
- Requires-Dist: numpy<2.3,>=2.2.6; extra == 'zzz-test-numpy'
125
+ Requires-Dist: numpy<2.4,>=2.3.0; extra == 'zzz-test-numpy'
119
126
  Provides-Extra: zzz-test-operator
120
127
  Requires-Dist: polars-lts-cpu<1.31,>=1.30.0; extra == 'zzz-test-operator'
121
128
  Requires-Dist: whenever<0.9,>=0.8.4; extra == 'zzz-test-operator'
@@ -172,7 +179,7 @@ Requires-Dist: scipy<1.16,>=1.15.3; extra == 'zzz-test-scipy'
172
179
  Provides-Extra: zzz-test-sentinel
173
180
  Provides-Extra: zzz-test-shelve
174
181
  Provides-Extra: zzz-test-slack-sdk
175
- Requires-Dist: aiohttp<3.12.10,>=3.12.9; extra == 'zzz-test-slack-sdk'
182
+ Requires-Dist: aiohttp<3.13,>=3.12.11; extra == 'zzz-test-slack-sdk'
176
183
  Requires-Dist: slack-sdk<3.36,>=3.35.0; extra == 'zzz-test-slack-sdk'
177
184
  Provides-Extra: zzz-test-socket
178
185
  Provides-Extra: zzz-test-sqlalchemy
@@ -1,4 +1,5 @@
1
- utilities/__init__.py,sha256=Ea2sLI04_oNAg8JArocs5IF0T0dgZO_dvaFh04klnq8,61
1
+ utilities/__init__.py,sha256=68eOW405LMEIFZzGFWl6p2nKjkeZBEUDPTHc4L430R4,61
2
+ utilities/aiolimiter.py,sha256=mD0wEiqMgwpty4XTbawFpnkkmJS6R4JRsVXFUaoitSU,628
2
3
  utilities/altair.py,sha256=Gpja-flOo-Db0PIPJLJsgzAlXWoKUjPU1qY-DQ829ek,9156
3
4
  utilities/asyncio.py,sha256=3n5EIcSq2xtEF1i4oR0oY2JmBq3NyugeHKFK39Mt22s,37987
4
5
  utilities/atomicwrites.py,sha256=geFjn9Pwn-tTrtoGjDDxWli9NqbYfy3gGL6ZBctiqSo,5393
@@ -30,7 +31,7 @@ utilities/iterables.py,sha256=mDqw2_0MUVp-P8FklgcaVTi2TXduH0MxbhTDzzhSBho,44915
30
31
  utilities/jupyter.py,sha256=ft5JA7fBxXKzP-L9W8f2-wbF0QeYc_2uLQNFDVk4Z-M,2917
31
32
  utilities/libcst.py,sha256=Jto5ppzRzsxn4AD32IS8n0lbgLYXwsVJB6EY8giNZyY,4974
32
33
  utilities/lightweight_charts.py,sha256=0xNfcsrgFI0R9xL25LtSm-W5yhfBI93qQNT6HyaXAhg,2769
33
- utilities/logging.py,sha256=dA54i2gmULBLuEJ2roGYWt9pW2NvNBmx0YxlMns347M,26126
34
+ utilities/logging.py,sha256=GvSjMcjjHehbGeFGLQDiNvDteKym3-M-WF8tPlVDIQY,26228
34
35
  utilities/loguru.py,sha256=MEMQVWrdECxk1e3FxGzmOf21vWT9j8CAir98SEXFKPA,3809
35
36
  utilities/luigi.py,sha256=fpH9MbxJDuo6-k9iCXRayFRtiVbUtibCJKugf7ygpv0,5988
36
37
  utilities/math.py,sha256=-mQgbah-dPJwOEWf3SonrFoVZ2AVxMgpeQ3dfVa-oJA,26764
@@ -63,7 +64,7 @@ utilities/random.py,sha256=lYdjgxB7GCfU_fwFVl5U-BIM_HV3q6_urL9byjrwDM8,4157
63
64
  utilities/re.py,sha256=5J4d8VwIPFVrX2Eb8zfoxImDv7IwiN_U7mJ07wR2Wvs,3958
64
65
  utilities/redis.py,sha256=7Sc-G43VXVzFQU7MHKyI1y3u7My3oT1UoWXPGcKM_-0,36008
65
66
  utilities/reprlib.py,sha256=ssYTcBW-TeRh3fhCJv57sopTZHF5FrPyyUg9yp5XBlo,3953
66
- utilities/scipy.py,sha256=X6ROnHwiUhAmPhM0jkfEh0-Fd9iRvwiqtCQMOLmOQF8,945
67
+ utilities/scipy.py,sha256=wZJM7fEgBAkLSYYvSmsg5ac-QuwAI0BGqHVetw1_Hb0,947
67
68
  utilities/sentinel.py,sha256=3jIwgpMekWgDAxPDA_hXMP2St43cPhciKN3LWiZ7kv0,1248
68
69
  utilities/shelve.py,sha256=HZsMwK4tcIfg3sh0gApx4-yjQnrY4o3V3ZRimvRhoW0,738
69
70
  utilities/slack_sdk.py,sha256=ltmzv68aa73CJGqTDvt8L9vDm22YU9iOCo3NCiNd3vA,4347
@@ -90,7 +91,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
90
91
  utilities/whenever.py,sha256=QbXgFAPuUL7PCp2hajmIP-FFIfIR1J6Y0TxJbeoj60I,18434
91
92
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
92
93
  utilities/zoneinfo.py,sha256=-5j7IQ9nb7gR43rdgA7ms05im-XuqhAk9EJnQBXxCoQ,1874
93
- dycw_utilities-0.129.10.dist-info/METADATA,sha256=w9VpvO8zhmLUxyrwfut-D_8nzKJc4mlol7xp_Li98G4,12724
94
- dycw_utilities-0.129.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
95
- dycw_utilities-0.129.10.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
96
- dycw_utilities-0.129.10.dist-info/RECORD,,
94
+ dycw_utilities-0.129.12.dist-info/METADATA,sha256=3e68t7tbu3fs_QovBfPMgWYpyd8VgCZySiQAnTgvsn8,13084
95
+ dycw_utilities-0.129.12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
96
+ dycw_utilities-0.129.12.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
97
+ dycw_utilities-0.129.12.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.129.10"
3
+ __version__ = "0.129.12"
@@ -0,0 +1,25 @@
1
+ from __future__ import annotations
2
+
3
+ from asyncio import get_running_loop
4
+ from typing import TYPE_CHECKING
5
+
6
+ from aiolimiter import AsyncLimiter
7
+
8
+ if TYPE_CHECKING:
9
+ from collections.abc import Hashable
10
+
11
+ _LIMITERS: dict[tuple[int, Hashable], AsyncLimiter] = {}
12
+
13
+
14
+ def get_async_limiter(key: Hashable, /, *, rate: float = 1.0) -> AsyncLimiter:
15
+ """Get a loop-aware rate limiter."""
16
+ id_ = id(get_running_loop())
17
+ full = (id_, key)
18
+ try:
19
+ return _LIMITERS[full]
20
+ except KeyError:
21
+ limiter = _LIMITERS[full] = AsyncLimiter(1.0, time_period=rate)
22
+ return limiter
23
+
24
+
25
+ __all__ = ["get_async_limiter"]
utilities/logging.py CHANGED
@@ -85,6 +85,9 @@ except ModuleNotFoundError: # pragma: no cover
85
85
  type _When = Literal[
86
86
  "S", "M", "H", "D", "midnight", "W0", "W1", "W2", "W3", "W4", "W5", "W6"
87
87
  ]
88
+ _BACKUP_COUNT: int = 100
89
+ _MAX_BYTES: int = 10 * 1024**2
90
+ _WHEN: _When = "D"
88
91
 
89
92
 
90
93
  class SizeAndTimeRotatingFileHandler(BaseRotatingHandler):
@@ -100,10 +103,10 @@ class SizeAndTimeRotatingFileHandler(BaseRotatingHandler):
100
103
  encoding: str | None = None,
101
104
  delay: bool = False,
102
105
  errors: Literal["strict", "ignore", "replace"] | None = None,
103
- maxBytes: int = 0,
104
- when: _When = "midnight",
106
+ maxBytes: int = _MAX_BYTES,
107
+ when: _When = _WHEN,
105
108
  interval: int = 1,
106
- backupCount: int = 0,
109
+ backupCount: int = _BACKUP_COUNT,
107
110
  utc: bool = False,
108
111
  atTime: dt.time | None = None,
109
112
  ) -> None:
@@ -554,10 +557,10 @@ def setup_logging(
554
557
  console_filters: Iterable[_FilterType] | None = None,
555
558
  console_fmt: str = "❯ {_zoned_datetime_str} | {name}:{funcName}:{lineno} | {message}", # noqa: RUF001
556
559
  files_dir: MaybeCallablePathLike | None = get_default_logging_path,
557
- files_when: _When = "D",
560
+ files_when: _When = _WHEN,
558
561
  files_interval: int = 1,
559
- files_backup_count: int = 10,
560
- files_max_bytes: int = 10 * 1024**2,
562
+ files_backup_count: int = _BACKUP_COUNT,
563
+ files_max_bytes: int = _MAX_BYTES,
561
564
  files_filters: Iterable[_FilterType] | None = None,
562
565
  files_fmt: str = "{_zoned_datetime_str} | {name}:{funcName}:{lineno} | {levelname:8} | {message}",
563
566
  filters: MaybeIterable[_FilterType] | None = None,
utilities/scipy.py CHANGED
@@ -19,7 +19,7 @@ def _ppf_1d(array: NDArrayF, cutoff: float, /) -> NDArrayF:
19
19
  out = full_like(array, nan, dtype=float)
20
20
  out[j] = _ppf_1d(array[j], cutoff)
21
21
  return out
22
- low, high = min(array), max(array)
22
+ low, high = array.min(), array.max()
23
23
  if is_zero(span := high - low):
24
24
  return zeros_like(array, dtype=float)
25
25
  centred = (array - low) / span