reactivex 4.1.0__py3-none-any.whl → 5.0.0a2__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.
Files changed (219) hide show
  1. reactivex/__init__.py +35 -39
  2. reactivex/_version.py +1 -1
  3. reactivex/abc/disposable.py +3 -4
  4. reactivex/abc/observable.py +13 -6
  5. reactivex/abc/observer.py +2 -1
  6. reactivex/abc/periodicscheduler.py +7 -6
  7. reactivex/abc/scheduler.py +10 -9
  8. reactivex/abc/subject.py +5 -5
  9. reactivex/disposable/compositedisposable.py +4 -4
  10. reactivex/disposable/disposable.py +1 -2
  11. reactivex/disposable/multipleassignmentdisposable.py +2 -3
  12. reactivex/disposable/refcountdisposable.py +1 -2
  13. reactivex/disposable/serialdisposable.py +4 -5
  14. reactivex/disposable/singleassignmentdisposable.py +3 -4
  15. reactivex/internal/__init__.py +2 -0
  16. reactivex/internal/basic.py +2 -2
  17. reactivex/internal/concurrency.py +2 -1
  18. reactivex/internal/curry.py +59 -0
  19. reactivex/internal/exceptions.py +7 -12
  20. reactivex/internal/priorityqueue.py +2 -2
  21. reactivex/internal/utils.py +3 -2
  22. reactivex/notification.py +22 -21
  23. reactivex/observable/case.py +5 -6
  24. reactivex/observable/catch.py +3 -2
  25. reactivex/observable/combinelatest.py +4 -5
  26. reactivex/observable/concat.py +3 -2
  27. reactivex/observable/connectableobservable.py +7 -7
  28. reactivex/observable/defer.py +4 -3
  29. reactivex/observable/empty.py +3 -4
  30. reactivex/observable/forkjoin.py +5 -5
  31. reactivex/observable/fromcallback.py +4 -3
  32. reactivex/observable/fromfuture.py +2 -2
  33. reactivex/observable/fromiterable.py +4 -3
  34. reactivex/observable/generate.py +2 -2
  35. reactivex/observable/generatewithrelativetime.py +4 -3
  36. reactivex/observable/groupedobservable.py +4 -4
  37. reactivex/observable/ifthen.py +3 -2
  38. reactivex/observable/interval.py +1 -4
  39. reactivex/observable/marbles.py +18 -17
  40. reactivex/observable/mixins/__init__.py +32 -0
  41. reactivex/observable/mixins/combination.py +481 -0
  42. reactivex/observable/mixins/conditional.py +135 -0
  43. reactivex/observable/mixins/error_handling.py +130 -0
  44. reactivex/observable/mixins/filtering.py +1119 -0
  45. reactivex/observable/mixins/mathematical.py +277 -0
  46. reactivex/observable/mixins/multicasting.py +306 -0
  47. reactivex/observable/mixins/testing.py +193 -0
  48. reactivex/observable/mixins/time_based.py +209 -0
  49. reactivex/observable/mixins/transformation.py +632 -0
  50. reactivex/observable/mixins/utility.py +811 -0
  51. reactivex/observable/mixins/windowing.py +688 -0
  52. reactivex/observable/never.py +2 -2
  53. reactivex/observable/observable.py +72 -25
  54. reactivex/observable/onerrorresumenext.py +7 -6
  55. reactivex/observable/range.py +6 -6
  56. reactivex/observable/repeat.py +2 -2
  57. reactivex/observable/returnvalue.py +6 -5
  58. reactivex/observable/start.py +3 -2
  59. reactivex/observable/startasync.py +2 -1
  60. reactivex/observable/throw.py +3 -3
  61. reactivex/observable/timer.py +12 -12
  62. reactivex/observable/toasync.py +3 -2
  63. reactivex/observable/using.py +5 -4
  64. reactivex/observable/withlatestfrom.py +4 -5
  65. reactivex/observable/zip.py +7 -6
  66. reactivex/observer/autodetachobserver.py +4 -4
  67. reactivex/observer/observer.py +5 -4
  68. reactivex/observer/scheduledobserver.py +2 -2
  69. reactivex/operators/__init__.py +162 -208
  70. reactivex/operators/_all.py +23 -6
  71. reactivex/operators/_amb.py +88 -75
  72. reactivex/operators/_asobservable.py +20 -17
  73. reactivex/operators/_average.py +48 -45
  74. reactivex/operators/_buffer.py +81 -35
  75. reactivex/operators/_bufferwithtime.py +29 -9
  76. reactivex/operators/_bufferwithtimeorcount.py +27 -8
  77. reactivex/operators/_catch.py +33 -32
  78. reactivex/operators/_combinelatest.py +28 -20
  79. reactivex/operators/_concat.py +16 -13
  80. reactivex/operators/_contains.py +25 -6
  81. reactivex/operators/_count.py +24 -8
  82. reactivex/operators/_debounce.py +141 -138
  83. reactivex/operators/_defaultifempty.py +45 -42
  84. reactivex/operators/_delay.py +24 -23
  85. reactivex/operators/_delaysubscription.py +23 -21
  86. reactivex/operators/_delaywithmapper.py +10 -11
  87. reactivex/operators/_dematerialize.py +25 -21
  88. reactivex/operators/_distinct.py +50 -46
  89. reactivex/operators/_distinctuntilchanged.py +60 -57
  90. reactivex/operators/_do.py +123 -116
  91. reactivex/operators/_dowhile.py +3 -2
  92. reactivex/operators/_elementatordefault.py +57 -33
  93. reactivex/operators/_exclusive.py +59 -53
  94. reactivex/operators/_expand.py +82 -77
  95. reactivex/operators/_filter.py +63 -68
  96. reactivex/operators/_finallyaction.py +3 -2
  97. reactivex/operators/_find.py +49 -32
  98. reactivex/operators/_first.py +18 -11
  99. reactivex/operators/_firstordefault.py +5 -4
  100. reactivex/operators/_flatmap.py +89 -83
  101. reactivex/operators/_forkjoin.py +23 -18
  102. reactivex/operators/_groupby.py +27 -6
  103. reactivex/operators/_groupbyuntil.py +8 -5
  104. reactivex/operators/_groupjoin.py +7 -6
  105. reactivex/operators/_ignoreelements.py +20 -15
  106. reactivex/operators/_isempty.py +15 -4
  107. reactivex/operators/_join.py +6 -5
  108. reactivex/operators/_last.py +36 -31
  109. reactivex/operators/_lastordefault.py +8 -8
  110. reactivex/operators/_map.py +54 -39
  111. reactivex/operators/_materialize.py +30 -31
  112. reactivex/operators/_max.py +18 -11
  113. reactivex/operators/_maxby.py +5 -5
  114. reactivex/operators/_merge.py +132 -129
  115. reactivex/operators/_min.py +16 -10
  116. reactivex/operators/_minby.py +9 -8
  117. reactivex/operators/_multicast.py +9 -9
  118. reactivex/operators/_observeon.py +35 -31
  119. reactivex/operators/_onerrorresumenext.py +2 -1
  120. reactivex/operators/_pairwise.py +38 -34
  121. reactivex/operators/_partition.py +80 -73
  122. reactivex/operators/_pluck.py +4 -3
  123. reactivex/operators/_publish.py +36 -21
  124. reactivex/operators/_publishvalue.py +8 -7
  125. reactivex/operators/_reduce.py +16 -12
  126. reactivex/operators/_repeat.py +33 -30
  127. reactivex/operators/_replay.py +9 -9
  128. reactivex/operators/_retry.py +12 -10
  129. reactivex/operators/_sample.py +31 -27
  130. reactivex/operators/_scan.py +41 -39
  131. reactivex/operators/_sequenceequal.py +8 -7
  132. reactivex/operators/_single.py +20 -13
  133. reactivex/operators/_singleordefault.py +6 -5
  134. reactivex/operators/_skip.py +35 -32
  135. reactivex/operators/_skiplast.py +38 -34
  136. reactivex/operators/_skiplastwithtime.py +5 -4
  137. reactivex/operators/_skipuntil.py +40 -35
  138. reactivex/operators/_skipuntilwithtime.py +4 -3
  139. reactivex/operators/_skipwhile.py +65 -44
  140. reactivex/operators/_skipwithtime.py +50 -46
  141. reactivex/operators/_slice.py +58 -53
  142. reactivex/operators/_some.py +48 -47
  143. reactivex/operators/_startswith.py +17 -15
  144. reactivex/operators/_subscribeon.py +44 -41
  145. reactivex/operators/_sum.py +23 -6
  146. reactivex/operators/_switchlatest.py +71 -69
  147. reactivex/operators/_take.py +37 -33
  148. reactivex/operators/_takelast.py +37 -36
  149. reactivex/operators/_takelastbuffer.py +38 -37
  150. reactivex/operators/_takelastwithtime.py +60 -56
  151. reactivex/operators/_takeuntil.py +33 -32
  152. reactivex/operators/_takeuntilwithtime.py +42 -39
  153. reactivex/operators/_takewhile.py +108 -100
  154. reactivex/operators/_takewithtime.py +46 -41
  155. reactivex/operators/_throttlefirst.py +52 -45
  156. reactivex/operators/_timeinterval.py +40 -36
  157. reactivex/operators/_timeout.py +81 -79
  158. reactivex/operators/_timeoutwithmapper.py +6 -5
  159. reactivex/operators/_timestamp.py +24 -22
  160. reactivex/operators/_todict.py +51 -43
  161. reactivex/operators/_tofuture.py +24 -15
  162. reactivex/operators/_toiterable.py +33 -27
  163. reactivex/operators/_tomarbles.py +5 -5
  164. reactivex/operators/_toset.py +29 -19
  165. reactivex/operators/_whiledo.py +2 -1
  166. reactivex/operators/_window.py +100 -99
  167. reactivex/operators/_windowwithcount.py +56 -54
  168. reactivex/operators/_windowwithtime.py +95 -79
  169. reactivex/operators/_windowwithtimeorcount.py +85 -69
  170. reactivex/operators/_withlatestfrom.py +13 -9
  171. reactivex/operators/_zip.py +67 -63
  172. reactivex/operators/connectable/_refcount.py +4 -3
  173. reactivex/pipe.py +2 -1
  174. reactivex/run.py +8 -4
  175. reactivex/scheduler/catchscheduler.py +11 -10
  176. reactivex/scheduler/currentthreadscheduler.py +2 -3
  177. reactivex/scheduler/eventloop/asyncioscheduler.py +7 -6
  178. reactivex/scheduler/eventloop/asynciothreadsafescheduler.py +12 -14
  179. reactivex/scheduler/eventloop/eventletscheduler.py +4 -4
  180. reactivex/scheduler/eventloop/geventscheduler.py +4 -4
  181. reactivex/scheduler/eventloop/ioloopscheduler.py +4 -4
  182. reactivex/scheduler/eventloop/twistedscheduler.py +4 -4
  183. reactivex/scheduler/eventloopscheduler.py +9 -12
  184. reactivex/scheduler/historicalscheduler.py +1 -2
  185. reactivex/scheduler/immediatescheduler.py +5 -4
  186. reactivex/scheduler/mainloop/gtkscheduler.py +6 -7
  187. reactivex/scheduler/mainloop/pygamescheduler.py +4 -4
  188. reactivex/scheduler/mainloop/qtscheduler.py +6 -6
  189. reactivex/scheduler/mainloop/tkinterscheduler.py +4 -4
  190. reactivex/scheduler/mainloop/wxscheduler.py +7 -7
  191. reactivex/scheduler/newthreadscheduler.py +6 -8
  192. reactivex/scheduler/periodicscheduler.py +4 -4
  193. reactivex/scheduler/scheduleditem.py +4 -4
  194. reactivex/scheduler/scheduler.py +5 -5
  195. reactivex/scheduler/threadpoolscheduler.py +3 -3
  196. reactivex/scheduler/timeoutscheduler.py +5 -4
  197. reactivex/scheduler/trampoline.py +1 -2
  198. reactivex/scheduler/trampolinescheduler.py +5 -6
  199. reactivex/scheduler/virtualtimescheduler.py +4 -4
  200. reactivex/subject/asyncsubject.py +2 -2
  201. reactivex/subject/behaviorsubject.py +2 -2
  202. reactivex/subject/innersubscription.py +2 -2
  203. reactivex/subject/replaysubject.py +8 -8
  204. reactivex/subject/subject.py +4 -4
  205. reactivex/testing/coldobservable.py +5 -5
  206. reactivex/testing/hotobservable.py +6 -6
  207. reactivex/testing/marbles.py +21 -20
  208. reactivex/testing/mockdisposable.py +1 -3
  209. reactivex/testing/mockobserver.py +2 -2
  210. reactivex/testing/reactivetest.py +2 -2
  211. reactivex/testing/recorded.py +1 -1
  212. reactivex/testing/subscription.py +3 -3
  213. reactivex/testing/testscheduler.py +13 -12
  214. reactivex/typing.py +25 -14
  215. {reactivex-4.1.0.dist-info → reactivex-5.0.0a2.dist-info}/METADATA +59 -26
  216. reactivex-5.0.0a2.dist-info/RECORD +236 -0
  217. {reactivex-4.1.0.dist-info → reactivex-5.0.0a2.dist-info}/WHEEL +1 -1
  218. reactivex-4.1.0.dist-info/RECORD +0 -223
  219. {reactivex-4.1.0.dist-info → reactivex-5.0.0a2.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,7 @@
1
- from typing import Callable, Dict, Optional, TypeVar, cast
1
+ from typing import TypeVar, cast
2
2
 
3
3
  from reactivex import Observable, abc
4
+ from reactivex.internal import curry_flip
4
5
  from reactivex.typing import Mapper
5
6
 
6
7
  _T = TypeVar("_T")
@@ -8,57 +9,64 @@ _TKey = TypeVar("_TKey")
8
9
  _TValue = TypeVar("_TValue")
9
10
 
10
11
 
12
+ @curry_flip
11
13
  def to_dict_(
12
- key_mapper: Mapper[_T, _TKey], element_mapper: Optional[Mapper[_T, _TValue]] = None
13
- ) -> Callable[[Observable[_T]], Observable[Dict[_TKey, _TValue]]]:
14
- def to_dict(source: Observable[_T]) -> Observable[Dict[_TKey, _TValue]]:
15
- """Converts the observable sequence to a Map if it exists.
16
-
17
- Args:
18
- source: Source observable to convert.
19
-
20
- Returns:
21
- An observable sequence with a single value of a dictionary
22
- containing the values from the observable sequence.
23
- """
24
-
25
- def subscribe(
26
- observer: abc.ObserverBase[Dict[_TKey, _TValue]],
27
- scheduler: Optional[abc.SchedulerBase] = None,
28
- ) -> abc.DisposableBase:
29
- m: Dict[_TKey, _TValue] = dict()
30
-
31
- def on_next(x: _T) -> None:
14
+ source: Observable[_T],
15
+ key_mapper: Mapper[_T, _TKey],
16
+ element_mapper: Mapper[_T, _TValue] | None = None,
17
+ ) -> Observable[dict[_TKey, _TValue]]:
18
+ """Converts the observable sequence to a dictionary.
19
+
20
+ Examples:
21
+ >>> result = source.pipe(to_dict(lambda x: x.id))
22
+ >>> result = to_dict(lambda x: x.id)(source)
23
+ >>> result = source.pipe(to_dict(lambda x: x.id, lambda x: x.name))
24
+
25
+ Args:
26
+ source: Source observable to convert.
27
+ key_mapper: Function to extract the key from each element.
28
+ element_mapper: Optional function to extract the value from each element.
29
+
30
+ Returns:
31
+ An observable sequence with a single value of a dictionary
32
+ containing the values from the observable sequence.
33
+ """
34
+
35
+ def subscribe(
36
+ observer: abc.ObserverBase[dict[_TKey, _TValue]],
37
+ scheduler: abc.SchedulerBase | None = None,
38
+ ) -> abc.DisposableBase:
39
+ m: dict[_TKey, _TValue] = dict()
40
+
41
+ def on_next(x: _T) -> None:
42
+ try:
43
+ key = key_mapper(x)
44
+ except Exception as ex: # pylint: disable=broad-except
45
+ observer.on_error(ex)
46
+ return
47
+
48
+ if element_mapper:
32
49
  try:
