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,4 +1,5 @@
1
- from typing import Any, Callable, Dict, List, Optional, TypeVar
1
+ from collections.abc import Callable
2
+ from typing import Any, TypeVar
2
3
 
3
4
  from reactivex import Observable, abc, typing
4
5
  from reactivex.scheduler import TimeoutScheduler
@@ -7,7 +8,7 @@ _T = TypeVar("_T")
7
8
 
8
9
 
9
10
  def skip_last_with_time_(
10
- duration: typing.RelativeTime, scheduler: Optional[abc.SchedulerBase] = None
11
+ duration: typing.RelativeTime, scheduler: abc.SchedulerBase | None = None
11
12
  ) -> Callable[[Observable[_T]], Observable[_T]]:
12
13
  """Skips elements for the specified duration from the end of the
13
14
  observable source sequence.
@@ -34,7 +35,7 @@ def skip_last_with_time_(
34
35
  def skip_last_with_time(source: Observable[_T]) -> Observable[_T]:
35
36
  def subscribe(
36
37
  observer: abc.ObserverBase[_T],
37
- scheduler_: Optional[abc.SchedulerBase] = None,
38
+ scheduler_: abc.SchedulerBase | None = None,
38
39
  ) -> abc.DisposableBase:
39
40
  nonlocal duration
40
41
 
@@ -42,7 +43,7 @@ def skip_last_with_time_(
42
43
  scheduler or scheduler_ or TimeoutScheduler.singleton()
43
44
  )
44
45
  duration = _scheduler.to_timedelta(duration)
45
- q: List[Dict[str, Any]] = []
46
+ q: list[dict[str, Any]] = []
46
47
 
47
48
  def on_next(x: _T) -> None:
48
49
  now = _scheduler.now
@@ -1,26 +1,34 @@
1
1
  from asyncio import Future
2
- from typing import Any, Callable, Optional, TypeVar, Union
2
+ from typing import Any, TypeVar, Union
3
3
 
4
4
  from reactivex import Observable, abc, from_future
5
5
  from reactivex.disposable import CompositeDisposable, SingleAssignmentDisposable
6
+ from reactivex.internal import curry_flip
6
7
 
7
8
  _T = TypeVar("_T")
8
9
 
9
10
 
11
+ @curry_flip
10
12
  def skip_until_(
11
- other: Union[Observable[Any], "Future[Any]"]
12
- ) -> Callable[[Observable[_T]], Observable[_T]]:
13
+ source: Observable[_T],
14
+ other: Union[Observable[Any], "Future[Any]"],
15
+ ) -> Observable[_T]:
13
16
  """Returns the values from the source observable sequence only after
14
17
  the other observable sequence produces a value.
15
18
 
19
+ Examples:
20
+ >>> source.pipe(skip_until(other))
21
+ >>> skip_until(other)(source)
22
+
16
23
  Args:
24
+ source: Source observable to skip elements from.
17
25
  other: The observable sequence that triggers propagation of
18
26
  elements of the source sequence.
19
27
 
20
28
  Returns:
21
29
  An observable sequence containing the elements of the source
