dycw-utilities 0.116.4__py3-none-any.whl → 0.116.5__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.116.4
3
+ Version: 0.116.5
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -43,7 +43,7 @@ Requires-Dist: whenever<0.8,>=0.7.3; 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<44.1,>=44.0.2; extra == 'zzz-test-cryptography'
46
+ Requires-Dist: cryptography<46.0,>=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
@@ -1,4 +1,4 @@
1
- utilities/__init__.py,sha256=b6XtB99cyX4IZ76DFvF8Igz1IiLess5LdFIaswgC0Ko,60
1
+ utilities/__init__.py,sha256=GXLQ5JDCKi8MkhRcLwoG6sQHEvI7WNjzrUQe35jlk60,60
2
2
  utilities/altair.py,sha256=Gpja-flOo-Db0PIPJLJsgzAlXWoKUjPU1qY-DQ829ek,9156
3
3
  utilities/astor.py,sha256=xuDUkjq0-b6fhtwjhbnebzbqQZAjMSHR1IIS5uOodVg,777
4
4
  utilities/asyncio.py,sha256=7qisjTnEGEKcguy_STXN6qOXij_yzTvcQ5fIbrPeyZ8,23305
@@ -59,7 +59,7 @@ 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=0LAmbQFkwbJ3w6teTqGw1fNCSs1tDivL3DVAqob0S5c,26732
62
+ utilities/redis.py,sha256=P766qKT2SkDeKa9PpPEZIPCnAc2QDIi35ow2EEHGd20,27225
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
@@ -88,7 +88,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
88
88
  utilities/whenever.py,sha256=iLRP_-8CZtBpHKbGZGu-kjSMg1ZubJ-VSmgSy7Eudxw,17787
89
89
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
90
90
  utilities/zoneinfo.py,sha256=-Xm57PMMwDTYpxJdkiJG13wnbwK--I7XItBh5WVhD-o,1874
91
- dycw_utilities-0.116.4.dist-info/METADATA,sha256=P8hMpiUHgXKsNKT5dTwM4LbirjzE57NNYNB7KdmeZVQ,12943
92
- dycw_utilities-0.116.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
- dycw_utilities-0.116.4.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
94
- dycw_utilities-0.116.4.dist-info/RECORD,,
91
+ dycw_utilities-0.116.5.dist-info/METADATA,sha256=Prqc-G7Nlh_dk6GIwbMqc91_J8g49NALvLToCr02X28,12943
92
+ dycw_utilities-0.116.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
+ dycw_utilities-0.116.5.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
94
+ dycw_utilities-0.116.5.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.116.4"
3
+ __version__ = "0.116.5"
utilities/redis.py CHANGED
@@ -19,6 +19,7 @@ from typing import (
19
19
  from uuid import UUID, uuid4
20
20
 
21
21
  from redis.asyncio import Redis
22
+ from redis.asyncio.client import PubSub
22
23
  from redis.typing import EncodableT
23
24
 
24
25
  from utilities.asyncio import InfiniteQueueLooper, QueueProcessor, timeout_dur
@@ -46,7 +47,6 @@ if TYPE_CHECKING:
46
47
  )
47
48
 
48
49
  from redis.asyncio import ConnectionPool
49
- from redis.asyncio.client import PubSub
50
50
  from redis.typing import ResponseT
51
51
 
52
52
  from utilities.iterables import MaybeIterable
@@ -649,7 +649,7 @@ _SUBSCRIBE_SLEEP: Duration = MILLISECOND
649
649
 
650
650
  @overload