33
- key = key_mapper(x)
50
+ element = element_mapper(x)
34
51
  except Exception as ex: # pylint: disable=broad-except
35
52
  observer.on_error(ex)
36
53
  return
54
+ else:
55
+ element = cast(_TValue, x)
37
56
 
38
- if element_mapper:
39
- try:
40
- element = element_mapper(x)
41
- except Exception as ex: # pylint: disable=broad-except
42
- observer.on_error(ex)
43
- return
44
- else:
45
- element = cast(_TValue, x)
57
+ m[key] = element
46
58
 
47
- m[key] = element
59
+ def on_completed() -> None:
60
+ nonlocal m
61
+ observer.on_next(m)
62
+ m = dict()
63
+ observer.on_completed()
48
64
 
49
- def on_completed() -> None:
50
- nonlocal m
51
- observer.on_next(m)
52
- m = dict()
53
- observer.on_completed()
65
+ return source.subscribe(
66
+ on_next, observer.on_error, on_completed, scheduler=scheduler
67
+ )
54
68
 
55
- return source.subscribe(
56
- on_next, observer.on_error, on_completed, scheduler=scheduler
57
- )
58
-
59
- return Observable(subscribe)
60
-
61
- return to_dict
69
+ return Observable(subscribe)
62
70
 
63
71
 
