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.
- reactivex/__init__.py +35 -39
- reactivex/_version.py +1 -1
- reactivex/abc/disposable.py +3 -4
- reactivex/abc/observable.py +13 -6
- reactivex/abc/observer.py +2 -1
- reactivex/abc/periodicscheduler.py +7 -6
- reactivex/abc/scheduler.py +10 -9
- reactivex/abc/subject.py +5 -5
- reactivex/disposable/compositedisposable.py +4 -4
- reactivex/disposable/disposable.py +1 -2
- reactivex/disposable/multipleassignmentdisposable.py +2 -3
- reactivex/disposable/refcountdisposable.py +1 -2
- reactivex/disposable/serialdisposable.py +4 -5
- reactivex/disposable/singleassignmentdisposable.py +3 -4
- reactivex/internal/__init__.py +2 -0
- reactivex/internal/basic.py +2 -2
- reactivex/internal/concurrency.py +2 -1
- reactivex/internal/curry.py +59 -0
- reactivex/internal/exceptions.py +7 -12
- reactivex/internal/priorityqueue.py +2 -2
- reactivex/internal/utils.py +3 -2
- reactivex/notification.py +22 -21
- reactivex/observable/case.py +5 -6
- reactivex/observable/catch.py +3 -2
- reactivex/observable/combinelatest.py +4 -5
- reactivex/observable/concat.py +3 -2
- reactivex/observable/connectableobservable.py +7 -7
- reactivex/observable/defer.py +4 -3
- reactivex/observable/empty.py +3 -4
- reactivex/observable/forkjoin.py +5 -5
- reactivex/observable/fromcallback.py +4 -3
- reactivex/observable/fromfuture.py +2 -2
- reactivex/observable/fromiterable.py +4 -3
- reactivex/observable/generate.py +2 -2
- reactivex/observable/generatewithrelativetime.py +4 -3
- reactivex/observable/groupedobservable.py +4 -4
- reactivex/observable/ifthen.py +3 -2
- reactivex/observable/interval.py +1 -4
- reactivex/observable/marbles.py +18 -17
- reactivex/observable/mixins/__init__.py +32 -0
- reactivex/observable/mixins/combination.py +481 -0
- reactivex/observable/mixins/conditional.py +135 -0
- reactivex/observable/mixins/error_handling.py +130 -0
- reactivex/observable/mixins/filtering.py +1119 -0
- reactivex/observable/mixins/mathematical.py +277 -0
- reactivex/observable/mixins/multicasting.py +306 -0
- reactivex/observable/mixins/testing.py +193 -0
- reactivex/observable/mixins/time_based.py +209 -0
- reactivex/observable/mixins/transformation.py +632 -0
- reactivex/observable/mixins/utility.py +811 -0
- reactivex/observable/mixins/windowing.py +688 -0
- reactivex/observable/never.py +2 -2
- reactivex/observable/observable.py +72 -25
- reactivex/observable/onerrorresumenext.py +7 -6
- reactivex/observable/range.py +6 -6
- reactivex/observable/repeat.py +2 -2
- reactivex/observable/returnvalue.py +6 -5
- reactivex/observable/start.py +3 -2
- reactivex/observable/startasync.py +2 -1
- reactivex/observable/throw.py +3 -3
- reactivex/observable/timer.py +12 -12
- reactivex/observable/toasync.py +3 -2
- reactivex/observable/using.py +5 -4
- reactivex/observable/withlatestfrom.py +4 -5
- reactivex/observable/zip.py +7 -6
- reactivex/observer/autodetachobserver.py +4 -4
- reactivex/observer/observer.py +5 -4
- reactivex/observer/scheduledobserver.py +2 -2
- reactivex/operators/__init__.py +162 -208
- reactivex/operators/_all.py +23 -6
- reactivex/operators/_amb.py +88 -75
- reactivex/operators/_asobservable.py +20 -17
- reactivex/operators/_average.py +48 -45
- reactivex/operators/_buffer.py +81 -35
- reactivex/operators/_bufferwithtime.py +29 -9
- reactivex/operators/_bufferwithtimeorcount.py +27 -8
- reactivex/operators/_catch.py +33 -32
- reactivex/operators/_combinelatest.py +28 -20
- reactivex/operators/_concat.py +16 -13
- reactivex/operators/_contains.py +25 -6
- reactivex/operators/_count.py +24 -8
- reactivex/operators/_debounce.py +141 -138
- reactivex/operators/_defaultifempty.py +45 -42
- reactivex/operators/_delay.py +24 -23
- reactivex/operators/_delaysubscription.py +23 -21
- reactivex/operators/_delaywithmapper.py +10 -11
- reactivex/operators/_dematerialize.py +25 -21
- reactivex/operators/_distinct.py +50 -46
- reactivex/operators/_distinctuntilchanged.py +60 -57
- reactivex/operators/_do.py +123 -116
- reactivex/operators/_dowhile.py +3 -2
- reactivex/operators/_elementatordefault.py +57 -33
- reactivex/operators/_exclusive.py +59 -53
- reactivex/operators/_expand.py +82 -77
- reactivex/operators/_filter.py +63 -68
- reactivex/operators/_finallyaction.py +3 -2
- reactivex/operators/_find.py +49 -32
- reactivex/operators/_first.py +18 -11
- reactivex/operators/_firstordefault.py +5 -4
- reactivex/operators/_flatmap.py +89 -83
- reactivex/operators/_forkjoin.py +23 -18
- reactivex/operators/_groupby.py +27 -6
- reactivex/operators/_groupbyuntil.py +8 -5
- reactivex/operators/_groupjoin.py +7 -6
- reactivex/operators/_ignoreelements.py +20 -15
- reactivex/operators/_isempty.py +15 -4
- reactivex/operators/_join.py +6 -5
- reactivex/operators/_last.py +36 -31
- reactivex/operators/_lastordefault.py +8 -8
- reactivex/operators/_map.py +54 -39
- reactivex/operators/_materialize.py +30 -31
- reactivex/operators/_max.py +18 -11
- reactivex/operators/_maxby.py +5 -5
- reactivex/operators/_merge.py +132 -129
- reactivex/operators/_min.py +16 -10
- reactivex/operators/_minby.py +9 -8
- reactivex/operators/_multicast.py +9 -9
- reactivex/operators/_observeon.py +35 -31
- reactivex/operators/_onerrorresumenext.py +2 -1
- reactivex/operators/_pairwise.py +38 -34
- reactivex/operators/_partition.py +80 -73
- reactivex/operators/_pluck.py +4 -3
- reactivex/operators/_publish.py +36 -21
- reactivex/operators/_publishvalue.py +8 -7
- reactivex/operators/_reduce.py +16 -12
- reactivex/operators/_repeat.py +33 -30
- reactivex/operators/_replay.py +9 -9
- reactivex/operators/_retry.py +12 -10
- reactivex/operators/_sample.py +31 -27
- reactivex/operators/_scan.py +41 -39
- reactivex/operators/_sequenceequal.py +8 -7
- reactivex/operators/_single.py +20 -13
- reactivex/operators/_singleordefault.py +6 -5
- reactivex/operators/_skip.py +35 -32
- reactivex/operators/_skiplast.py +38 -34
- reactivex/operators/_skiplastwithtime.py +5 -4
- reactivex/operators/_skipuntil.py +40 -35
- reactivex/operators/_skipuntilwithtime.py +4 -3
- reactivex/operators/_skipwhile.py +65 -44
- reactivex/operators/_skipwithtime.py +50 -46
- reactivex/operators/_slice.py +58 -53
- reactivex/operators/_some.py +48 -47
- reactivex/operators/_startswith.py +17 -15
- reactivex/operators/_subscribeon.py +44 -41
- reactivex/operators/_sum.py +23 -6
- reactivex/operators/_switchlatest.py +71 -69
- reactivex/operators/_take.py +37 -33
- reactivex/operators/_takelast.py +37 -36
- reactivex/operators/_takelastbuffer.py +38 -37
- reactivex/operators/_takelastwithtime.py +60 -56
- reactivex/operators/_takeuntil.py +33 -32
- reactivex/operators/_takeuntilwithtime.py +42 -39
- reactivex/operators/_takewhile.py +108 -100
- reactivex/operators/_takewithtime.py +46 -41
- reactivex/operators/_throttlefirst.py +52 -45
- reactivex/operators/_timeinterval.py +40 -36
- reactivex/operators/_timeout.py +81 -79
- reactivex/operators/_timeoutwithmapper.py +6 -5
- reactivex/operators/_timestamp.py +24 -22
- reactivex/operators/_todict.py +51 -43
- reactivex/operators/_tofuture.py +24 -15
- reactivex/operators/_toiterable.py +33 -27
- reactivex/operators/_tomarbles.py +5 -5
- reactivex/operators/_toset.py +29 -19
- reactivex/operators/_whiledo.py +2 -1
- reactivex/operators/_window.py +100 -99
- reactivex/operators/_windowwithcount.py +56 -54
- reactivex/operators/_windowwithtime.py +95 -79
- reactivex/operators/_windowwithtimeorcount.py +85 -69
- reactivex/operators/_withlatestfrom.py +13 -9
- reactivex/operators/_zip.py +67 -63
- reactivex/operators/connectable/_refcount.py +4 -3
- reactivex/pipe.py +2 -1
- reactivex/run.py +8 -4
- reactivex/scheduler/catchscheduler.py +11 -10
- reactivex/scheduler/currentthreadscheduler.py +2 -3
- reactivex/scheduler/eventloop/asyncioscheduler.py +7 -6
- reactivex/scheduler/eventloop/asynciothreadsafescheduler.py +12 -14
- reactivex/scheduler/eventloop/eventletscheduler.py +4 -4
- reactivex/scheduler/eventloop/geventscheduler.py +4 -4
- reactivex/scheduler/eventloop/ioloopscheduler.py +4 -4
- reactivex/scheduler/eventloop/twistedscheduler.py +4 -4
- reactivex/scheduler/eventloopscheduler.py +9 -12
- reactivex/scheduler/historicalscheduler.py +1 -2
- reactivex/scheduler/immediatescheduler.py +5 -4
- reactivex/scheduler/mainloop/gtkscheduler.py +6 -7
- reactivex/scheduler/mainloop/pygamescheduler.py +4 -4
- reactivex/scheduler/mainloop/qtscheduler.py +6 -6
- reactivex/scheduler/mainloop/tkinterscheduler.py +4 -4
- reactivex/scheduler/mainloop/wxscheduler.py +7 -7
- reactivex/scheduler/newthreadscheduler.py +6 -8
- reactivex/scheduler/periodicscheduler.py +4 -4
- reactivex/scheduler/scheduleditem.py +4 -4
- reactivex/scheduler/scheduler.py +5 -5
- reactivex/scheduler/threadpoolscheduler.py +3 -3
- reactivex/scheduler/timeoutscheduler.py +5 -4
- reactivex/scheduler/trampoline.py +1 -2
- reactivex/scheduler/trampolinescheduler.py +5 -6
- reactivex/scheduler/virtualtimescheduler.py +4 -4
- reactivex/subject/asyncsubject.py +2 -2
- reactivex/subject/behaviorsubject.py +2 -2
- reactivex/subject/innersubscription.py +2 -2
- reactivex/subject/replaysubject.py +8 -8
- reactivex/subject/subject.py +4 -4
- reactivex/testing/coldobservable.py +5 -5
- reactivex/testing/hotobservable.py +6 -6
- reactivex/testing/marbles.py +21 -20
- reactivex/testing/mockdisposable.py +1 -3
- reactivex/testing/mockobserver.py +2 -2
- reactivex/testing/reactivetest.py +2 -2
- reactivex/testing/recorded.py +1 -1
- reactivex/testing/subscription.py +3 -3
- reactivex/testing/testscheduler.py +13 -12
- reactivex/typing.py +25 -14
- {reactivex-4.1.0.dist-info → reactivex-5.0.0a2.dist-info}/METADATA +59 -26
- reactivex-5.0.0a2.dist-info/RECORD +236 -0
- {reactivex-4.1.0.dist-info → reactivex-5.0.0a2.dist-info}/WHEEL +1 -1
- reactivex-4.1.0.dist-info/RECORD +0 -223
- {reactivex-4.1.0.dist-info → reactivex-5.0.0a2.dist-info}/licenses/LICENSE +0 -0
reactivex/operators/_do.py
CHANGED
|
@@ -1,86 +1,86 @@
|
|
|
1
|
-
from
|
|
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.disposable import CompositeDisposable
|
|
6
|
+
from reactivex.internal import curry_flip
|
|
5
7
|
|
|
6
8
|
_T = TypeVar("_T")
|
|
7
9
|
|
|
8
10
|
|
|
11
|
+
@curry_flip
|
|
9
12
|
def do_action_(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return Observable(subscribe)
|
|
82
|
-
|
|
83
|
-
return do_action
|
|
13
|
+
source: Observable[_T],
|
|
14
|
+
on_next: typing.OnNext[_T] | None = None,
|
|
15
|
+
on_error: typing.OnError | None = None,
|
|
16
|
+
on_completed: typing.OnCompleted | None = None,
|
|
17
|
+
) -> Observable[_T]:
|
|
18
|
+
"""Invokes an action for each element in the observable
|
|
19
|
+
sequence and invokes an action on graceful or exceptional
|
|
20
|
+
termination of the observable sequence. This method can be used
|
|
21
|
+
for debugging, logging, etc. of query behavior by intercepting
|
|
22
|
+
the message stream to run arbitrary actions for messages on the
|
|
23
|
+
pipeline.
|
|
24
|
+
|
|
25
|
+
Examples:
|
|
26
|
+
>>> res = source.pipe(do_action(send))
|
|
27
|
+
>>> res = source.pipe(do_action(on_next, on_error))
|
|
28
|
+
>>> res = source.pipe(do_action(on_next, on_error, on_completed))
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
source: Source observable.
|
|
32
|
+
on_next: [Optional] Action to invoke for each element in
|
|
33
|
+
the observable sequence.
|
|
34
|
+
on_error: [Optional] Action to invoke on exceptional
|
|
35
|
+
termination of the observable sequence.
|
|
36
|
+
on_completed: [Optional] Action to invoke on graceful
|
|
37
|
+
termination of the observable sequence.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
An observable source sequence with the side-effecting
|
|
41
|
+
behavior applied.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
def subscribe(
|
|
45
|
+
observer: abc.ObserverBase[_T],
|
|
46
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
47
|
+
) -> abc.DisposableBase:
|
|
48
|
+
def _on_next(x: _T) -> None:
|
|
49
|
+
if not on_next:
|
|
50
|
+
observer.on_next(x)
|
|
51
|
+
else:
|
|
52
|
+
try:
|
|
53
|
+
on_next(x)
|
|
54
|
+
except Exception as e: # pylint: disable=broad-except
|
|
55
|
+
observer.on_error(e)
|
|
56
|
+
|
|
57
|
+
observer.on_next(x)
|
|
58
|
+
|
|
59
|
+
def _on_error(exception: Exception) -> None:
|
|
60
|
+
if not on_error:
|
|
61
|
+
observer.on_error(exception)
|
|
62
|
+
else:
|
|
63
|
+
try:
|
|
64
|
+
on_error(exception)
|
|
65
|
+
except Exception as e: # pylint: disable=broad-except
|
|
66
|
+
observer.on_error(e)
|
|
67
|
+
|
|
68
|
+
observer.on_error(exception)
|
|
69
|
+
|
|
70
|
+
def _on_completed() -> None:
|
|
71
|
+
if not on_completed:
|
|
72
|
+
observer.on_completed()
|
|
73
|
+
else:
|
|
74
|
+
try:
|
|
75
|
+
on_completed()
|
|
76
|
+
except Exception as e: # pylint: disable=broad-except
|
|
77
|
+
observer.on_error(e)
|
|
78
|
+
|
|
79
|
+
observer.on_completed()
|
|
80
|
+
|
|
81
|
+
return source.subscribe(_on_next, _on_error, _on_completed, scheduler=scheduler)
|
|
82
|
+
|
|
83
|
+
return Observable(subscribe)
|
|
84
84
|
|
|
85
85
|
|
|
86
86
|
def do_(observer: abc.ObserverBase[_T]) -> Callable[[Observable[_T]], Observable[_T]]:
|
|
@@ -114,7 +114,7 @@ def do_after_next(
|
|
|
114
114
|
"""
|
|
115
115
|
|
|
116
116
|
def subscribe(
|
|
117
|
-
observer: abc.ObserverBase[_T], scheduler:
|
|
117
|
+
observer: abc.ObserverBase[_T], scheduler: abc.SchedulerBase | None = None
|
|
118
118
|
) -> abc.DisposableBase:
|
|
119
119
|
def on_next(value: _T):
|
|
120
120
|
try:
|
|
@@ -139,7 +139,7 @@ def do_on_subscribe(source: Observable[Any], on_subscribe: typing.Action):
|
|
|
139
139
|
"""
|
|
140
140
|
|
|
141
141
|
def subscribe(
|
|
142
|
-
observer: abc.ObserverBase[Any], scheduler:
|
|
142
|
+
observer: abc.ObserverBase[Any], scheduler: abc.SchedulerBase | None = None
|
|
143
143
|
) -> abc.DisposableBase:
|
|
144
144
|
on_subscribe()
|
|
145
145
|
return source.subscribe(
|
|
@@ -167,7 +167,7 @@ def do_on_dispose(source: Observable[Any], on_dispose: typing.Action):
|
|
|
167
167
|
on_dispose()
|
|
168
168
|
|
|
169
169
|
def subscribe(
|
|
170
|
-
observer: abc.ObserverBase[Any], scheduler:
|
|
170
|
+
observer: abc.ObserverBase[Any], scheduler: abc.SchedulerBase | None = None
|
|
171
171
|
) -> abc.DisposableBase:
|
|
172
172
|
composite_disposable = CompositeDisposable()
|
|
173
173
|
composite_disposable.add(OnDispose())
|
|
@@ -193,7 +193,7 @@ def do_on_terminate(source: Observable[Any], on_terminate: typing.Action):
|
|
|
193
193
|
"""
|
|
194
194
|
|
|
195
195
|
def subscribe(
|
|
196
|
-
observer: abc.ObserverBase[Any], scheduler:
|
|
196
|
+
observer: abc.ObserverBase[Any], scheduler: abc.SchedulerBase | None = None
|
|
197
197
|
) -> abc.DisposableBase:
|
|
198
198
|
def on_completed():
|
|
199
199
|
try:
|
|
@@ -228,7 +228,7 @@ def do_after_terminate(source: Observable[Any], after_terminate: typing.Action):
|
|
|
228
228
|
"""
|
|
229
229
|
|
|
230
230
|
def subscribe(
|
|
231
|
-
observer: abc.ObserverBase[Any], scheduler:
|
|
231
|
+
observer: abc.ObserverBase[Any], scheduler: abc.SchedulerBase | None = None
|
|
232
232
|
) -> abc.DisposableBase:
|
|
233
233
|
def on_completed():
|
|
234
234
|
observer.on_completed()
|
|
@@ -251,9 +251,11 @@ def do_after_terminate(source: Observable[Any], after_terminate: typing.Action):
|
|
|
251
251
|
return Observable(subscribe)
|
|
252
252
|
|
|
253
253
|
|
|
254
|
+
@curry_flip
|
|
254
255
|
def do_finally(
|
|
256
|
+
source: Observable[_T],
|
|
255
257
|
finally_action: typing.Action,
|
|
256
|
-
) ->
|
|
258
|
+
) -> Observable[_T]:
|
|
257
259
|
"""Invokes an action after an on_complete(), on_error(), or disposal
|
|
258
260
|
event occurs.
|
|
259
261
|
|
|
@@ -263,13 +265,21 @@ def do_finally(
|
|
|
263
265
|
Note this operator will strive to execute the finally_action once,
|
|
264
266
|
and prevent any redudant calls
|
|
265
267
|
|
|
268
|
+
Examples:
|
|
269
|
+
>>> res = source.pipe(do_finally(lambda: print("done")))
|
|
270
|
+
>>> res = do_finally(lambda: print("done"))(source)
|
|
271
|
+
|
|
266
272
|
Args:
|
|
267
|
-
|
|
268
|
-
|
|
273
|
+
source: Source observable.
|
|
274
|
+
finally_action: Action to invoke after on_complete, on_error,
|
|
275
|
+
or disposal is called
|
|
276
|
+
|
|
277
|
+
Returns:
|
|
278
|
+
An observable sequence with the finally action applied.
|
|
269
279
|
"""
|
|
270
280
|
|
|
271
281
|
class OnDispose(abc.DisposableBase):
|
|
272
|
-
def __init__(self, was_invoked:
|
|
282
|
+
def __init__(self, was_invoked: list[bool]):
|
|
273
283
|
self.was_invoked = was_invoked
|
|
274
284
|
|
|
275
285
|
def dispose(self) -> None:
|
|
@@ -277,43 +287,40 @@ def do_finally(
|
|
|
277
287
|
finally_action()
|
|
278
288
|
self.was_invoked[0] = True
|
|
279
289
|
|
|
280
|
-
def
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
was_invoked = [False]
|
|
286
|
-
|
|
287
|
-
def on_completed():
|
|
288
|
-
observer.on_completed()
|
|
289
|
-
try:
|
|
290
|
-
if not was_invoked[0]:
|
|
291
|
-
finally_action()
|
|
292
|
-
was_invoked[0] = True
|
|
293
|
-
except Exception as err: # pylint: disable=broad-except
|
|
294
|
-
observer.on_error(err)
|
|
290
|
+
def subscribe(
|
|
291
|
+
observer: abc.ObserverBase[_T],
|
|
292
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
293
|
+
) -> abc.DisposableBase:
|
|
294
|
+
was_invoked = [False]
|
|
295
295
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
296
|
+
def on_completed():
|
|
297
|
+
observer.on_completed()
|
|
298
|
+
try:
|
|
299
|
+
if not was_invoked[0]:
|
|
300
|
+
finally_action()
|
|
301
|
+
was_invoked[0] = True
|
|
302
|
+
except Exception as err: # pylint: disable=broad-except
|
|
303
|
+
observer.on_error(err)
|
|
304
304
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
305
|
+
def on_error(exception: Exception):
|
|
306
|
+
observer.on_error(exception)
|
|
307
|
+
try:
|
|
308
|
+
if not was_invoked[0]:
|
|
309
|
+
finally_action()
|
|
310
|
+
was_invoked[0] = True
|
|
311
|
+
except Exception as err: # pylint: disable=broad-except
|
|
312
|
+
observer.on_error(err)
|
|
311
313
|
|
|
312
|
-
|
|
314
|
+
composite_disposable = CompositeDisposable()
|
|
315
|
+
composite_disposable.add(OnDispose(was_invoked))
|
|
316
|
+
subscription = source.subscribe(
|
|
317
|
+
observer.on_next, on_error, on_completed, scheduler=scheduler
|
|
318
|
+
)
|
|
319
|
+
composite_disposable.add(subscription)
|
|
313
320
|
|
|
314
|
-
return
|
|
321
|
+
return composite_disposable
|
|
315
322
|
|
|
316
|
-
return
|
|
323
|
+
return Observable(subscribe)
|
|
317
324
|
|
|
318
325
|
|
|
319
326
|
__all__ = [
|
reactivex/operators/_dowhile.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
from
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from typing import TypeVar
|
|
2
3
|
|
|
3
4
|
from reactivex import Observable
|
|
4
5
|
from reactivex import operators as ops
|
|
@@ -7,7 +8,7 @@ _T = TypeVar("_T")
|
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
def do_while_(
|
|
10
|
-
condition: Callable[[Observable[_T]], bool]
|
|
11
|
+
condition: Callable[[Observable[_T]], bool],
|
|
11
12
|
) -> Callable[[Observable[_T]], Observable[_T]]:
|
|
12
13
|
"""Repeats source as long as condition holds emulating a do while
|
|
13
14
|
loop.
|
|
@@ -1,51 +1,75 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import TypeVar, cast
|
|
2
2
|
|
|
3
3
|
from reactivex import Observable, abc
|
|
4
|
+
from reactivex.internal import curry_flip
|
|
4
5
|
from reactivex.internal.exceptions import ArgumentOutOfRangeException
|
|
5
6
|
|
|
6
7
|
_T = TypeVar("_T")
|
|
7
8
|
|
|
8
9
|
|
|
10
|
+
@curry_flip
|
|
9
11
|
def element_at_or_default_(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
source: Observable[_T],
|
|
13
|
+
index: int,
|
|
14
|
+
has_default: bool = False,
|
|
15
|
+
default_value: _T | None = None,
|
|
16
|
+
) -> Observable[_T]:
|
|
17
|
+
"""Returns the element at a specified index in a sequence or a default value
|
|
18
|
+
if the index is out of range.
|
|
19
|
+
|
|
20
|
+
Examples:
|
|
21
|
+
>>> result = source.pipe(element_at_or_default(5))
|
|
22
|
+
>>> result = element_at_or_default(5)(source)
|
|
23
|
+
>>> result = source.pipe(element_at_or_default(5, True, 0))
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
source: The source observable sequence.
|
|
27
|
+
index: The zero-based index of the element to retrieve.
|
|
28
|
+
has_default: Whether to return a default value if index is out of range.
|
|
29
|
+
default_value: The default value to return if has_default is True.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
An observable sequence that produces the element at the specified
|
|
33
|
+
position in the source sequence, or a default value if the index is
|
|
34
|
+
out of range.
|
|
35
|
+
|
|
36
|
+
Raises:
|
|
37
|
+
ArgumentOutOfRangeException: If index is negative.
|
|
38
|
+
"""
|
|
12
39
|
if index < 0:
|
|
13
40
|
raise ArgumentOutOfRangeException()
|
|
14
41
|
|
|
15
|
-
def
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
index_ -= 1
|
|
28
|
-
else:
|
|
29
|
-
found = True
|
|
30
|
-
|
|
31
|
-
if found:
|
|
32
|
-
observer.on_next(x)
|
|
33
|
-
observer.on_completed()
|
|
34
|
-
|
|
35
|
-
def on_completed():
|
|
36
|
-
if not has_default:
|
|
37
|
-
observer.on_error(ArgumentOutOfRangeException())
|
|
42
|
+
def subscribe(
|
|
43
|
+
observer: abc.ObserverBase[_T],
|
|
44
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
45
|
+
) -> abc.DisposableBase:
|
|
46
|
+
index_ = index
|
|
47
|
+
|
|
48
|
+
def on_next(x: _T) -> None:
|
|
49
|
+
nonlocal index_
|
|
50
|
+
found = False
|
|
51
|
+
with source.lock:
|
|
52
|
+
if index_:
|
|
53
|
+
index_ -= 1
|
|
38
54
|
else:
|
|
39
|
-
|
|
40
|
-
|
|
55
|
+
found = True
|
|
56
|
+
|
|
57
|
+
if found:
|
|
58
|
+
observer.on_next(x)
|
|
59
|
+
observer.on_completed()
|
|
41
60
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
61
|
+
def on_completed():
|
|
62
|
+
if not has_default:
|
|
63
|
+
observer.on_error(ArgumentOutOfRangeException())
|
|
64
|
+
else:
|
|
65
|
+
observer.on_next(cast(_T, default_value))
|
|
66
|
+
observer.on_completed()
|
|
45
67
|
|
|
46
|
-
return
|
|
68
|
+
return source.subscribe(
|
|
69
|
+
on_next, observer.on_error, on_completed, scheduler=scheduler
|
|
70
|
+
)
|
|
47
71
|
|
|
48
|
-
return
|
|
72
|
+
return Observable(subscribe)
|
|
49
73
|
|
|
50
74
|
|
|
51
75
|
__all__ = ["element_at_or_default_"]
|
|
@@ -1,74 +1,80 @@
|
|
|
1
1
|
from asyncio import Future
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import TypeVar, Union
|
|
3
3
|
|
|
4
4
|
import reactivex
|
|
5
5
|
from reactivex import Observable, abc
|
|
6
6
|
from reactivex.disposable import CompositeDisposable, SingleAssignmentDisposable
|
|
7
|
+
from reactivex.internal import curry_flip
|
|
7
8
|
|
|
8
9
|
_T = TypeVar("_T")
|
|
9
10
|
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
@curry_flip
|
|
13
|
+
def exclusive_(source: Observable[Observable[_T]]) -> Observable[_T]:
|
|
12
14
|
"""Performs a exclusive waiting for the first to finish before
|
|
13
15
|
subscribing to another observable. Observables that come in between
|
|
14
16
|
subscriptions will be dropped on the floor.
|
|
15
17
|
|
|
18
|
+
Examples:
|
|
19
|
+
>>> res = source.pipe(exclusive())
|
|
20
|
+
>>> res = exclusive()(source)
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
source: Source observable of observables.
|
|
24
|
+
|
|
16
25
|
Returns:
|
|
17
26
|
An exclusive observable with only the results that
|
|
18
27
|
happen when subscribed.
|
|
19
28
|
"""
|
|
20
29
|
|
|
21
|
-
def
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
inner_source
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return Observable(subscribe)
|
|
70
|
-
|
|
71
|
-
return exclusive
|
|
30
|
+
def subscribe(
|
|
31
|
+
observer: abc.ObserverBase[_T],
|
|
32
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
33
|
+
) -> abc.DisposableBase:
|
|
34
|
+
has_current = [False]
|
|
35
|
+
is_stopped = [False]
|
|
36
|
+
m = SingleAssignmentDisposable()
|
|
37
|
+
g = CompositeDisposable()
|
|
38
|
+
|
|
39
|
+
g.add(m)
|
|
40
|
+
|
|
41
|
+
def on_next(inner_source: Union[Observable[_T], "Future[_T]"]) -> None:
|
|
42
|
+
if not has_current[0]:
|
|
43
|
+
has_current[0] = True
|
|
44
|
+
|
|
45
|
+
inner_source = (
|
|
46
|
+
reactivex.from_future(inner_source)
|
|
47
|
+
if isinstance(inner_source, Future)
|
|
48
|
+
else inner_source
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
inner_subscription = SingleAssignmentDisposable()
|
|
52
|
+
g.add(inner_subscription)
|
|
53
|
+
|
|
54
|
+
def on_completed_inner():
|
|
55
|
+
g.remove(inner_subscription)
|
|
56
|
+
has_current[0] = False
|
|
57
|
+
if is_stopped[0] and len(g) == 1:
|
|
58
|
+
observer.on_completed()
|
|
59
|
+
|
|
60
|
+
inner_subscription.disposable = inner_source.subscribe(
|
|
61
|
+
observer.on_next,
|
|
62
|
+
observer.on_error,
|
|
63
|
+
on_completed_inner,
|
|
64
|
+
scheduler=scheduler,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
def on_completed() -> None:
|
|
68
|
+
is_stopped[0] = True
|
|
69
|
+
if not has_current[0] and len(g) == 1:
|
|
70
|
+
observer.on_completed()
|
|
71
|
+
|
|
72
|
+
m.disposable = source.subscribe(
|
|
73
|
+
on_next, observer.on_error, on_completed, scheduler=scheduler
|
|
74
|
+
)
|
|
75
|
+
return g
|
|
76
|
+
|
|
77
|
+
return Observable(subscribe)
|
|
72
78
|
|
|
73
79
|
|
|
74
80
|
__all__ = ["exclusive_"]
|