22
- sequence starting from the point the other sequence triggered
23
- propagation.
30
+ sequence starting from the point the other sequence triggered
31
+ propagation.
24
32
  """
25
33
 
26
34
  if isinstance(other, Future):
@@ -28,45 +36,42 @@ def skip_until_(
28
36
  else:
29
37
  obs = other
30
38
 
31
- def skip_until(source: Observable[_T]) -> Observable[_T]:
32
- def subscribe(
33
- observer: abc.ObserverBase[_T],
34
- scheduler: Optional[abc.SchedulerBase] = None,
35
- ):
36
- is_open = [False]
37
-
38
- def on_next(left: _T) -> None:
39
- if is_open[0]:
40
- observer.on_next(left)
39
+ def subscribe(
40
+ observer: abc.ObserverBase[_T],
41
+ scheduler: abc.SchedulerBase | None = None,
42
+ ):
43
+ is_open = [False]
41
44
 
42
- def on_completed() -> None:
43
- if is_open[0]:
44
- observer.on_completed()
45
+ def on_next(left: _T) -> None:
46
+ if is_open[0]:
47
+ observer.on_next(left)
45
48
 
46
- subs = source.subscribe(
47
- on_next, observer.on_error, on_completed, scheduler=scheduler
48
- )
49
- subscriptions = CompositeDisposable(subs)
49
+ def on_completed() -> None:
50
+ if is_open[0]:
51
+ observer.on_completed()
50
52
 
51
- right_subscription = SingleAssignmentDisposable()
52
- subscriptions.add(right_subscription)
53
+ subs = source.subscribe(
54
+ on_next, observer.on_error, on_completed, scheduler=scheduler
55
+ )
56
+ subscriptions = CompositeDisposable(subs)
53
57
 
54
- def on_next2(x: Any) -> None:
55
- is_open[0] = True
56
- right_subscription.dispose()
58
+ right_subscription = SingleAssignmentDisposable()
59
+ subscriptions.add(right_subscription)
57
60
 
58
- def on_completed2():
59
- right_subscription.dispose()
61
+ def on_next2(x: Any) -> None:
62
+ is_open[0] = True
63
+ right_subscription.dispose()
60
64
 
61
- right_subscription.disposable = obs.subscribe(
62
- on_next2, observer.on_error, on_completed2, scheduler=scheduler
63
- )
65
+ def on_completed2():
66
+ right_subscription.dispose()
64
67
 
65
- return subscriptions
68
+ right_subscription.disposable = obs.subscribe(
69
+ on_next2, observer.on_error, on_completed2, scheduler=scheduler
70
+ )
66
71
 
67
- return Observable(subscribe)
72
+ return subscriptions
68
73
 
69
- return skip_until
74
+ return Observable(subscribe)
70
75
 
71
76
 
72
77
  __all__ = ["skip_until_"]
@@ -1,5 +1,6 @@
1
+ from collections.abc import Callable
1
2
  from datetime import datetime
2
- from typing import Any, Callable, Optional, TypeVar
3
+ from typing import Any, TypeVar
3
4
 
4
5
  from reactivex import Observable, abc, typing
5
6
  from reactivex.disposable import CompositeDisposable
@@ -10,7 +11,7 @@ _T = TypeVar("_T")
10
11
 
11
12
  def skip_until_with_time_(
12
13
  start_time: typing.AbsoluteOrRelativeTime,
13
- scheduler: Optional[abc.SchedulerBase] = None,
14
+ scheduler: abc.SchedulerBase | None = None,
14
15
  ) -> Callable[[Observable[_T]], Observable[_T]]:
15
16
  def skip_until_with_time(source: Observable[_T]) -> Observable[_T]:
16
17
  """Skips elements from the observable source sequence until the