64
72
  __all__ = ["to_dict_"]
@@ -1,6 +1,7 @@
1
1
  import asyncio
2
2
  from asyncio import Future
3
- from typing import Callable, Optional, TypeVar, cast
3
+ from collections.abc import Callable
4
+ from typing import TypeVar, cast
4
5
 
5
6
  from reactivex import Observable, abc
6
7
  from reactivex.internal.exceptions import SequenceContainsNoElementsError
@@ -9,15 +10,10 @@ _T = TypeVar("_T")
9
10
 
10
11
 
11
12
  def to_future_(
12
- future_ctor: Optional[Callable[[], "Future[_T]"]] = None,
13
- scheduler: Optional[abc.SchedulerBase] = None,
14
- ) -> Callable[[Observable[_T]], "Future[_T]"]:
15
- future_ctor_: Callable[[], "Future[_T]"] = (
16
- future_ctor or asyncio.get_event_loop().create_future
17
- )
18
- future: "Future[_T]" = future_ctor_()
19
-
20
- def to_future(source: Observable[_T]) -> "Future[_T]":
13
+ future_ctor: Callable[[], Future[_T]] | None = None,
14
+ scheduler: abc.SchedulerBase | None = None,
15
+ ) -> Callable[[Observable[_T]], Future[_T]]:
16
+ def to_future(source: Observable[_T]) -> Future[_T]:
21
17
  """Converts an existing observable sequence to a Future.
22
18
 
23
19
  If the observable emits a single item, then this item is set as the
@@ -33,25 +29,38 @@ def to_future_(
33
29
  Returns:
34
30
  A future with the last value from the observable sequence.
35
31
  """