651
651
  def subscribe(
652
- pubsub: PubSub,
652
+ redis_or_pubsub: Redis | PubSub,
653
653
  channels: MaybeIterable[str],
654
654
  /,
655
655
  *,
@@ -659,7 +659,7 @@ def subscribe(
659
659
  ) -> AsyncIterator[_T]: ...
660
660
  @overload
661
661
  def subscribe(
662
- pubsub: PubSub,
662
+ redis_or_pubsub: Redis | PubSub,
663
663
  channels: MaybeIterable[str],
664
664
  /,
665
665
  *,
@@ -668,7 +668,7 @@ def subscribe(
668
668
  sleep: Duration = _SUBSCRIBE_SLEEP,
669
669
  ) -> AsyncIterator[bytes]: ...
670
670
  async def subscribe( # pyright: ignore[reportInconsistentOverload]
671
- pubsub: PubSub,
671
+ redis_or_pubsub: Redis | PubSub,
672
672
  channels: MaybeIterable[str],
673
673
  /,
674
674
  *,
@@ -679,7 +679,7 @@ async def subscribe( # pyright: ignore[reportInconsistentOverload]
679
679
  """Subscribe to the data of a given channel(s)."""
680
680
  channels = list(always_iterable(channels)) # skipif-ci-and-not-linux
681
681
  messages = subscribe_messages( # skipif-ci-and-not-linux
682
- pubsub, channels, timeout=timeout, sleep=sleep
682
+ redis_or_pubsub, channels, timeout=timeout, sleep=sleep
683
683
  )
684
684
  if deserializer is None: # skipif-ci-and-not-linux
685
685
  async for message in messages:
@@ -690,7 +690,7 @@ async def subscribe( # pyright: ignore[reportInconsistentOverload]
690
690
 
691
691
 
692
692
  async def subscribe_messages(
693
- pubsub: PubSub,
693
+ redis_or_pubsub: Redis | PubSub,
694
694
  channels: MaybeIterable[str],
695
695
  /,
696
696
  *,
@@ -698,28 +698,40 @@ async def subscribe_messages(
698
698
  sleep: Duration = _SUBSCRIBE_SLEEP,
699
699
  ) -> AsyncIterator[_RedisMessageSubscribe]:
700
700
  """Subscribe to the messages of a given channel(s)."""
701
- channels = list(always_iterable(channels)) # skipif-ci-and-not-linux
702
- for channel in channels: # skipif-ci-and-not-linux
703
- await pubsub.subscribe(channel)
704
- channels_bytes = [c.encode() for c in channels] # skipif-ci-and-not-linux
705
- timeout_use = ( # skipif-ci-and-not-linux
706
- None if timeout is None else datetime_duration_to_float(timeout)
707
- )
708
- sleep_use = datetime_duration_to_float(sleep) # skipif-ci-and-not-linux
709
- while True: # skipif-ci-and-not-linux
710
- message = cast(
711
- "_RedisMessageSubscribe | _RedisMessageUnsubscribe | None",
712
- await pubsub.get_message(timeout=timeout_use),
713
- )
714
- if (
715
- (message is not None)
716
- and (message["type"] in {"subscribe", "psubscribe", "message", "pmessage"})
717
- and (message["channel"] in channels_bytes)
718
- and isinstance(message["data"], bytes)
719
- ):
720
- yield cast("_RedisMessageSubscribe", message)
721
- else:
722
- await asyncio.sleep(sleep_use)
701
+ match redis_or_pubsub: # skipif-ci-and-not-linux
702
+ case Redis() as redis:
703
+ async for msg in subscribe_messages(
704
+ redis.pubsub(), channels, timeout=timeout, sleep=sleep
705
+ ):
706
+ yield msg
707
+ case PubSub() as pubsub:
708
+ channels = list(always_iterable(channels))
709
+ for channel in channels:
710
+ await pubsub.subscribe(channel)
711
+ channels_bytes = [c.encode() for c in channels]
712
+ timeout_use = (
713
+ None if timeout is None else datetime_duration_to_float(timeout)
714
+ )
715
+ sleep_use = datetime_duration_to_float(sleep)
716
+ while True:
717
+ message = cast(
718
+ "_RedisMessageSubscribe | _RedisMessageUnsubscribe | None",
719
+ await pubsub.get_message(timeout=timeout_use),
720
+ )
721
+ if (
722
+ (message is not None)
723
+ and (
724
+ message["type"]
725
+ in {"subscribe", "psubscribe", "message", "pmessage"}
726
+ )
727
+ and (message["channel"] in channels_bytes)
728
+ and isinstance(message["data"], bytes)
729
+ ):
730
+ yield cast("_RedisMessageSubscribe", message)
731
+ else:
732
+ await asyncio.sleep(sleep_use)
733
+ case _ as never:
734
+ assert_never(never)
723
735
 
724
736
 
725
737
  class _RedisMessageSubscribe(TypedDict):