@@ -41,7 +42,7 @@ def skip_until_with_time_(
41
42
 
42
43
  def subscribe(
43
44
  observer: abc.ObserverBase[_T],
44
- scheduler_: Optional[abc.SchedulerBase] = None,
45
+ scheduler_: abc.SchedulerBase | None = None,
45
46
  ):
46
47
  _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton()
47
48
 
@@ -1,74 +1,95 @@
1
- from typing import Callable, Optional, Tuple, TypeVar
1
+ from typing import TypeVar
2
2
 
3
- from reactivex import Observable, abc, compose
3
+ from reactivex import Observable, abc, typing
4
4
  from reactivex import operators as ops
5
- from reactivex import typing
5
+ from reactivex.internal import curry_flip
6
6
 
7
7
  _T = TypeVar("_T")
8
8
 
9
9
 
10
+ @curry_flip
10
11
  def skip_while_(
12
+ source: Observable[_T],
11
13
  predicate: typing.Predicate[_T],
12
- ) -> Callable[[Observable[_T]], Observable[_T]]:
13
- def skip_while(source: Observable[_T]) -> Observable[_T]:
14
- """Bypasses elements in an observable sequence as long as a
15
- specified condition is true and then returns the remaining
16
- elements. The element's index is used in the logic of the
17
- predicate function.
14
+ ) -> Observable[_T]:
15
+ """Bypasses elements in an observable sequence as long as a
16
+ specified condition is true and then returns the remaining
17
+ elements.
18
18
 
19
- Example:
20
- >>> skip_while(source)
19
+ Examples:
20
+ >>> res = source.pipe(skip_while(lambda x: x < 3))
21
+ >>> res = skip_while(lambda x: x < 3)(source)
21
22
 
22
- Args:
23
- source: The source observable to skip elements from.
23
+ Args:
24
+ source: The source observable to skip elements from.
25
+ predicate: A function to test each element for a condition.
24
26
 
25
- Returns:
26
- An observable sequence that contains the elements from the
27
- input sequence starting at the first element in the linear
28
- series that does not pass the test specified by predicate.
29
- """
27
+ Returns:
28
+ An observable sequence that contains the elements from the
29
+ input sequence starting at the first element in the linear
30
+ series that does not pass the test specified by predicate.
31
+ """
30
32
 
31
- def subscribe(
32
- observer: abc.ObserverBase[_T],
33
- scheduler: Optional[abc.SchedulerBase] = None,
34
- ):
35
- running = False
33
+ def subscribe(
34
+ observer: abc.ObserverBase[_T],
35
+ scheduler: abc.SchedulerBase | None = None,
36
+ ):
37
+ running = False
36
38
 
37
- def on_next(value: _T):
38
- nonlocal running
39
+ def on_next(value: _T):
40
+ nonlocal running
39
41
 
40
- if not running:
41
- try:
42
- running = not predicate(value)
43
- except Exception as exn:
44
- observer.on_error(exn)
45
- return
42
+ if not running:
43
+ try:
44
+ running = not predicate(value)
45
+ except Exception as exn:
46
+ observer.on_error(exn)
47
+ return
46
48
 
47
- if running:
48
- observer.on_next(value)
49
+ if running:
50
+ observer.on_next(value)
49
51
 
50
- return source.subscribe(
51
- on_next, observer.on_error, observer.on_completed, scheduler=scheduler
52
- )
52
+ return source.subscribe(
53
+ on_next, observer.on_error, observer.on_completed, scheduler=scheduler
54
+ )
53
55
 
54
- return Observable(subscribe)
55
-
56
- return skip_while
56
+ return Observable(subscribe)
57
57
 
58
58
 
59
+ @curry_flip
59
60
  def skip_while_indexed_(
61
+ source: Observable[_T],
60
62
  predicate: typing.PredicateIndexed[_T],
61
- ) -> Callable[[Observable[_T]], Observable[_T]]:
62
- def indexer(x: _T, i: int) -> Tuple[_T, int]:
63
+ ) -> Observable[_T]:
64
+ """Bypasses elements in an observable sequence as long as a
65
+ specified condition is true and then returns the remaining
66
+ elements. The element's index is used in the logic of the
67
+ predicate function.
68
+
69
+ Examples:
70
+ >>> res = source.pipe(skip_while_indexed(lambda x, i: i < 3))
71
+ >>> res = skip_while_indexed(lambda x, i: i < 3)(source)
72
+
73
+ Args:
74
+ source: The source observable to skip elements from.
75
+ predicate: A function to test each element and its index for a condition.
76
+
77
+ Returns:
78
+ An observable sequence that contains the elements from the
79
+ input sequence starting at the first element that does not
80
+ pass the test specified by predicate.
81
+ """
82
+
83
+ def indexer(x: _T, i: int) -> tuple[_T, int]:
63
84
  return (x, i)
64
85
 
65
- def skipper(x: Tuple[_T, int]) -> bool:
86
+ def skipper(x: tuple[_T, int]) -> bool:
66
87
  return predicate(*x)
67
88
 
68
- def mapper(x: Tuple[_T, int]) -> _T:
89
+ def mapper(x: tuple[_T, int]) -> _T:
69
90
  return x[0]
70
91
 