32
+ if future_ctor is not None:
33
+ future_ctor_ = future_ctor
34
+ else:
35
+ try:
36
+ future_ctor_ = asyncio.get_running_loop().create_future
37
+ except RuntimeError:
38
+
39
+ def create_future() -> Future[_T]:
40
+ return Future() # Explicitly using Future[_T]
41
+
42
+ future_ctor_ = create_future # If no running loop
43
+
44
+ future: Future[_T] = future_ctor_()
36
45
 
37
46
  has_value = False
38
- last_value = cast(_T, None)
47
+ last_value: _T | None = None
39
48
 
40
- def on_next(value: _T):
49
+ def on_next(value: _T) -> None:
41
50
  nonlocal last_value
42
51
  nonlocal has_value
43
52
  last_value = value
44
53
  has_value = True
45
54
 
46
- def on_error(err: Exception):
55
+ def on_error(err: Exception) -> None:
47
56
  if not future.cancelled():
48
57
  future.set_exception(err)
49
58
 
50
- def on_completed():
59
+ def on_completed() -> None:
51
60
  nonlocal last_value
52
61
  if not future.cancelled():
53
62
  if has_value:
54
- future.set_result(last_value)
63
+ future.set_result(cast(_T, last_value))
55
64
  else:
56
65
  future.set_exception(SequenceContainsNoElementsError())
