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,1119 @@
1
+ """Filtering operators mixin for Observable."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast
6
+
7
+ from reactivex import abc, typing
8
+
9
+ if TYPE_CHECKING:
10
+ from reactivex.observable import Observable
11
+
12
+ _T = TypeVar("_T", covariant=True)
13
+
14
+
15
+ class FilteringMixin(Generic[_T]):
16
+ """Mixin providing filtering operators for Observable.
17
+
18
+ This mixin adds operators that filter elements based on various criteria,
19
+ including predicates, position, distinctness, and timing.
20
+ """
21
+
22
+ def _as_observable(self) -> Observable[_T]:
23
+ """Cast mixin instance to Observable preserving type parameter.
24
+
25
+ This is safe because this mixin is only ever used as part of the Observable
26
+ class through multiple inheritance. At runtime, `self` in mixin methods will
27
+ always be an Observable[_T] instance. The type checker cannot infer this
28
+ because it analyzes mixins in isolation.
29
+
30
+ Returns:
31
+ The instance cast to Observable[_T] for type-safe method access.
32
+ """
33
+ return cast("Observable[_T]", self)
34
+
35
+ def filter(self, predicate: typing.Predicate[Any]) -> Observable[Any]:
36
+ """Filter elements based on a predicate.
37
+
38
+ Filters the elements of an observable sequence based on a predicate function.
39
+ Only elements for which the predicate returns True will be emitted.
40
+
41
+ Examples:
42
+ Fluent style:
43
+ >>> result = source.filter(lambda x: x > 0)
44
+ >>> result = source.filter(lambda x: x % 2 == 0) # Even numbers only
45
+
46
+ Equivalent pipe style:
47
+ >>> from reactivex import operators as ops
48
+ >>> result = source.pipe(ops.filter(lambda x: x > 0))
49
+
50
+ Args:
51
+ predicate: A function to test each source element for a condition.
52
+
53
+ Returns:
54
+ An observable sequence that contains elements from the input sequence
55
+ that satisfy the condition specified by the predicate.
56
+
57
+ See Also:
58
+ - :func:`filter <reactivex.operators.filter>`
59
+ - :meth:`filter_indexed`
60
+ """
61
+ from reactivex import operators as ops
62
+
63
+ return self._as_observable().pipe(ops.filter(predicate))
64
+
65
+ def take(self, count: int) -> Observable[Any]:
66
+ """Return a specified number of contiguous elements from the start.
67
+
68
+ Takes the first `count` elements from the observable sequence and ignores
69
+ the rest.
70
+
71
+ Examples:
72
+ Fluent style:
73
+ >>> result = source.take(5)
74
+ >>> result = source.take(3).map(lambda x: x * 2)
75
+
76
+ Equivalent pipe style:
77
+ >>> from reactivex import operators as ops
78
+ >>> result = source.pipe(ops.take(5))
79
+
80
+ Args:
81
+ count: The number of elements to return.
82
+
83
+ Returns:
84
+ An observable sequence that contains the specified number of elements
85
+ from the start of the input sequence.
86
+
87
+ See Also:
88
+ - :func:`take <reactivex.operators.take>`
89
+ - :meth:`take_last`
90
+ - :meth:`take_while`
91
+ - :meth:`skip`
92
+ """
93
+ from reactivex import operators as ops
94
+
95
+ return self._as_observable().pipe(ops.take(count))
96
+
97
+ def skip(self, count: int) -> Observable[Any]:
98
+ """Skip a specified number of elements from the start.
99
+
100
+ Bypasses the first `count` elements in the observable sequence and returns
101
+ the remaining elements.
102
+
103
+ Examples:
104
+ Fluent style:
105
+ >>> result = source.skip(5)
106
+ >>> result = source.skip(2).take(10)
107
+
108
+ Equivalent pipe style:
109
+ >>> from reactivex import operators as ops
110
+ >>> result = source.pipe(ops.skip(5))
111
+
112
+ Args:
113
+ count: The number of elements to skip before returning elements.
114
+
115
+ Returns:
116
+ An observable sequence that contains the elements that occur after
117
+ the specified index in the input sequence.
118
+
119
+ See Also:
120
+ - :func:`skip <reactivex.operators.skip>`
121
+ - :meth:`skip_last`
122
+ - :meth:`skip_while`
123
+ - :meth:`take`
124
+ """
125
+ from reactivex import operators as ops
126
+
127
+ return self._as_observable().pipe(ops.skip(count))
128
+
129
+ def first(self, predicate: typing.Predicate[Any] | None = None) -> Observable[Any]:
130
+ """Return the first element, optionally that satisfies a condition.
131
+
132
+ Returns the first element of an observable sequence that satisfies the
133
+ condition in the predicate if present, otherwise the first element.
134
+
135
+ Examples:
136
+ Fluent style:
137
+ >>> result = source.first()
138
+ >>> result = source.first(lambda x: x > 10)
139
+
140
+ Equivalent pipe style:
141
+ >>> from reactivex import operators as ops
142
+ >>> result = source.pipe(ops.first())
143
+ >>> result = source.pipe(ops.first(lambda x: x > 10))
144
+
145
+ Args:
146
+ predicate: An optional function to test each source element for a condition.
147
+
148
+ Returns:
149
+ An observable sequence containing the first element that satisfies the
150
+ condition if predicate is provided, otherwise the first element.
151
+
152
+ Raises:
153
+ SequenceContainsNoElementsError: if the source sequence is empty.
154
+
155
+ See Also:
156
+ - :func:`first <reactivex.operators.first>`
157
+ - :meth:`first_or_default`
158
+ - :meth:`last`
159
+ """
160
+ from reactivex import operators as ops
161
+
162
+ return self._as_observable().pipe(ops.first(predicate))
163
+
164
+ def last(self, predicate: typing.Predicate[Any] | None = None) -> Observable[Any]:
165
+ """Return the last element, optionally that satisfies a condition.
166
+
167
+ Returns the last element of an observable sequence that satisfies the
168
+ condition in the predicate if specified, otherwise the last element.
169
+
170
+ Examples:
171
+ Fluent style:
172
+ >>> result = source.last()
173
+ >>> result = source.last(lambda x: x < 10)
174
+
175
+ Equivalent pipe style:
176
+ >>> from reactivex import operators as ops
177
+ >>> result = source.pipe(ops.last())
178
+ >>> result = source.pipe(ops.last(lambda x: x < 10))
179
+
180
+ Args:
181
+ predicate: An optional function to test each source element for a condition.
182
+
183
+ Returns:
184
+ An observable sequence containing the last element that satisfies the
185
+ condition if predicate is provided, otherwise the last element.
186
+
187
+ Raises:
188
+ SequenceContainsNoElementsError: if the source sequence is empty.
189
+
190
+ See Also:
191
+ - :func:`last <reactivex.operators.last>`
192
+ - :meth:`last_or_default`
193
+ - :meth:`first`
194
+ """
195
+ from reactivex import operators as ops
196
+
197
+ return self._as_observable().pipe(ops.last(predicate))
198
+
199
+ def take_last(self, count: int) -> Observable[Any]:
200
+ """Take a specified number of elements from the end.
201
+
202
+ Returns a specified number of contiguous elements from the end of an
203
+ observable sequence.
204
+
205
+ Examples:
206
+ Fluent style:
207
+ >>> result = source.take_last(3)
208
+
209
+ Equivalent pipe style:
210
+ >>> from reactivex import operators as ops
211
+ >>> result = source.pipe(ops.take_last(3))
212
+
213
+ Args:
214
+ count: Number of elements to take from the end of the sequence.
215
+
216
+ Returns:
217
+ An observable sequence containing the specified number of elements
218
+ from the end of the source sequence.
219
+
220
+ See Also:
221
+ - :func:`take_last <reactivex.operators.take_last>`
222
+ - :meth:`take`
223
+ - :meth:`skip_last`
224
+ """
225
+ from reactivex import operators as ops
226
+
227
+ return self._as_observable().pipe(ops.take_last(count))
228
+
229
+ def skip_last(self, count: int) -> Observable[Any]:
230
+ """Skip a specified number of elements from the end.
231
+
232
+ Bypasses a specified number of elements at the end of an observable
233
+ sequence.
234
+
235
+ Examples:
236
+ Fluent style:
237
+ >>> result = source.skip_last(2)
238
+
239
+ Equivalent pipe style:
240
+ >>> from reactivex import operators as ops
241
+ >>> result = source.pipe(ops.skip_last(2))
242
+
243
+ Args:
244
+ count: Number of elements to bypass at the end of the sequence.
245
+
246
+ Returns:
247
+ An observable sequence containing the source sequence elements except
248
+ for the bypassed ones at the end.
249
+
250
+ See Also:
251
+ - :func:`skip_last <reactivex.operators.skip_last>`
252
+ - :meth:`skip`
253
+ - :meth:`take_last`
254
+ """
255
+ from reactivex import operators as ops
256
+
257
+ return self._as_observable().pipe(ops.skip_last(count))
258
+
259
+ def distinct(
260
+ self,
261
+ key_mapper: typing.Mapper[Any, Any] | None = None,
262
+ comparer: typing.Comparer[Any] | None = None,
263
+ ) -> Observable[Any]:
264
+ """Return distinct elements based on a key selector and comparer.
265
+
266
+ Returns an observable sequence that contains only distinct elements according
267
+ to the key_mapper and the comparer.
268
+
269
+ Examples:
270
+ Fluent style:
271
+ >>> result = source.distinct()
272
+ >>> result = source.distinct(lambda x: x.id)
273
+
274
+ Equivalent pipe style:
275
+ >>> from reactivex import operators as ops
276
+ >>> result = source.pipe(ops.distinct())
277
+
278
+ Args:
279
+ key_mapper: Optional function to compute a comparison key for each element.
280
+ comparer: Optional equality comparer for computed keys.
281
+
282
+ Returns:
283
+ An observable sequence only containing the distinct elements from
284
+ the source sequence.
285
+
286
+ See Also:
287
+ - :func:`distinct <reactivex.operators.distinct>`
288
+ - :meth:`distinct_until_changed`
289
+ """
290
+ from reactivex import operators as ops
291
+
292
+ return self._as_observable().pipe(ops.distinct(key_mapper, comparer))
293
+
294
+ def distinct_until_changed(
295
+ self,
296
+ key_mapper: typing.Mapper[Any, Any] | None = None,
297
+ comparer: typing.Comparer[Any] | None = None,
298
+ ) -> Observable[Any]:
299
+ """Return elements with distinct contiguous values.
300
+
301
+ Returns an observable sequence that contains only distinct contiguous
302
+ elements according to the key_mapper and the comparer.
303
+
304
+ Examples:
305
+ Fluent style:
306
+ >>> result = source.distinct_until_changed()
307
+ >>> result = source.distinct_until_changed(lambda x: x.id)
308
+
309
+ Equivalent pipe style:
310
+ >>> from reactivex import operators as ops
311
+ >>> result = source.pipe(ops.distinct_until_changed())
312
+
313
+ Args:
314
+ key_mapper: Optional function to compute a comparison key for each element.
315
+ comparer: Optional equality comparer for computed keys.
316
+
317
+ Returns:
318
+ An observable sequence only containing distinct contiguous elements from
319
+ the source sequence.
320
+
321
+ See Also:
322
+ - :func:`distinct_until_changed \
323
+ <reactivex.operators.distinct_until_changed>`
324
+ - :meth:`distinct`
325
+ """
326
+ from reactivex import operators as ops
327
+
328
+ return self._as_observable().pipe(
329
+ ops.distinct_until_changed(key_mapper, comparer)
330
+ )
331
+
332
+ def take_while(
333
+ self, predicate: typing.Predicate[Any], inclusive: bool = False
334
+ ) -> Observable[Any]:
335
+ """Take elements while predicate is true.
336
+
337
+ Returns elements from an observable sequence as long as a specified
338
+ condition is true.
339
+
340
+ Examples:
341
+ Fluent style:
342
+ >>> result = source.take_while(lambda x: x < 5)
343
+ >>> result = source.take_while(lambda x: x < 5, inclusive=True)
344
+
345
+ Equivalent pipe style:
346
+ >>> from reactivex import operators as ops
347
+ >>> result = source.pipe(ops.take_while(lambda x: x < 5))
348
+
349
+ Args:
350
+ predicate: A function to test each element for a condition.
351
+ inclusive: If True, include the element that failed the predicate.
352
+
353
+ Returns:
354
+ An observable sequence that contains elements from the input sequence
355
+ that occur before the element at which the test no longer passes.
356
+
357
+ See Also:
358
+ - :func:`take_while <reactivex.operators.take_while>`
359
+ - :meth:`skip_while`
360
+ - :meth:`take_until`
361
+ """
362
+ from reactivex import operators as ops
363
+
364
+ return self._as_observable().pipe(ops.take_while(predicate, inclusive))
365
+
366
+ def skip_while(self, predicate: typing.Predicate[Any]) -> Observable[Any]:
367
+ """Skip elements while predicate is true.
368
+
369
+ Bypasses elements in an observable sequence as long as a specified
370
+ condition is true and then returns the remaining elements.
371
+
372
+ Examples:
373
+ Fluent style:
374
+ >>> result = source.skip_while(lambda x: x < 5)
375
+
376
+ Equivalent pipe style:
377
+ >>> from reactivex import operators as ops
378
+ >>> result = source.pipe(ops.skip_while(lambda x: x < 5))
379
+
380
+ Args:
381
+ predicate: A function to test each element for a condition.
382
+
383
+ Returns:
384
+ An observable sequence that contains the elements from the input
385
+ sequence starting at the first element in the linear series that
386
+ does not pass the test specified by predicate.
387
+
388
+ See Also:
389
+ - :func:`skip_while <reactivex.operators.skip_while>`
390
+ - :meth:`take_while`
391
+ - :meth:`skip_until`
392
+ """
393
+ from reactivex import operators as ops
394
+
395
+ return self._as_observable().pipe(ops.skip_while(predicate))
396
+
397
+ def take_until(self, other: Observable[Any]) -> Observable[Any]:
398
+ """Take elements until other observable emits.
399
+
400
+ Returns the values from the source observable sequence until the other
401
+ observable sequence produces a value.
402
+
403
+ Examples:
404
+ Fluent style:
405
+ >>> result = source.take_until(trigger)
406
+
407
+ Equivalent pipe style:
408
+ >>> from reactivex import operators as ops
409
+ >>> result = source.pipe(ops.take_until(trigger))
410
+
411
+ Args:
412
+ other: Observable sequence that terminates propagation of elements
413
+ of the source sequence.
414
+
415
+ Returns:
416
+ An observable sequence containing the elements of the source sequence
417
+ up to the point the other sequence interrupted further propagation.
418
+
419
+ See Also:
420
+ - :func:`take_until <reactivex.operators.take_until>`
421
+ - :meth:`skip_until`
422
+ - :meth:`take_while`
423
+ """
424
+ from reactivex import operators as ops
425
+
426
+ return self._as_observable().pipe(ops.take_until(other))
427
+
428
+ def skip_until(self, other: Observable[Any]) -> Observable[Any]:
429
+ """Skip elements until other observable emits.
430
+
431
+ Returns the values from the source observable sequence only after the
432
+ other observable sequence produces a value.
433
+
434
+ Examples:
435
+ Fluent style:
436
+ >>> result = source.skip_until(trigger)
437
+
438
+ Equivalent pipe style:
439
+ >>> from reactivex import operators as ops
440
+ >>> result = source.pipe(ops.skip_until(trigger))
441
+
442
+ Args:
443
+ other: The observable sequence that triggers propagation of elements
444
+ of the source sequence.
445
+
446
+ Returns:
447
+ An observable sequence containing the elements of the source sequence
448
+ starting from the point the other sequence triggered propagation.
449
+
450
+ See Also:
451
+ - :func:`skip_until <reactivex.operators.skip_until>`
452
+ - :meth:`take_until`
453
+ - :meth:`skip_while`
454
+ """
455
+ from reactivex import operators as ops
456
+
457
+ return self._as_observable().pipe(ops.skip_until(other))
458
+
459
+ def element_at(self, index: int) -> Observable[Any]:
460
+ """Get the element at a specified index.
461
+
462
+ Returns the element at a specified index in a sequence.
463
+
464
+ Examples:
465
+ Fluent style:
466
+ >>> result = source.element_at(5)
467
+
468
+ Equivalent pipe style:
469
+ >>> from reactivex import operators as ops
470
+ >>> result = source.pipe(ops.element_at(5))
471
+
472
+ Args:
473
+ index: The zero-based index of the element to retrieve.
474
+
475
+ Returns:
476
+ An observable sequence that produces the element at the specified
477
+ position in the source sequence.
478
+
479
+ Raises:
480
+ ArgumentOutOfRangeError: if index is less than 0 or greater than
481
+ or equal to the number of elements in the source sequence.
482
+
483
+ See Also:
484
+ - :func:`element_at <reactivex.operators.element_at>`
485
+ - :meth:`element_at_or_default`
486
+ """
487
+ from reactivex import operators as ops
488
+
489
+ return self._as_observable().pipe(ops.element_at(index))
490
+
491
+ def filter_indexed(
492
+ self, predicate_indexed: typing.PredicateIndexed[Any]
493
+ ) -> Observable[Any]:
494
+ """Filter elements based on a predicate with index.
495
+
496
+ Filters the elements of an observable sequence based on a predicate function
497
+ that incorporates the element's index.
498
+
499
+ Examples:
500
+ Fluent style:
501
+ >>> result = source.filter_indexed(lambda x, i: i % 2 == 0) # Even indices
502
+ >>> result = source.filter_indexed(lambda x, i: x > i)
503
+
504
+ Equivalent pipe style:
505
+ >>> from reactivex import operators as ops
506
+ >>> result = source.pipe(ops.filter_indexed(lambda x, i: i % 2 == 0))
507
+
508
+ Args:
509
+ predicate_indexed: A function to test each source element and its index.
510
+ The function receives (value, index) and returns bool.
511
+
512
+ Returns:
513
+ An observable sequence that contains elements from the input sequence
514
+ that satisfy the condition specified by the indexed predicate.
515
+
516
+ See Also:
517
+ - :func:`filter_indexed <reactivex.operators.filter_indexed>`
518
+ - :meth:`filter`
519
+ """
520
+ from reactivex import operators as ops
521
+
522
+ return self._as_observable().pipe(ops.filter_indexed(predicate_indexed))
523
+
524
+ def take_while_indexed(
525
+ self, predicate_indexed: typing.PredicateIndexed[Any], inclusive: bool = False
526
+ ) -> Observable[Any]:
527
+ """Take elements while predicate is true, with index.
528
+
529
+ Returns elements from an observable sequence as long as a specified
530
+ condition is true, incorporating the element's index.
531
+
532
+ Examples:
533
+ Fluent style:
534
+ >>> result = source.take_while_indexed(lambda x, i: i < 5)
535
+ >>> result = source.take_while_indexed(
536
+ ... lambda x, i: x < i * 10, inclusive=True
537
+ ... )
538
+
539
+ Equivalent pipe style:
540
+ >>> from reactivex import operators as ops
541
+ >>> result = source.pipe(ops.take_while_indexed(lambda x, i: i < 5))
542
+
543
+ Args:
544
+ predicate_indexed: A function to test each element and its index.
545
+ inclusive: If True, include the element that failed the predicate.
546
+
547
+ Returns:
548
+ An observable sequence that contains elements from the input sequence
549
+ that occur before the element at which the test no longer passes.
550
+
551
+ See Also:
552
+ - :func:`take_while_indexed <reactivex.operators.take_while_indexed>`
553
+ - :meth:`take_while`
554
+ - :meth:`skip_while_indexed`
555
+ """
556
+ from reactivex import operators as ops
557
+
558
+ return self._as_observable().pipe(
559
+ ops.take_while_indexed(predicate_indexed, inclusive)
560
+ )
561
+
562
+ def skip_while_indexed(
563
+ self, predicate_indexed: typing.PredicateIndexed[Any]
564
+ ) -> Observable[Any]:
565
+ """Skip elements while predicate is true, with index.
566
+
567
+ Bypasses elements in an observable sequence as long as a specified
568
+ condition is true and then returns the remaining elements, incorporating
569
+ the element's index.
570
+
571
+ Examples:
572
+ Fluent style:
573
+ >>> result = source.skip_while_indexed(lambda x, i: i < 3)
574
+ >>> result = source.skip_while_indexed(lambda x, i: x < i * 10)
575
+
576
+ Equivalent pipe style:
577
+ >>> from reactivex import operators as ops
578
+ >>> result = source.pipe(ops.skip_while_indexed(lambda x, i: i < 3))
579
+
580
+ Args:
581
+ predicate_indexed: A function to test each element and its index.
582
+
583
+ Returns:
584
+ An observable sequence that contains the elements from the input
585
+ sequence starting at the first element in the linear series that
586
+ does not pass the test specified by predicate.
587
+
588
+ See Also:
589
+ - :func:`skip_while_indexed <reactivex.operators.skip_while_indexed>`
590
+ - :meth:`skip_while`
591
+ - :meth:`take_while_indexed`
592
+ """
593
+ from reactivex import operators as ops
594
+
595
+ return self._as_observable().pipe(ops.skip_while_indexed(predicate_indexed))
596
+
597
+ def single(self, predicate: typing.Predicate[_T] | None = None) -> Observable[_T]:
598
+ """Return single element matching predicate.
599
+
600
+ Returns the only element of an observable sequence that satisfies the condition
601
+ in the optional predicate, and reports an exception if there is not exactly one
602
+ element in the observable sequence.
603
+
604
+ Examples:
605
+ Fluent style:
606
+ >>> result = source.single()
607
+ >>> result = source.single(lambda x: x == 42)
608
+
609
+ Equivalent pipe style:
610
+ >>> from reactivex import operators as ops
611
+ >>> result = source.pipe(ops.single())
612
+ >>> result = source.pipe(ops.single(lambda x: x == 42))
613
+
614
+ Args:
615
+ predicate: A predicate function to evaluate for elements in the source
616
+ sequence.
617
+
618
+ Returns:
619
+ An observable sequence containing the single element in the observable
620
+ sequence that satisfies the condition in the predicate.
621
+
622
+ Raises:
623
+ Exception: If there is not exactly one element matching the predicate.
624
+
625
+ See Also:
626
+ - :func:`single <reactivex.operators.single>`
627
+ - :meth:`single_or_default`
628
+ - :meth:`first`
629
+ - :meth:`last`
630
+ """
631
+ from reactivex import operators as ops
632
+
633
+ return self._as_observable().pipe(ops.single(predicate))
634
+
635
+ def single_or_default(
636
+ self, predicate: typing.Predicate[_T] | None = None, default_value: Any = None
637
+ ) -> Observable[_T]:
638
+ """Return single element or default.
639
+
640
+ Returns the only element of an observable sequence that matches the predicate,
641
+ or a default value if no such element exists.
642
+
643
+ Examples:
644
+ Fluent style:
645
+ >>> result = source.single_or_default()
646
+ >>> result = source.single_or_default(lambda x: x == 42, 0)
647
+
648
+ Equivalent pipe style:
649
+ >>> from reactivex import operators as ops
650
+ >>> result = source.pipe(ops.single_or_default())
651
+ >>> result = source.pipe(ops.single_or_default(lambda x: x == 42, 0))
652
+
653
+ Args:
654
+ predicate: A predicate function to evaluate for elements in the source
655
+ sequence.
656
+ default_value: The default value if no element matches or sequence is empty.
657
+
658
+ Returns:
659
+ An observable sequence containing the single element in the observable
660
+ sequence that satisfies the condition in the predicate, or the default
661
+ value if no such element exists.
662
+
663
+ See Also:
664
+ - :func:`single_or_default <reactivex.operators.single_or_default>`
665
+ - :meth:`single`
666
+ - :meth:`first_or_default`
667
+ - :meth:`last_or_default`
668
+ """
669
+ from reactivex import operators as ops
670
+
671
+ return self._as_observable().pipe(
672
+ ops.single_or_default(predicate, default_value)
673
+ )
674
+
675
+ def single_or_default_async(
676
+ self, has_default: bool = False, default_value: Any = None
677
+ ) -> Observable[_T]:
678
+ """Return single element or default (async variant).
679
+
680
+ Returns the only element of an observable sequence, or a default value if
681
+ the sequence is empty. Reports an exception if there is more than one element.
682
+
683
+ This is an async variant optimized for certain scenarios.
684
+
685
+ Examples:
686
+ Fluent style:
687
+ >>> result = source.single_or_default_async()
688
+ >>> result = source.single_or_default_async(
689
+ ... has_default=True, default_value=0
690
+ ... )
691
+
692
+ Equivalent pipe style:
693
+ >>> from reactivex import operators as ops
694
+ >>> result = source.pipe(ops.single_or_default_async())
695
+
696
+ Args:
697
+ has_default: Whether a default value is provided.
698
+ default_value: The default value if sequence is empty.
699
+
700
+ Returns:
701
+ An observable sequence containing the single element,
702
+ or the default value if empty.
703
+
704
+ See Also:
705
+ - :func:`single_or_default_async \
706
+ <reactivex.operators.single_or_default_async>`
707
+ - :meth:`single_or_default`
708
+ - :meth:`single`
709
+ """
710
+ from reactivex import operators as ops
711
+
712
+ return self._as_observable().pipe(
713
+ ops.single_or_default_async(has_default, default_value)
714
+ )
715
+
716
+ def element_at_or_default(
717
+ self, index: int, default_value: _T | None = None
718
+ ) -> Observable[_T]:
719
+ """Get element at index or default.
720
+
721
+ Returns the element at a specified index in a sequence or a default value if
722
+ the index is out of range.
723
+
724
+ Examples:
725
+ Fluent style:
726
+ >>> result = source.element_at_or_default(5)
727
+ >>> result = source.element_at_or_default(5, 0)
728
+
729
+ Equivalent pipe style:
730
+ >>> from reactivex import operators as ops
731
+ >>> result = source.pipe(ops.element_at_or_default(5))
732
+ >>> result = source.pipe(ops.element_at_or_default(5, 0))
733
+
734
+ Args:
735
+ index: The zero-based index of the element to retrieve.
736
+ default_value: The default value if the index is outside the bounds of
737
+ the source sequence.
738
+
739
+ Returns:
740
+ An observable sequence that produces the element at the specified position
741
+ in the source sequence, or a default value if the index is outside the
742
+ bounds of the source sequence.
743
+
744
+ See Also:
745
+ - :func:`element_at_or_default <reactivex.operators.element_at_or_default>`
746
+ - :meth:`element_at`
747
+ - :meth:`first_or_default`
748
+ - :meth:`last_or_default`
749
+ """
750
+ from reactivex import operators as ops
751
+
752
+ return self._as_observable().pipe(
753
+ ops.element_at_or_default(index, default_value)
754
+ )
755
+
756
+ def first_or_default(
757
+ self,
758
+ predicate: typing.Predicate[_T] | None = None,
759
+ default_value: _T | None = None,
760
+ ) -> Observable[_T]:
761
+ """Return first element or default value.
762
+
763
+ Returns the first element of an observable sequence that satisfies
764
+ the condition in the predicate, or a default value if no such element exists.
765
+
766
+ Examples:
767
+ Fluent style:
768
+ >>> result = source.first_or_default(lambda x: x > 3, default_value=0)
769
+ >>> result = source.first_or_default(default_value=0)
770
+
771
+ Equivalent pipe style:
772
+ >>> from reactivex import operators as ops
773
+ >>> result = source.pipe(ops.first_or_default(lambda x: x > 3, 0))
774
+
775
+ Args:
776
+ predicate: Optional predicate function to test elements.
777
+ default_value: Default value if no element is found.
778
+
779
+ Returns:
780
+ An observable sequence containing the first element that matches
781
+ the predicate, or the default value.
782
+
783
+ See Also:
784
+ - :func:`first_or_default <reactivex.operators.first_or_default>`
785
+ - :meth:`first`
786
+ - :meth:`last_or_default`
787
+ """
788
+ from reactivex import operators as ops
789
+
790
+ return self._as_observable().pipe(
791
+ ops.first_or_default(predicate, default_value)
792
+ )
793
+
794
+ def last_or_default(
795
+ self,
796
+ default_value: Any = None,
797
+ predicate: typing.Predicate[_T] | None = None,
798
+ ) -> Observable[Any]:
799
+ """Return last element or default value.
800
+
801
+ Returns the last element of an observable sequence that satisfies
802
+ the condition in the predicate, or a default value if no such element exists.
803
+
804
+ Examples:
805
+ Fluent style:
806
+ >>> result = source.last_or_default()
807
+ >>> result = source.last_or_default(default_value=0)
808
+ >>> result = source.last_or_default(0, lambda x: x > 3)
809
+
810
+ Equivalent pipe style:
811
+ >>> from reactivex import operators as ops
812
+ >>> result = source.pipe(ops.last_or_default(0, lambda x: x > 3))
813
+
814
+ Args:
815
+ default_value: Default value if no element is found. Defaults to None.
816
+ predicate: Optional predicate function to test elements.
817
+
818
+ Returns:
819
+ An observable sequence containing the last element that matches
820
+ the predicate, or the default value.
821
+
822
+ See Also:
823
+ - :func:`last_or_default <reactivex.operators.last_or_default>`
824
+ - :meth:`last`
825
+ - :meth:`first_or_default`
826
+ """
827
+ from collections.abc import Callable
828
+
829
+ from reactivex import operators as ops
830
+
831
+ # Documented cast: Due to covariant TypeVar _T in Generic[_T], we cannot
832
+ # pass Predicate[_T] to the operator directly. The operator implementation
833
+ # accepts the signature but overloads don't cover all cases. We handle the
834
+ # None case separately and cast the operator for the predicate case.
835
+ if predicate is None:
836
+ return self._as_observable().pipe(ops.last_or_default(default_value))
837
+
838
+ op: Callable[[Observable[Any]], Observable[Any]] = ops.last_or_default(
839
+ default_value, predicate
840
+ )
841
+ return self._as_observable().pipe(op)
842
+
843
+ def slice(
844
+ self,
845
+ start: int | None = None,
846
+ stop: int | None = None,
847
+ step: int | None = None,
848
+ ) -> Observable[_T]:
849
+ """Extract a slice of the observable sequence.
850
+
851
+ Slices the observable using Python slice semantics. This is basically
852
+ a wrapper around the operators skip, skip_last, take, take_last and filter.
853
+
854
+ Examples:
855
+ Fluent style:
856
+ >>> result = source.slice(1, 10) # Elements from index 1 to 9
857
+ >>> result = source.slice(start=5) # Skip first 5 elements
858
+ >>> result = source.slice(step=2) # Every other element
859
+
860
+ Equivalent pipe style:
861
+ >>> from reactivex import operators as ops
862
+ >>> result = source.pipe(ops.slice(1, 10))
863
+
864
+ Args:
865
+ start: Starting index (inclusive). None means start from beginning.
866
+ stop: Stopping index (exclusive). None means continue to end.
867
+ step: Step size. None means step of 1.
868
+
869
+ Returns:
870
+ An observable sequence with the sliced elements.
871
+
872
+ See Also:
873
+ - :func:`slice <reactivex.operators.slice>`
874
+ - :meth:`skip`
875
+ - :meth:`take`
876
+ """
877
+ from reactivex import operators as ops
878
+
879
+ return self._as_observable().pipe(ops.slice(start, stop, step))
880
+
881
+ def take_last_buffer(self, count: int) -> Observable[list[_T]]:
882
+ """Take last N elements as a buffer.
883
+
884
+ Returns a list with the last N elements of the observable sequence.
885
+
886
+ Examples:
887
+ Fluent style:
888
+ >>> result = source.take_last_buffer(3)
889
+
890
+ Equivalent pipe style:
891
+ >>> from reactivex import operators as ops
892
+ >>> result = source.pipe(ops.take_last_buffer(3))
893
+
894
+ Args:
895
+ count: Number of elements to take from the end.
896
+
897
+ Returns:
898
+ An observable sequence containing a single list with the last
899
+ count elements.
900
+
901
+ See Also:
902
+ - :func:`take_last_buffer <reactivex.operators.take_last_buffer>`
903
+ - :meth:`take_last`
904
+ - :meth:`to_list`
905
+ """
906
+ from reactivex import operators as ops
907
+
908
+ return self._as_observable().pipe(ops.take_last_buffer(count))
909
+
910
+ def skip_with_time(
911
+ self,
912
+ duration: typing.RelativeTime,
913
+ scheduler: abc.SchedulerBase | None = None,
914
+ ) -> Observable[_T]:
915
+ """Skip elements for specified duration from start.
916
+
917
+ Skips elements for the specified duration from the start of the
918
+ observable source sequence.
919
+
920
+ Examples:
921
+ Fluent style:
922
+ >>> result = source.skip_with_time(5.0) # Skip first 5 seconds
923
+
924
+ Equivalent pipe style:
925
+ >>> from reactivex import operators as ops
926
+ >>> result = source.pipe(ops.skip_with_time(5.0))
927
+
928
+ Args:
929
+ duration: Duration for skipping elements (in scheduler time units).
930
+ scheduler: Optional scheduler to use for timing.
931
+
932
+ Returns:
933
+ An observable sequence with elements skipped for the specified
934
+ duration from the start.
935
+
936
+ See Also:
937
+ - :func:`skip_with_time <reactivex.operators.skip_with_time>`
938
+ - :meth:`skip`
939
+ - :meth:`take_with_time`
940
+ """
941
+ from reactivex import operators as ops
942
+
943
+ return self._as_observable().pipe(ops.skip_with_time(duration, scheduler))
944
+
945
+ def take_with_time(
946
+ self,
947
+ duration: typing.RelativeTime,
948
+ scheduler: abc.SchedulerBase | None = None,
949
+ ) -> Observable[_T]:
950
+ """Take elements for specified duration from start.
951
+
952
+ Takes elements for the specified duration from the start of the
953
+ observable source sequence.
954
+
955
+ Examples:
956
+ Fluent style:
957
+ >>> result = source.take_with_time(5.0) # Take first 5 seconds
958
+
959
+ Equivalent pipe style:
960
+ >>> from reactivex import operators as ops
961
+ >>> result = source.pipe(ops.take_with_time(5.0))
962
+
963
+ Args:
964
+ duration: Duration for taking elements (in scheduler time units).
965
+ scheduler: Optional scheduler to use for timing.
966
+
967
+ Returns:
968
+ An observable sequence with elements taken for the specified
969
+ duration from the start.
970
+
971
+ See Also:
972
+ - :func:`take_with_time <reactivex.operators.take_with_time>`
973
+ - :meth:`take`
974
+ - :meth:`skip_with_time`
975
+ """
976
+ from reactivex import operators as ops
977
+
978
+ return self._as_observable().pipe(ops.take_with_time(duration, scheduler))
979
+
980
+ def skip_last_with_time(
981
+ self,
982
+ duration: typing.RelativeTime,
983
+ scheduler: abc.SchedulerBase | None = None,
984
+ ) -> Observable[_T]:
985
+ """Skip elements for specified duration from end.
986
+
987
+ Skips elements for the specified duration from the end of the
988
+ observable source sequence.
989
+
990
+ Examples:
991
+ Fluent style:
992
+ >>> result = source.skip_last_with_time(5.0)
993
+
994
+ Equivalent pipe style:
995
+ >>> from reactivex import operators as ops
996
+ >>> result = source.pipe(ops.skip_last_with_time(5.0))
997
+
998
+ Args:
999
+ duration: Duration for skipping elements from the end.
1000
+ scheduler: Optional scheduler to use for timing.
1001
+
1002
+ Returns:
1003
+ An observable sequence with elements skipped for the specified
1004
+ duration from the end.
1005
+
1006
+ See Also:
1007
+ - :func:`skip_last_with_time <reactivex.operators.skip_last_with_time>`
1008
+ - :meth:`skip_last`
1009
+ - :meth:`take_last_with_time`
1010
+ """
1011
+ from reactivex import operators as ops
1012
+
1013
+ return self._as_observable().pipe(ops.skip_last_with_time(duration, scheduler))
1014
+
1015
+ def take_last_with_time(
1016
+ self,
1017
+ duration: typing.RelativeTime,
1018
+ scheduler: abc.SchedulerBase | None = None,
1019
+ ) -> Observable[_T]:
1020
+ """Take elements within specified duration from end.
1021
+
1022
+ Returns elements within the specified duration from the end of the
1023
+ observable source sequence.
1024
+
1025
+ Examples:
1026
+ Fluent style:
1027
+ >>> result = source.take_last_with_time(5.0)
1028
+
1029
+ Equivalent pipe style:
1030
+ >>> from reactivex import operators as ops
1031
+ >>> result = source.pipe(ops.take_last_with_time(5.0))
1032
+
1033
+ Args:
1034
+ duration: Duration for taking elements from the end.
1035
+ scheduler: Optional scheduler to use for timing.
1036
+
1037
+ Returns:
1038
+ An observable sequence with elements within the specified
1039
+ duration from the end.
1040
+
1041
+ See Also:
1042
+ - :func:`take_last_with_time <reactivex.operators.take_last_with_time>`
1043
+ - :meth:`take_last`
1044
+ - :meth:`skip_last_with_time`
1045
+ """
1046
+ from reactivex import operators as ops
1047
+
1048
+ return self._as_observable().pipe(ops.take_last_with_time(duration, scheduler))
1049
+
1050
+ def skip_until_with_time(
1051
+ self,
1052
+ start_time: typing.AbsoluteOrRelativeTime,
1053
+ scheduler: abc.SchedulerBase | None = None,
1054
+ ) -> Observable[_T]:
1055
+ """Skip elements until specified time.
1056
+
1057
+ Skips elements from the observable source sequence until the
1058
+ specified start time.
1059
+
1060
+ Examples:
1061
+ Fluent style:
1062
+ >>> result = source.skip_until_with_time(datetime(2024, 1, 1))
1063
+
1064
+ Equivalent pipe style:
1065
+ >>> from reactivex import operators as ops
1066
+ >>> result = source.pipe(ops.skip_until_with_time(datetime(2024, 1, 1)))
1067
+
1068
+ Args:
1069
+ start_time: Time to start taking elements (absolute or relative).
1070
+ scheduler: Optional scheduler to use for timing.
1071
+
1072
+ Returns:
1073
+ An observable sequence with elements skipped until the
1074
+ specified time.
1075
+
1076
+ See Also:
1077
+ - :func:`skip_until_with_time <reactivex.operators.skip_until_with_time>`
1078
+ - :meth:`skip_until`
1079
+ - :meth:`take_until_with_time`
1080
+ """
1081
+ from reactivex import operators as ops
1082
+
1083
+ return self._as_observable().pipe(
1084
+ ops.skip_until_with_time(start_time, scheduler)
1085
+ )
1086
+
1087
+ def take_until_with_time(
1088
+ self,
1089
+ end_time: typing.AbsoluteOrRelativeTime,
1090
+ scheduler: abc.SchedulerBase | None = None,
1091
+ ) -> Observable[_T]:
1092
+ """Take elements until specified time.
1093
+
1094
+ Takes elements for the specified duration until the specified time.
1095
+
1096
+ Examples:
1097
+ Fluent style:
1098
+ >>> result = source.take_until_with_time(datetime(2024, 1, 1))
1099
+
1100
+ Equivalent pipe style:
1101
+ >>> from reactivex import operators as ops
1102
+ >>> result = source.pipe(ops.take_until_with_time(datetime(2024, 1, 1)))
1103
+
1104
+ Args:
1105
+ end_time: Time to stop taking elements (absolute or relative).
1106
+ scheduler: Optional scheduler to use for timing.
1107
+
1108
+ Returns:
1109
+ An observable sequence with elements taken until the
1110
+ specified time.
1111
+
1112
+ See Also:
1113
+ - :func:`take_until_with_time <reactivex.operators.take_until_with_time>`
1114
+ - :meth:`take_until`
1115
+ - :meth:`skip_until_with_time`
1116
+ """
1117
+ from reactivex import operators as ops
1118
+
1119
+ return self._as_observable().pipe(ops.take_until_with_time(end_time, scheduler))