71
- return compose(
92
+ return source.pipe(
72
93
  ops.map_indexed(indexer),
73
94
  ops.skip_while(skipper),
74
95
  ops.map(mapper),
@@ -1,66 +1,70 @@
1
- from typing import Any, Callable, Optional, TypeVar
1
+ from typing import Any, TypeVar
2
2
 
3
3
  from reactivex import Observable, abc, typing
4
4
  from reactivex.disposable import CompositeDisposable
5
+ from reactivex.internal import curry_flip
5
6
  from reactivex.scheduler import TimeoutScheduler
6
7
 
7
8
  _T = TypeVar("_T")
8
9
 
9
10
 
11
+ @curry_flip
10
12
  def skip_with_time_(
11
- duration: typing.RelativeTime, scheduler: Optional[abc.SchedulerBase] = None
12
- ) -> Callable[[Observable[_T]], Observable[_T]]:
13
- def skip_with_time(source: Observable[_T]) -> Observable[_T]:
14
- """Skips elements for the specified duration from the start of
15
- the observable source sequence.
16
-
17
- Args:
18
- >>> res = skip_with_time(5.0)
19
-
20
- Specifying a zero value for duration doesn't guarantee no
21
- elements will be dropped from the start of the source sequence.
22
- This is a side-effect of the asynchrony introduced by the
23
- scheduler, where the action that causes callbacks from the
24
- source sequence to be forwarded may not execute immediately,
25
- despite the zero due time.
26
-
27
- Errors produced by the source sequence are always forwarded to
28
- the result sequence, even if the error occurs before the
29
- duration.
30
-
31
- Args:
32
- duration: Duration for skipping elements from the start of
13
+ source: Observable[_T],
14
+ duration: typing.RelativeTime,
15
+ scheduler: abc.SchedulerBase | None = None,
16
+ ) -> Observable[_T]:
17
+ """Skips elements for the specified duration from the start of
18
+ the observable source sequence.
19
+
20
+ Examples:
21
+ >>> source.pipe(skip_with_time(5.0))
22
+ >>> skip_with_time(5.0)(source)
23
+
24
+ Specifying a zero value for duration doesn't guarantee no
25
+ elements will be dropped from the start of the source sequence.
26
+ This is a side-effect of the asynchrony introduced by the
27
+ scheduler, where the action that causes callbacks from the
28
+ source sequence to be forwarded may not execute immediately,
29
+ despite the zero due time.
30
+
31
+ Errors produced by the source sequence are always forwarded to
32
+ the result sequence, even if the error occurs before the
33
+ duration.
34
+
35
+ Args:
36
+ source: Source observable to skip elements from.
37
+ duration: Duration for skipping elements from the start of
33
38
  the sequence.
39
+ scheduler: Scheduler to use for timing.
34
40
 
35
- Returns:
36
- An observable sequence with the elements skipped during the
37
- specified duration from the start of the source sequence.
38
- """
41
+ Returns:
42
+ An observable sequence with the elements skipped during the
43
+ specified duration from the start of the source sequence.
44
+ """
39
45
 
40
- def subscribe(
41
- observer: abc.ObserverBase[_T],
42
- scheduler_: Optional[abc.SchedulerBase] = None,
43
- ):
44
- _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton()
45
- open = [False]
46
+ def subscribe(
47
+ observer: abc.ObserverBase[_T],
48
+ scheduler_: abc.SchedulerBase | None = None,
49
+ ):
50
+ _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton()
51
+ open = [False]
46
52
 
47
- def action(scheduler: abc.SchedulerBase, state: Any) -> None:
48
- open[0] = True
53
+ def action(scheduler: abc.SchedulerBase, state: Any) -> None:
54
+ open[0] = True
49
55
 
50
- t = _scheduler.schedule_relative(duration, action)
56
+ t = _scheduler.schedule_relative(duration, action)
51
57
 
52
- def on_next(x: _T):
53
- if open[0]:
54
- observer.on_next(x)
58
+ def on_next(x: _T):
59
+ if open[0]:
60
+ observer.on_next(x)
55
61
 
56
- d = source.subscribe(
57
- on_next, observer.on_error, observer.on_completed, scheduler=scheduler_
58
- )
59
- return CompositeDisposable(t, d)
62
+ d = source.subscribe(
63
+ on_next, observer.on_error, observer.on_completed, scheduler=scheduler_
64
+ )
65
+ return CompositeDisposable(t, d)
60
66
 
61
- return Observable(subscribe)
62
-
63
- return skip_with_time
67
+ return Observable(subscribe)
64
68
 
65
69
 
66
70
  __all__ = ["skip_with_time_"]
@@ -1,75 +1,80 @@
1
1
  from sys import maxsize
2
- from typing import Any, Callable, List, Optional, TypeVar
2
+ from typing import Any, TypeVar
3
3
 
4
4
  from reactivex import Observable
5
5
  from reactivex import operators as ops
6
+ from reactivex.internal import curry_flip
6
7
 
7
8
  _T = TypeVar("_T")
8
9
 
9
10
 
10
11
  # pylint: disable=redefined-builtin
12
+ @curry_flip
11
13
  def slice_(
12
- start: Optional[int] = None, stop: Optional[int] = None, step: Optional[int] = None
13
- ) -> Callable[[Observable[_T]], Observable[_T]]:
14
+ source: Observable[_T],
15
+ start: int | None = None,
16
+ stop: int | None = None,
17
+ step: int | None = None,
18
+ ) -> Observable[_T]:
19
+ """Slices the given observable.
20
+
21
+ It is basically a wrapper around the operators
22
+ :func:`skip <reactivex.operators.skip>`,
23
+ :func:`skip_last <reactivex.operators.skip_last>`,
24
+ :func:`take <reactivex.operators.take>`,
25
+ :func:`take_last <reactivex.operators.take_last>` and
26
+ :func:`filter <reactivex.operators.filter>`.
27
+
28
+ The following diagram helps you remember how slices works with streams.
29
+
30
+ Positive numbers are relative to the start of the events, while negative
31
+ numbers are relative to the end (close) of the stream.
32
+
33
+ .. code::
34
+
35
+ r---e---a---c---t---i---v---e---!
36
+ 0 1 2 3 4 5 6 7 8
37
+ -8 -7 -6 -5 -4 -3 -2 -1 0
38
+
39
+ Examples:
40
+ >>> result = source.pipe(slice(1, 10))
41
+ >>> result = slice(1, 10)(source)
42
+ >>> result = source.pipe(slice(1, -2))
43
+ >>> result = source.pipe(slice(1, -1, 2))
44
+
45
+ Args:
46
+ source: Observable to slice
47
+ start: Start index
48
+ stop: Stop index
49
+ step: Step size
50
+
51
+ Returns:
52
+ A sliced observable sequence.
53
+ """
14
54
  _start: int = 0 if start is None else start
15
55
  _stop: int = maxsize if stop is None else stop
16
56
  _step: int = 1 if step is None else step
17
57
 
18
- pipeline: List[Callable[[Observable[Any]], Observable[Any]]] = []
58
+ pipeline: list[Any] = []
19
59
 
20
- def slice(source: Observable[_T]) -> Observable[_T]:
21
- """The partially applied slice operator.
60
+ if _stop >= 0:
61
+ pipeline.append(ops.take(_stop))
22
62
 
23
- Slices the given observable. It is basically a wrapper around the operators
24
- :func:`skip <reactivex.operators.skip>`,
25
- :func:`skip_last <reactivex.operators.skip_last>`,
26
- :func:`take <reactivex.operators.take>`,
27
- :func:`take_last <reactivex.operators.take_last>` and
28
- :func:`filter <reactivex.operators.filter>`.
63
+ if _start > 0:
64
+ pipeline.append(ops.skip(_start))
65
+ elif _start < 0:
66
+ pipeline.append(ops.take_last(-_start))
29
67
 
30
- The following diagram helps you remember how slices works with streams.
68
+ if _stop < 0:
69
+ pipeline.append(ops.skip_last(-_stop))
31
70
 
32
- Positive numbers are relative to the start of the events, while negative
33
- numbers are relative to the end (close) of the stream.
71
+ if _step > 1:
72
+ pipeline.append(ops.filter_indexed(lambda x, i: i % _step == 0))
73
+ elif _step < 0:
74
+ # Reversing events is not supported
75
+ raise TypeError("Negative step not supported.")
34
76
 
35
- .. code::
36
-
37
- r---e---a---c---t---i---v---e---!
38
- 0 1 2 3 4 5 6 7 8
39
- -8 -7 -6 -5 -4 -3 -2 -1 0
40
-
41
- Examples:
42
- >>> result = source.slice(1, 10)
43
- >>> result = source.slice(1, -2)
44
- >>> result = source.slice(1, -1, 2)
45
-
46
- Args:
47
- source: Observable to slice
48
-
49
- Returns:
50
- A sliced observable sequence.
51
- """
52
-
53
- if _stop >= 0:
54
- pipeline.append(ops.take(_stop))
55
-
56
- if _start > 0:
57
- pipeline.append(ops.skip(_start))
58
- elif _start < 0:
59
- pipeline.append(ops.take_last(-_start))
60
-
61
- if _stop < 0:
62
- pipeline.append(ops.skip_last(-_stop))
63
-
64
- if _step > 1:
65
- pipeline.append(ops.filter_indexed(lambda x, i: i % _step == 0))
66
- elif _step < 0:
67
- # Reversing events is not supported
68
- raise TypeError("Negative step not supported.")
69
-
70
- return source.pipe(*pipeline)
71
-
72
- return slice
77
+ return source.pipe(*pipeline)
73
78
 
74
79
 
75
80
  __all__ = ["slice_"]