57
66
  last_value = None
@@ -1,44 +1,50 @@
1
- from typing import Callable, List, Optional, TypeVar
1
+ from typing import TypeVar
2
2
 
3
3
  from reactivex import Observable, abc
4
+ from reactivex.internal import curry_flip
4
5
 
5
6
  _T = TypeVar("_T")
6
7
 
7
8
 
8
- def to_iterable_() -> Callable[[Observable[_T]], Observable[List[_T]]]:
9
- def to_iterable(source: Observable[_T]) -> Observable[List[_T]]:
10
- """Creates an iterable from an observable sequence.
9
+ @curry_flip
10
+ def to_iterable_(source: Observable[_T]) -> Observable[list[_T]]:
11
+ """Creates an iterable from an observable sequence.
11
12
 
12
- Returns:
13
- An observable sequence containing a single element with an
14
- iterable containing all the elements of the source
15
- sequence.
16
- """
13
+ Examples:
14
+ >>> res = source.pipe(to_iterable())
15
+ >>> res = to_iterable()(source)
17
16
 
18
- def subscribe(
19
- observer: abc.ObserverBase[List[_T]],
20
- scheduler: Optional[abc.SchedulerBase] = None,
21
- ):
22
- nonlocal source
17
+ Args:
18
+ source: Source observable.
23
19
 
24
- queue: List[_T] = []
20
+ Returns:
21
+ An observable sequence containing a single element with an
22
+ iterable containing all the elements of the source
23
+ sequence.
24
+ """
25
25
 
26
- def on_next(item: _T):
27
- queue.append(item)
26
+ def subscribe(
27
+ observer: abc.ObserverBase[list[_T]],
28
+ scheduler: abc.SchedulerBase | None = None,
29
+ ):
30
+ nonlocal source
28
31
 
29
- def on_completed():
30
- nonlocal queue
31
- observer.on_next(queue)
32
- queue = []
33
- observer.on_completed()
32
+ queue: list[_T] = []
34
33
 
35
- return source.subscribe(
36
- on_next, observer.on_error, on_completed, scheduler=scheduler
37
- )
34
+ def on_next(item: _T):
35
+ queue.append(item)
38
36
 
39
- return Observable(subscribe)
37
+ def on_completed():
38
+ nonlocal queue
39
+ observer.on_next(queue)
40
+ queue = []
41
+ observer.on_completed()
40
42
 
41
- return to_iterable
43
+ return source.subscribe(
44
+ on_next, observer.on_error, on_completed, scheduler=scheduler
45
+ )
46
+
47
+ return Observable(subscribe)
42
48
 
43
49
 
44
50
  __all__ = ["to_iterable_"]
@@ -1,4 +1,4 @@
1
- from typing import Any, List, Optional
1
+ from typing import Any
2
2
 
