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
@@ -0,0 +1,688 @@
1
+ """Windowing operators mixin for Observable."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Callable
6
+ from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast
7
+
8
+ from reactivex import typing
9
+
10
+ if TYPE_CHECKING:
11
+ from reactivex.observable import Observable
12
+
13
+
14
+ _T = TypeVar("_T", covariant=True)
15
+ _A = TypeVar("_A")
16
+ _B = TypeVar("_B")
17
+
18
+
19
+ class WindowingMixin(Generic[_T]):
20
+ """Mixin providing windowing operators for Observable.
21
+
22
+ This mixin adds operators that group and window elements,
23
+ including buffering, grouping, partitioning, and pairing.
24
+ """
25
+
26
+ def _as_observable(self) -> Observable[_T]:
27
+ """Cast mixin instance to Observable preserving type parameter.
28
+
29
+ This is safe because this mixin is only ever used as part of the Observable
30
+ class through multiple inheritance. At runtime, `self` in mixin methods will
31
+ always be an Observable[_T] instance. The type checker cannot infer this
32
+ because it analyzes mixins in isolation.
33
+
34
+ Returns:
35
+ The instance cast to Observable[_T] for type-safe method access.
36
+ """
37
+ return cast("Observable[_T]", self)
38
+
39
+ def buffer(self, boundaries: Observable[Any]) -> Observable[list[_T]]:
40
+ """Buffer elements based on boundary observable.
41
+
42
+ Projects each element of an observable sequence into zero or more buffers
43
+ which are produced based on timing information from another observable sequence.
44
+
45
+ Examples:
46
+ Fluent style:
47
+ >>> result = source.buffer(rx.interval(1.0))
48
+ >>> result = source.buffer(trigger_observable)
49
+
50
+ Equivalent pipe style:
51
+ >>> from reactivex import operators as ops
52
+ >>> result = source.pipe(ops.buffer(rx.interval(1.0)))
53
+
54
+ Args:
55
+ boundaries: Observable sequence whose elements denote the creation
56
+ and completion of buffers.
57
+
58
+ Returns:
59
+ An observable sequence of buffers.
60
+
61
+ See Also:
62
+ - :func:`buffer <reactivex.operators.buffer>`
63
+ - :meth:`buffer_with_count`
64
+ - :meth:`buffer_with_time`
65
+ """
66
+ from reactivex import operators as ops
67
+
68
+ return self._as_observable().pipe(ops.buffer(boundaries))
69
+
70
+ def group_by(
71
+ self,
72
+ key_mapper: typing.Mapper[_T, Any],
73
+ element_mapper: typing.Mapper[_T, Any] | None = None,
74
+ subject_mapper: Callable[[], Any] | None = None,
75
+ ) -> Observable[Any]:
76
+ """Group elements by key.
77
+
78
+ Groups the elements of an observable sequence according to a
79
+ specified key mapper function and comparer and selects the
80
+ resulting elements by using a specified function.
81
+
82
+ Examples:
83
+ Fluent style:
84
+ >>> result = source.group_by(lambda x: x % 2)
85
+ >>> result = source.group_by(
86
+ ... key_mapper=lambda x: x.category,
87
+ ... element_mapper=lambda x: x.value
88
+ ... )
89
+
90
+ Equivalent pipe style:
91
+ >>> from reactivex import operators as ops
92
+ >>> result = source.pipe(ops.group_by(lambda x: x % 2))
93
+
94
+ Args:
95
+ key_mapper: A function to extract the key for each element.
96
+ element_mapper: A function to map each source element to an
97
+ element in an observable group.
98
+ subject_mapper: A function that returns a subject to use for
99
+ each group.
100
+
101
+ Returns:
102
+ A sequence of observable groups, each of which corresponds to
103
+ a unique key value, containing all elements that share that
104
+ same key value.
105
+
106
+ See Also:
107
+ - :func:`group_by <reactivex.operators.group_by>`
108
+ - :meth:`partition`
109
+ """
110
+ from reactivex import operators as ops
111
+
112
+ return self._as_observable().pipe(
113
+ ops.group_by(key_mapper, element_mapper, subject_mapper)
114
+ )
115
+
116
+ def partition(self, predicate: typing.Predicate[_T]) -> list[Observable[_T]]:
117
+ """Partition elements into two sequences.
118
+
119
+ Returns two observables which partition the observations of the
120
+ source by the given function. The first will trigger observations
121
+ for those values for which the predicate returns true. The second
122
+ will trigger observations for those values where the predicate
123
+ returns false.
124
+
125
+ Examples:
126
+ Fluent style:
127
+ >>> evens, odds = source.partition(lambda x: x % 2 == 0)
128
+
129
+ Equivalent pipe style:
130
+ >>> from reactivex import operators as ops
131
+ >>> evens, odds = source.pipe(ops.partition(lambda x: x % 2 == 0))
132
+
133
+ Args:
134
+ predicate: The function to test each source element for a condition.
135
+
136
+ Returns:
137
+ A list of two observable sequences. The first sequence emits
138
+ elements for which the predicate returned true; the second
139
+ emits those for which it returned false.
140
+
141
+ See Also:
142
+ - :func:`partition <reactivex.operators.partition>`
143
+ - :meth:`filter`
144
+ - :meth:`group_by`
145
+ """
146
+ from reactivex import operators as ops
147
+
148
+ return self._as_observable().pipe(ops.partition(predicate))
149
+
150
+ def pairwise(self) -> Observable[tuple[_T, _T]]:
151
+ """Emit consecutive pairs of elements.
152
+
153
+ Returns a new observable that triggers on the second and subsequent
154
+ triggerings of the input observable. The Nth triggering of the
155
+ input observable passes the arguments from the N-1th and Nth
156
+ triggering as a pair.
157
+
158
+ Examples:
159
+ Fluent style:
160
+ >>> result = source.pairwise()
161
+ >>> # Input: 1, 2, 3, 4
162
+ >>> # Output: (1, 2), (2, 3), (3, 4)
163
+
164
+ Equivalent pipe style:
165
+ >>> from reactivex import operators as ops
166
+ >>> result = source.pipe(ops.pairwise())
167
+
168
+ Returns:
169
+ An observable that triggers on successive pairs of
170
+ observations from the input observable as tuples.
171
+
172
+ See Also:
173
+ - :func:`pairwise <reactivex.operators.pairwise>`
174
+ - :meth:`buffer`
175
+ """
176
+ from reactivex import operators as ops
177
+
178
+ return self._as_observable().pipe(ops.pairwise())
179
+
180
+ def partition_indexed(
181
+ self, predicate_indexed: typing.PredicateIndexed[_T]
182
+ ) -> list[Observable[_T]]:
183
+ """Partition observable into two based on indexed predicate.
184
+
185
+ Returns a list of two observable sequences: the first contains elements
186
+ for which the predicate evaluated true, the second contains the rest.
187
+ The predicate function incorporates the element's index.
188
+
189
+ Examples:
190
+ Fluent style:
191
+ >>> true_obs, false_obs = source.partition_indexed(lambda x, i: i % 2 == 0)
192
+
193
+ Equivalent pipe style:
194
+ >>> from reactivex import operators as ops
195
+ >>> true_obs, false_obs = source.pipe(
196
+ ... ops.partition_indexed(lambda x, i: i % 2 == 0)
197
+ ... )
198
+
199
+ Args:
200
+ predicate_indexed: A function to test each element and its index.
201
+ The function receives (value, index) and returns bool.
202
+
203
+ Returns:
204
+ A list of two observables: [true_sequence, false_sequence].
205
+
206
+ See Also:
207
+ - :func:`partition_indexed <reactivex.operators.partition_indexed>`
208
+ - :meth:`partition`
209
+ - :meth:`filter_indexed`
210
+ """
211
+ from reactivex import operators as ops
212
+
213
+ return ops.partition_indexed(predicate_indexed)(self._as_observable())
214
+
215
+ def buffer_with_count(
216
+ self, count: int, skip: int | None = None
217
+ ) -> Observable[list[_T]]:
218
+ """Buffer elements by count.
219
+
220
+ Projects each element of an observable sequence into zero or more buffers
221
+ which are produced based on element count information.
222
+
223
+ Examples:
224
+ Fluent style:
225
+ >>> result = source.buffer_with_count(5)
226
+ >>> result = source.buffer_with_count(5, 3) # overlapping buffers
227
+
228
+ Equivalent pipe style:
229
+ >>> from reactivex import operators as ops
230
+ >>> result = source.pipe(ops.buffer_with_count(5))
231
+
232
+ Args:
233
+ count: Length of each buffer.
234
+ skip: Number of elements to skip between creation of consecutive
235
+ buffers. If not specified, defaults to count.
236
+
237
+ Returns:
238
+ An observable sequence of buffers.
239
+
240
+ See Also:
241
+ - :func:`buffer_with_count <reactivex.operators.buffer_with_count>`
242
+ - :meth:`buffer`
243
+ - :meth:`buffer_with_time`
244
+ """
245
+ from reactivex import operators as ops
246
+
247
+ return self._as_observable().pipe(ops.buffer_with_count(count, skip))
248
+
249
+ def buffer_with_time(
250
+ self,
251
+ timespan: typing.RelativeTime,
252
+ timeshift: typing.RelativeTime | None = None,
253
+ scheduler: Any = None,
254
+ ) -> Observable[list[_T]]:
255
+ """Buffer elements by time.
256
+
257
+ Projects each element of an observable sequence into zero or more buffers
258
+ which are produced based on timing information.
259
+
260
+ Examples:
261
+ Fluent style:
262
+ >>> result = source.buffer_with_time(1.0)
263
+ >>> result = source.buffer_with_time(1.0, 0.5) # overlapping buffers
264
+
265
+ Equivalent pipe style:
266
+ >>> from reactivex import operators as ops
267
+ >>> result = source.pipe(ops.buffer_with_time(1.0))
268
+
269
+ Args:
270
+ timespan: Length of each buffer (in seconds).
271
+ timeshift: Interval between creation of consecutive buffers.
272
+ If not specified, defaults to timespan.
273
+ scheduler: Scheduler to run the timer on. If not specified,
274
+ defaults to timeout scheduler.
275
+
276
+ Returns:
277
+ An observable sequence of buffers.
278
+
279
+ See Also:
280
+ - :func:`buffer_with_time <reactivex.operators.buffer_with_time>`
281
+ - :meth:`buffer`
282
+ - :meth:`buffer_with_count`
283
+ """
284
+ from reactivex import operators as ops
285
+
286
+ return self._as_observable().pipe(
287
+ ops.buffer_with_time(timespan, timeshift, scheduler)
288
+ )
289
+
290
+ def buffer_with_time_or_count(
291
+ self,
292
+ timespan: typing.RelativeTime,
293
+ count: int,
294
+ scheduler: Any = None,
295
+ ) -> Observable[list[_T]]:
296
+ """Buffer elements by time or count.
297
+
298
+ Projects each element of an observable sequence into a buffer that is
299
+ completed when either it's full or a given amount of time has elapsed.
300
+
301
+ Examples:
302
+ Fluent style:
303
+ >>> result = source.buffer_with_time_or_count(1.0, 5)
304
+
305
+ Equivalent pipe style:
306
+ >>> from reactivex import operators as ops
307
+ >>> result = source.pipe(ops.buffer_with_time_or_count(1.0, 5))
308
+
309
+ Args:
310
+ timespan: Maximum time length of a buffer.
311
+ count: Maximum element count of a buffer.
312
+ scheduler: Scheduler to run the timer on. If not specified,
313
+ defaults to timeout scheduler.
314
+
315
+ Returns:
316
+ An observable sequence of buffers.
317
+
318
+ See Also:
319
+ - :func:`buffer_with_time_or_count
320
+ <reactivex.operators.buffer_with_time_or_count>`
321
+ - :meth:`buffer_with_time`
322
+ - :meth:`buffer_with_count`
323
+ """
324
+ from reactivex import operators as ops
325
+
326
+ return self._as_observable().pipe(
327
+ ops.buffer_with_time_or_count(timespan, count, scheduler)
328
+ )
329
+
330
+ def buffer_when(
331
+ self, closing_mapper: Callable[[], Observable[Any]]
332
+ ) -> Observable[list[_T]]:
333
+ """Buffer elements with dynamic boundaries.
334
+
335
+ Projects each element of an observable sequence into zero or more buffers.
336
+
337
+ Examples:
338
+ Fluent style:
339
+ >>> result = source.buffer_when(lambda: rx.timer(1.0))
340
+
341
+ Equivalent pipe style:
342
+ >>> from reactivex import operators as ops
343
+ >>> result = source.pipe(ops.buffer_when(lambda: rx.timer(1.0)))
344
+
345
+ Args:
346
+ closing_mapper: A function invoked to define the closing of each
347
+ produced buffer. A buffer is started when the previous buffer
348
+ is closed. The observable returned by the closing_mapper is
349
+ used to close the buffer when it emits any notification.
350
+
351
+ Returns:
352
+ An observable sequence of buffers.
353
+
354
+ See Also:
355
+ - :func:`buffer_when <reactivex.operators.buffer_when>`
356
+ - :meth:`buffer`
357
+ - :meth:`buffer_toggle`
358
+ """
359
+ from reactivex import operators as ops
360
+
361
+ return self._as_observable().pipe(ops.buffer_when(closing_mapper))
362
+
363
+ def buffer_toggle(
364
+ self,
365
+ openings: Observable[Any],
366
+ closing_mapper: Callable[[Any], Observable[Any]],
367
+ ) -> Observable[list[_T]]:
368
+ """Buffer elements with opening and closing observables.
369
+
370
+ Projects each element of an observable sequence into zero or more buffers.
371
+
372
+ Examples:
373
+ Fluent style:
374
+ >>> result = source.buffer_toggle(
375
+ ... openings=rx.interval(5.0),
376
+ ... closing_mapper=lambda x: rx.timer(2.0)
377
+ ... )
378
+
379
+ Equivalent pipe style:
380
+ >>> from reactivex import operators as ops
381
+ >>> result = source.pipe(
382
+ ... ops.buffer_toggle(
383
+ ... openings=rx.interval(5.0),
384
+ ... closing_mapper=lambda x: rx.timer(2.0)
385
+ ... )
386
+ ... )
387
+
388
+ Args:
389
+ openings: Observable sequence whose elements denote the
390
+ opening of buffers.
391
+ closing_mapper: A function invoked to define the closing of
392
+ each produced buffer. Value emitted by openings observable
393
+ is provided as argument. The observable returned by
394
+ closing_mapper is used to close the buffer when it emits
395
+ any notification.
396
+
397
+ Returns:
398
+ An observable sequence of buffers.
399
+
400
+ See Also:
401
+ - :func:`buffer_toggle <reactivex.operators.buffer_toggle>`
402
+ - :meth:`buffer_when`
403
+ """
404
+ from reactivex import operators as ops
405
+
406
+ return self._as_observable().pipe(ops.buffer_toggle(openings, closing_mapper))
407
+
408
+ def window(self, boundaries: Observable[Any]) -> Observable[Observable[_T]]:
409
+ """Window elements based on boundary observable.
410
+
411
+ Projects each element of an observable sequence into zero or more windows
412
+ which are produced based on timing information from another observable
413
+ sequence.
414
+
415
+ Examples:
416
+ Fluent style:
417
+ >>> result = source.window(rx.interval(1.0))
418
+
419
+ Equivalent pipe style:
420
+ >>> from reactivex import operators as ops
421
+ >>> result = source.pipe(ops.window(rx.interval(1.0)))
422
+
423
+ Args:
424
+ boundaries: Observable sequence whose elements denote the creation
425
+ and completion of windows.
426
+
427
+ Returns:
428
+ An observable sequence of windows.
429
+
430
+ See Also:
431
+ - :func:`window <reactivex.operators.window>`
432
+ - :meth:`window_with_count`
433
+ - :meth:`window_with_time`
434
+ """
435
+ from reactivex import operators as ops
436
+
437
+ return self._as_observable().pipe(ops.window(boundaries))
438
+
439
+ def window_with_count(
440
+ self, count: int, skip: int | None = None
441
+ ) -> Observable[Observable[_T]]:
442
+ """Window elements by count.
443
+
444
+ Projects each element of an observable sequence into zero or more windows
445
+ which are produced based on element count information.
446
+
447
+ Examples:
448
+ Fluent style:
449
+ >>> result = source.window_with_count(5)
450
+ >>> result = source.window_with_count(5, 3) # overlapping windows
451
+
452
+ Equivalent pipe style:
453
+ >>> from reactivex import operators as ops
454
+ >>> result = source.pipe(ops.window_with_count(5))
455
+
456
+ Args:
457
+ count: Length of each window.
458
+ skip: Number of elements to skip between creation of consecutive
459
+ windows. If not specified, defaults to count.
460
+
461
+ Returns:
462
+ An observable sequence of windows.
463
+
464
+ See Also:
465
+ - :func:`window_with_count <reactivex.operators.window_with_count>`
466
+ - :meth:`window`
467
+ - :meth:`window_with_time`
468
+ """
469
+ from reactivex import operators as ops
470
+
471
+ return self._as_observable().pipe(ops.window_with_count(count, skip))
472
+
473
+ def window_with_time(
474
+ self,
475
+ timespan: typing.RelativeTime,
476
+ timeshift: typing.RelativeTime | None = None,
477
+ scheduler: Any = None,
478
+ ) -> Observable[Observable[_T]]:
479
+ """Window elements by time.
480
+
481
+ Projects each element of an observable sequence into zero or more windows
482
+ which are produced based on timing information.
483
+
484
+ Examples:
485
+ Fluent style:
486
+ >>> result = source.window_with_time(1.0)
487
+ >>> result = source.window_with_time(1.0, 0.5) # overlapping windows
488
+
489
+ Equivalent pipe style:
490
+ >>> from reactivex import operators as ops
491
+ >>> result = source.pipe(ops.window_with_time(1.0))
492
+
493
+ Args:
494
+ timespan: Length of each window (in seconds).
495
+ timeshift: Interval between creation of consecutive windows.
496
+ If not specified, defaults to timespan.
497
+ scheduler: Scheduler to run the timer on. If not specified,
498
+ defaults to timeout scheduler.
499
+
500
+ Returns:
501
+ An observable sequence of windows.
502
+
503
+ See Also:
504
+ - :func:`window_with_time <reactivex.operators.window_with_time>`
505
+ - :meth:`window`
506
+ - :meth:`window_with_count`
507
+ """
508
+ from reactivex import operators as ops
509
+
510
+ return self._as_observable().pipe(
511
+ ops.window_with_time(timespan, timeshift, scheduler)
512
+ )
513
+
514
+ def window_with_time_or_count(
515
+ self,
516
+ timespan: typing.RelativeTime,
517
+ count: int,
518
+ scheduler: Any = None,
519
+ ) -> Observable[Observable[_T]]:
520
+ """Window elements by time or count.
521
+
522
+ Projects each element of an observable sequence into a window that is
523
+ completed when either it's full or a given amount of time has elapsed.
524
+
525
+ Examples:
526
+ Fluent style:
527
+ >>> result = source.window_with_time_or_count(1.0, 5)
528
+
529
+ Equivalent pipe style:
530
+ >>> from reactivex import operators as ops
531
+ >>> result = source.pipe(ops.window_with_time_or_count(1.0, 5))
532
+
533
+ Args:
534
+ timespan: Maximum time length of a window.
535
+ count: Maximum element count of a window.
536
+ scheduler: Scheduler to run the timer on. If not specified,
537
+ defaults to timeout scheduler.
538
+
539
+ Returns:
540
+ An observable sequence of windows.
541
+
542
+ See Also:
543
+ - :func:`window_with_time_or_count
544
+ <reactivex.operators.window_with_time_or_count>`
545
+ - :meth:`window_with_time`
546
+ - :meth:`window_with_count`
547
+ """
548
+ from reactivex import operators as ops
549
+
550
+ return self._as_observable().pipe(
551
+ ops.window_with_time_or_count(timespan, count, scheduler)
552
+ )
553
+
554
+ def window_when(
555
+ self, closing_mapper: Callable[[], Observable[Any]]
556
+ ) -> Observable[Observable[_T]]:
557
+ """Window elements with dynamic boundaries.
558
+
559
+ Projects each element of an observable sequence into zero or more windows.
560
+
561
+ Examples:
562
+ Fluent style:
563
+ >>> result = source.window_when(lambda: rx.timer(1.0))
564
+
565
+ Equivalent pipe style:
566
+ >>> from reactivex import operators as ops
567
+ >>> result = source.pipe(ops.window_when(lambda: rx.timer(1.0)))
568
+
569
+ Args:
570
+ closing_mapper: A function invoked to define the closing of each
571
+ produced window. A window is started when the previous window
572
+ is closed. The observable returned by the closing_mapper is
573
+ used to close the window when it emits any notification.
574
+
575
+ Returns:
576
+ An observable sequence of windows.
577
+
578
+ See Also:
579
+ - :func:`window_when <reactivex.operators.window_when>`
580
+ - :meth:`window`
581
+ - :meth:`window_toggle`
582
+ """
583
+ from reactivex import operators as ops
584
+
585
+ return self._as_observable().pipe(ops.window_when(closing_mapper))
586
+
587
+ def window_toggle(
588
+ self,
589
+ openings: Observable[Any],
590
+ closing_mapper: Callable[[Any], Observable[Any]],
591
+ ) -> Observable[Observable[_T]]:
592
+ """Window elements with opening and closing observables.
593
+
594
+ Projects each element of an observable sequence into zero or more windows.
595
+
596
+ Examples:
597
+ Fluent style:
598
+ >>> result = source.window_toggle(
599
+ ... openings=rx.interval(5.0),
600
+ ... closing_mapper=lambda x: rx.timer(2.0)
601
+ ... )
602
+
603
+ Equivalent pipe style:
604
+ >>> from reactivex import operators as ops
605
+ >>> result = source.pipe(
606
+ ... ops.window_toggle(
607
+ ... openings=rx.interval(5.0),
608
+ ... closing_mapper=lambda x: rx.timer(2.0)
609
+ ... )
610
+ ... )
611
+
612
+ Args:
613
+ openings: Observable sequence whose elements denote the
614
+ opening of windows.
615
+ closing_mapper: A function invoked to define the closing of
616
+ each produced window. Value emitted by openings observable
617
+ is provided as argument. The observable returned by
618
+ closing_mapper is used to close the window when it emits
619
+ any notification.
620
+
621
+ Returns:
622
+ An observable sequence of windows.
623
+
624
+ See Also:
625
+ - :func:`window_toggle <reactivex.operators.window_toggle>`
626
+ - :meth:`window_when`
627
+ """
628
+ from reactivex import operators as ops
629
+
630
+ return self._as_observable().pipe(ops.window_toggle(openings, closing_mapper))
631
+
632
+ def group_by_until(
633
+ self,
634
+ key_mapper: typing.Mapper[_T, _A],
635
+ element_mapper: typing.Mapper[_T, _B] | None,
636
+ duration_mapper: Callable[[Any], Observable[Any]],
637
+ subject_mapper: Callable[[], Any] | None = None,
638
+ ) -> Observable[Any]:
639
+ """Group elements by key with duration control.
640
+
641
+ Groups the elements of an observable sequence according to a specified
642
+ key mapper function and comparer and selects the resulting elements by
643
+ using a specified function. A duration mapper is used to control the
644
+ lifetime of groups.
645
+
646
+ Examples:
647
+ Fluent style:
648
+ >>> result = source.group_by_until(
649
+ ... key_mapper=lambda x: x % 2,
650
+ ... element_mapper=None,
651
+ ... duration_mapper=lambda grp: rx.timer(5.0)
652
+ ... )
653
+
654
+ Equivalent pipe style:
655
+ >>> from reactivex import operators as ops
656
+ >>> result = source.pipe(
657
+ ... ops.group_by_until(
658
+ ... key_mapper=lambda x: x % 2,
659
+ ... element_mapper=None,
660
+ ... duration_mapper=lambda grp: rx.timer(5.0)
661
+ ... )
662
+ ... )
663
+
664
+ Args:
665
+ key_mapper: A function to extract the key for each element.
666
+ element_mapper: A function to map each source element to an
667
+ element in an observable group.
668
+ duration_mapper: A function to signal the expiration of a group.
669
+ subject_mapper: A function that returns a subject to use for
670
+ each group.
671
+
672
+ Returns:
673
+ A sequence of observable groups, each of which corresponds to
674
+ a unique key value, containing all elements that share that
675
+ same key value. When a group is expired, a new group with the
676
+ same key will be created.
677
+
678
+ See Also:
679
+ - :func:`group_by_until <reactivex.operators.group_by_until>`
680
+ - :meth:`group_by`
681
+ """
682
+ from reactivex import operators as ops
683
+
684
+ return self._as_observable().pipe(
685
+ ops.group_by_until(
686
+ key_mapper, element_mapper, duration_mapper, subject_mapper
687
+ )
688
+ )
@@ -1,4 +1,4 @@
1
- from typing import Any, Optional
1
+ from typing import Any
2
2
 
3
3
  from reactivex import Observable, abc
4
4
  from reactivex.disposable import Disposable
@@ -13,7 +13,7 @@ def never_() -> Observable[Any]:
13
13
  """
14
14
 
15
15
  def subscribe(
16
- observer: abc.ObserverBase[Any], scheduler: Optional[abc.SchedulerBase] = None
16
+ observer: abc.ObserverBase[Any], scheduler: abc.SchedulerBase | None = None
17
17
  ) -> abc.DisposableBase:
18
18
  return Disposable()
19
19