3
3
  from reactivex import Observable, abc
4
4
  from reactivex.scheduler import NewThreadScheduler
@@ -8,7 +8,7 @@ new_thread_scheduler = NewThreadScheduler()
8
8
 
9
9
 
10
10
  def to_marbles(
11
- timespan: RelativeTime = 0.1, scheduler: Optional[abc.SchedulerBase] = None
11
+ timespan: RelativeTime = 0.1, scheduler: abc.SchedulerBase | None = None
12
12
  ):
13
13
  def to_marbles(source: Observable[Any]) -> Observable[str]:
14
14
  """Convert an observable sequence into a marble diagram string.
@@ -25,11 +25,11 @@ def to_marbles(
25
25
 
26
26
  def subscribe(
27
27
  observer: abc.ObserverBase[str],
28
- scheduler: Optional[abc.SchedulerBase] = None,
28
+ scheduler: abc.SchedulerBase | None = None,
29
29
  ):
30
30
  scheduler = scheduler or new_thread_scheduler
31
31
 
32
- result: List[str] = []
32
+ result: list[str] = []
33
33
  last = scheduler.now
34
34
 
35
35
  def add_timespan():
@@ -70,7 +70,7 @@ def stringify(value: Any) -> str:
70
70
  """Utility for stringifying an event."""
71
71
  string = str(value)
72
72
  if len(string) > 1:
73
- string = "(%s)" % string
73
+ string = f"({string})"
74
74
 
75
75
  return string
76
76
 
@@ -1,37 +1,47 @@
1
- from typing import Callable, Optional, Set, TypeVar
1
+ from typing import TypeVar
2
2
 
3
3
  from reactivex import Observable, abc
4
+ from reactivex.internal import curry_flip
4
5
 
5
6
  _T = TypeVar("_T")
6
7
 
7
8
 
8
- def to_set_() -> Callable[[Observable[_T]], Observable[Set[_T]]]:
9
+ @curry_flip
10
+ def to_set_(source: Observable[_T]) -> Observable[set[_T]]:
9
11
  """Converts the observable sequence to a set.
10
12
 
11
13
  Returns an observable sequence with a single value of a set
12
14
  containing the values from the observable sequence.
13
- """
14
15
 
15
- def to_set(source: Observable[_T]) -> Observable[Set[_T]]:
16
- def subscribe(
17
- observer: abc.ObserverBase[Set[_T]],
18
- scheduler: Optional[abc.SchedulerBase] = None,
19
- ) -> abc.DisposableBase:
20
- s: Set[_T] = set()
16
+ Examples:
17
+ >>> res = source.pipe(to_set())
18
+ >>> res = to_set()(source)
19
+
20
+ Args:
21
+ source: Source observable.
22
+
23
+ Returns:
24
+ An observable sequence with a single value of a set
25
+ containing the values from the observable sequence.
26
+ """
21
27
 
22
- def on_completed() -> None:
23
- nonlocal s
24
- observer.on_next(s)
25
- s = set()
26
- observer.on_completed()
28
+ def subscribe(
29
+ observer: abc.ObserverBase[set[_T]],
30
+ scheduler: abc.SchedulerBase | None = None,
31
+ ) -> abc.DisposableBase:
32
+ s: set[_T] = set()
27
33
 
28
- return source.subscribe(
29
- s.add, observer.on_error, on_completed, scheduler=scheduler
30
- )
34
+ def on_completed() -> None:
35
+ nonlocal s
36
+ observer.on_next(s)
37
+ s = set()
38
+ observer.on_completed()
31
39
 
32
- return Observable(subscribe)
40
+ return source.subscribe(
41
+ s.add, observer.on_error, on_completed, scheduler=scheduler
42
+ )
33
43
 
34
- return to_set
44
+ return Observable(subscribe)
35
45
 
36
46
 
37
47
  __all__ = ["to_set_"]
@@ -1,6 +1,7 @@
1
1
  import itertools
2
2
  from asyncio import Future
3
- from typing import Callable, TypeVar, Union
3
+ from collections.abc import Callable
4
+ from typing import TypeVar, Union
4
5
 
5
6
  import reactivex
6
7
  from reactivex import Observable
@@ -1,5 +1,6 @@
1
1
  import logging
2
- from typing import Any, Callable, Optional, Tuple, TypeVar
2
+ from collections.abc import Callable
3
+ from typing import Any, TypeVar
3
4
 
4
5
  from reactivex import Observable, abc, empty
5
6
  from reactivex import operators as ops
@@ -9,7 +10,7 @@ from reactivex.disposable import (
9
10
  SerialDisposable,
10
11
  SingleAssignmentDisposable,
11
12
  )
12
- from reactivex.internal import add_ref, noop
13
+ from reactivex.internal import add_ref, curry_flip, noop
13
14
  from reactivex.subject import Subject
14
15
 
15
16
  log = logging.getLogger("Rx")
@@ -17,161 +18,161 @@ log = logging.getLogger("Rx")
17
18
  _T = TypeVar("_T")
18
19
 
19
20
 
21
+ @curry_flip
20
22
  def window_toggle_(
21
- openings: Observable[Any], closing_mapper: Callable[[Any], Observable[Any]]
22
- ) -> Callable[[Observable[_T]], Observable[Observable[_T]]]:
23
+ source: Observable[_T],
24
+ openings: Observable[Any],
25
+ closing_mapper: Callable[[Any], Observable[Any]],
26
+ ) -> Observable[Observable[_T]]:
23
27
  """Projects each element of an observable sequence into zero or
24
28
  more windows.
25
29
 
26
30
  Args:
27
31
  source: Source observable to project into windows.
32
+ openings: Observable that triggers window opening.
33
+ closing_mapper: Function to create closing observable.
28
34
 
29
35
  Returns:
30
36
  An observable sequence of windows.
31
37
  """
32
38
 
33
- def window_toggle(source: Observable[_T]) -> Observable[Observable[_T]]:
34
- def mapper(args: Tuple[Any, Observable[_T]]):
35
- _, window = args
36
- return window
37
-
38
- return openings.pipe(
39
- ops.group_join(
40
- source,
41
- closing_mapper,
42
- lambda _: empty(),
43
- ),
44
- ops.map(mapper),
45
- )
39
+ def mapper(args: tuple[Any, Observable[_T]]):
40
+ _, window = args
41
+ return window
46
42
 
47
- return window_toggle
43
+ return openings.pipe(
44
+ ops.group_join(
45
+ source,
46
+ closing_mapper,
47
+ lambda _: empty(),
48
+ ),
49
+ ops.map(mapper),
50
+ )
48
51
 
49
52
 
53
+ @curry_flip
50
54
  def window_(
55
+ source: Observable[_T],
51
56
  boundaries: Observable[Any],
52
- ) -> Callable[[Observable[_T]], Observable[Observable[_T]]]:
57
+ ) -> Observable[Observable[_T]]:
53
58
  """Projects each element of an observable sequence into zero or
54
59
  more windows.
55
60
 
56
61
  Args:
57
62
  source: Source observable to project into windows.
63
+ boundaries: Observable that triggers window boundaries.
58
64
 
59
65
  Returns:
60
66
  An observable sequence of windows.
61
67
  """
62
68
 
63
- def window(source: Observable[_T]) -> Observable[Observable[_T]]:
64
- def subscribe(
65
- observer: abc.ObserverBase[Observable[_T]],
66
- scheduler: Optional[abc.SchedulerBase] = None,
67
- ) -> abc.DisposableBase:
68
- window_subject: Subject[_T] = Subject()
69
- d = CompositeDisposable()
70
- r = RefCountDisposable(d)
69
+ def subscribe(
70
+ observer: abc.ObserverBase[Observable[_T]],
71
+ scheduler: abc.SchedulerBase | None = None,
72
+ ) -> abc.DisposableBase:
73
+ window_subject: Subject[_T] = Subject()
74
+ d = CompositeDisposable()
75
+ r = RefCountDisposable(d)
71
76
 
72
- observer.on_next(add_ref(window_subject, r))
77
+ observer.on_next(add_ref(window_subject, r))
73
78
 
74
- def on_next_window(x: _T) -> None:
75
- window_subject.on_next(x)
79
+ def on_next_window(x: _T) -> None:
80
+ window_subject.on_next(x)
76
81
 
77
- def on_error(err: Exception) -> None:
78
- window_subject.on_error(err)
79
- observer.on_error(err)
82
+ def on_error(err: Exception) -> None:
83
+ window_subject.on_error(err)
84
+ observer.on_error(err)
80
85
 
81
- def on_completed() -> None:
82
- window_subject.on_completed()
83
- observer.on_completed()
86
+ def on_completed() -> None:
87
+ window_subject.on_completed()
88
+ observer.on_completed()
84
89
 
85
- d.add(
86
- source.subscribe(
87
- on_next_window, on_error, on_completed, scheduler=scheduler
88
- )
90
+ d.add(
91
+ source.subscribe(
92
+ on_next_window, on_error, on_completed, scheduler=scheduler
89
93
  )
94
+ )
90
95
 
91
- def on_next_observer(w: Observable[_T]):
92
- nonlocal window_subject
93
- window_subject.on_completed()
94
- window_subject = Subject()
95
- observer.on_next(add_ref(window_subject, r))
96
+ def on_next_observer(w: Observable[_T]):
97
+ nonlocal window_subject
98
+ window_subject.on_completed()
99
+ window_subject = Subject()
100
+ observer.on_next(add_ref(window_subject, r))
96
101
 
97
- d.add(
98
- boundaries.subscribe(
99
- on_next_observer, on_error, on_completed, scheduler=scheduler
100
- )
102
+ d.add(
103
+ boundaries.subscribe(
104
+ on_next_observer, on_error, on_completed, scheduler=scheduler
101
105
  )
102
- return r
103
-
104
- return Observable(subscribe)
106
+ )
107
+ return r
105
108
 
106
- return window
109
+ return Observable(subscribe)
107
110
 
108
111
 
112
+ @curry_flip
109
113
  def window_when_(
110
- closing_mapper: Callable[[], Observable[Any]]
111
- ) -> Callable[[Observable[_T]], Observable[Observable[_T]]]:
114
+ source: Observable[_T],
115
+ closing_mapper: Callable[[], Observable[Any]],
116
+ ) -> Observable[Observable[_T]]:
112
117
  """Projects each element of an observable sequence into zero or
113
118
  more windows.
114
119
 
115
120
  Args:
116
121
  source: Source observable to project into windows.
122
+ closing_mapper: Function that returns an observable signaling window close.
117
123
 
118
124
  Returns:
119
125
  An observable sequence of windows.
120
126
  """
121
127
 
122
- def window_when(source: Observable[_T]) -> Observable[Observable[_T]]:
123
- def subscribe(
124
- observer: abc.ObserverBase[Observable[_T]],
125
- scheduler: Optional[abc.SchedulerBase] = None,
126
- ):
127
- m = SerialDisposable()
128
- d = CompositeDisposable(m)
129
- r = RefCountDisposable(d)
130
- window: Subject[_T] = Subject()
128
+ def subscribe(
129
+ observer: abc.ObserverBase[Observable[_T]],
130
+ scheduler: abc.SchedulerBase | None = None,
131
+ ):
132
+ m = SerialDisposable()
133
+ d = CompositeDisposable(m)
134
+ r = RefCountDisposable(d)
135
+ window: Subject[_T] = Subject()
131
136
 
132
- observer.on_next(add_ref(window, r))
137
+ observer.on_next(add_ref(window, r))
133
138
 
134
- def on_next(value: _T) -> None:
135
- window.on_next(value)
139
+ def on_next(value: _T) -> None:
140
+ window.on_next(value)
136
141
 
137
- def on_error(error: Exception) -> None:
138
- window.on_error(error)
139
- observer.on_error(error)
142
+ def on_error(error: Exception) -> None:
143
+ window.on_error(error)
144
+ observer.on_error(error)
140
145
 
141
- def on_completed() -> None:
142
- window.on_completed()
143
- observer.on_completed()
144
-
145
- d.add(
146
- source.subscribe(on_next, on_error, on_completed, scheduler=scheduler)
147
- )
146
+ def on_completed() -> None:
147
+ window.on_completed()
148
+ observer.on_completed()
148
149
 
149
- def create_window_on_completed():
150
- try:
151
- window_close = closing_mapper()
152
- except Exception as exception:
153
- observer.on_error(exception)
154
- return
150
+ d.add(source.subscribe(on_next, on_error, on_completed, scheduler=scheduler))
155
151
 
156
- def on_completed():
157
- nonlocal window
158
- window.on_completed()
159
- window = Subject()
160
- observer.on_next(add_ref(window, r))
161
- create_window_on_completed()
152
+ def create_window_on_completed():
153
+ try:
154
+ window_close = closing_mapper()
155
+ except Exception as exception:
156
+ observer.on_error(exception)
157
+ return
162
158
 
163
- m1 = SingleAssignmentDisposable()
164
- m.disposable = m1
165
- m1.disposable = window_close.pipe(ops.take(1)).subscribe(
166
- noop, on_error, on_completed, scheduler=scheduler
167
- )
168
-
169
- create_window_on_completed()
170
- return r
159
+ def on_completed():
160
+ nonlocal window
161
+ window.on_completed()
162
+ window = Subject()
163
+ observer.on_next(add_ref(window, r))
164
+ create_window_on_completed()
165
+
166
+ m1 = SingleAssignmentDisposable()
167
+ m.disposable = m1
168
+ m1.disposable = window_close.pipe(ops.take(1)).subscribe(
169
+ noop, on_error, on_completed, scheduler=scheduler
170
+ )
171
171
 
172
- return Observable(subscribe)
172
+ create_window_on_completed()
173
+ return r
173
174
 
174
- return window_when
175
+ return Observable(subscribe)
175
176
 
176
177
 
177
178
  __all__ = ["window_", "window_when_", "window_toggle_"]