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/_some.py
CHANGED
|
@@ -1,59 +1,60 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import TypeVar
|
|
2
2
|
|
|
3
3
|
from reactivex import Observable, abc
|
|
4
4
|
from reactivex import operators as ops
|
|
5
|
+
from reactivex.internal import curry_flip
|
|
5
6
|
from reactivex.typing import Predicate
|
|
6
7
|
|
|
7
8
|
_T = TypeVar("_T")
|
|
8
9
|
|
|
9
10
|
|
|
11
|
+
@curry_flip
|
|
10
12
|
def some_(
|
|
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
|
-
return some
|
|
13
|
+
source: Observable[_T],
|
|
14
|
+
predicate: Predicate[_T] | None = None,
|
|
15
|
+
) -> Observable[bool]:
|
|
16
|
+
"""Determines whether some element of an observable sequence satisfies a
|
|
17
|
+
condition if present, else if some items are in the sequence.
|
|
18
|
+
|
|
19
|
+
Examples:
|
|
20
|
+
>>> res = source.pipe(some())
|
|
21
|
+
>>> res = some()(source)
|
|
22
|
+
>>> res = source.pipe(some(lambda x: x > 3))
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
source: The source observable sequence.
|
|
26
|
+
predicate: A function to test each element for a condition.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
An observable sequence containing a single element
|
|
30
|
+
determining whether some elements in the source sequence
|
|
31
|
+
pass the test in the specified predicate if given, else if
|
|
32
|
+
some items are in the sequence.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def subscribe(
|
|
36
|
+
observer: abc.ObserverBase[bool],
|
|
37
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
38
|
+
):
|
|
39
|
+
def on_next(_: _T):
|
|
40
|
+
observer.on_next(True)
|
|
41
|
+
observer.on_completed()
|
|
42
|
+
|
|
43
|
+
def on_error():
|
|
44
|
+
observer.on_next(False)
|
|
45
|
+
observer.on_completed()
|
|
46
|
+
|
|
47
|
+
return source.subscribe(
|
|
48
|
+
on_next, observer.on_error, on_error, scheduler=scheduler
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
if predicate:
|
|
52
|
+
return source.pipe(
|
|
53
|
+
ops.filter(predicate),
|
|
54
|
+
ops.some(),
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
return Observable(subscribe)
|
|
57
58
|
|
|
58
59
|
|
|
59
60
|
__all__ = ["some_"]
|
|
@@ -1,28 +1,30 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import TypeVar
|
|
2
2
|
|
|
3
3
|
import reactivex
|
|
4
4
|
from reactivex import Observable
|
|
5
|
+
from reactivex.internal import curry_flip
|
|
5
6
|
|
|
6
7
|
_T = TypeVar("_T")
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
@curry_flip
|
|
11
|
+
def start_with_(source: Observable[_T], *args: _T) -> Observable[_T]:
|
|
12
|
+
"""Prepends a sequence of values to an observable sequence.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
Example:
|
|
15
|
+
>>> result = source.pipe(start_with(1, 2, 3))
|
|
16
|
+
>>> result = start_with(1, 2, 3)(source)
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
Args:
|
|
19
|
+
source: The source observable sequence.
|
|
20
|
+
args: Values to prepend to the source sequence.
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return start_with
|
|
22
|
+
Returns:
|
|
23
|
+
The source sequence prepended with the specified values.
|
|
24
|
+
"""
|
|
25
|
+
start = reactivex.from_iterable(args)
|
|
26
|
+
sequence = [start, source]
|
|
27
|
+
return reactivex.concat(*sequence)
|
|
26
28
|
|
|
27
29
|
|
|
28
30
|
__all__ = ["start_with_"]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any,
|
|
1
|
+
from typing import Any, TypeVar
|
|
2
2
|
|
|
3
3
|
from reactivex import Observable, abc
|
|
4
4
|
from reactivex.disposable import (
|
|
@@ -6,52 +6,55 @@ from reactivex.disposable import (
|
|
|
6
6
|
SerialDisposable,
|
|
7
7
|
SingleAssignmentDisposable,
|
|
8
8
|
)
|
|
9
|
+
from reactivex.internal import curry_flip
|
|
9
10
|
|
|
10
11
|
_T = TypeVar("_T")
|
|
11
12
|
|
|
12
13
|
|
|
14
|
+
@curry_flip
|
|
13
15
|
def subscribe_on_(
|
|
16
|
+
source: Observable[_T],
|
|
14
17
|
scheduler: abc.SchedulerBase,
|
|
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
|
-
return
|
|
53
|
-
|
|
54
|
-
return
|
|
18
|
+
) -> Observable[_T]:
|
|
19
|
+
"""Subscribe on the specified scheduler.
|
|
20
|
+
|
|
21
|
+
Wrap the source sequence in order to run its subscription and
|
|
22
|
+
unsubscription logic on the specified scheduler. This operation
|
|
23
|
+
is not commonly used; see the remarks section for more
|
|
24
|
+
information on the distinction between subscribe_on and
|
|
25
|
+
observe_on.
|
|
26
|
+
|
|
27
|
+
This only performs the side-effects of subscription and
|
|
28
|
+
unsubscription on the specified scheduler. In order to invoke
|
|
29
|
+
observer callbacks on a scheduler, use observe_on.
|
|
30
|
+
|
|
31
|
+
Examples:
|
|
32
|
+
>>> res = source.pipe(subscribe_on(scheduler))
|
|
33
|
+
>>> res = subscribe_on(scheduler)(source)
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
source: The source observable.
|
|
37
|
+
scheduler: Scheduler to use for subscription/unsubscription.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
The source sequence whose subscriptions and
|
|
41
|
+
un-subscriptions happen on the specified scheduler.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
def subscribe(observer: abc.ObserverBase[_T], _: abc.SchedulerBase | None = None):
|
|
45
|
+
m = SingleAssignmentDisposable()
|
|
46
|
+
d = SerialDisposable()
|
|
47
|
+
d.disposable = m
|
|
48
|
+
|
|
49
|
+
def action(scheduler: abc.SchedulerBase, state: Any | None = None):
|
|
50
|
+
d.disposable = ScheduledDisposable(
|
|
51
|
+
scheduler, source.subscribe(observer, scheduler=scheduler)
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
m.disposable = scheduler.schedule(action)
|
|
55
|
+
return d
|
|
56
|
+
|
|
57
|
+
return Observable(subscribe)
|
|
55
58
|
|
|
56
59
|
|
|
57
60
|
__all__ = ["subscribe_on_"]
|
reactivex/operators/_sum.py
CHANGED
|
@@ -1,20 +1,37 @@
|
|
|
1
|
-
from typing import Any
|
|
1
|
+
from typing import Any
|
|
2
2
|
|
|
3
|
-
from reactivex import Observable
|
|
3
|
+
from reactivex import Observable
|
|
4
4
|
from reactivex import operators as ops
|
|
5
|
+
from reactivex.internal import curry_flip
|
|
5
6
|
from reactivex.typing import Mapper
|
|
6
7
|
|
|
7
8
|
|
|
9
|
+
@curry_flip
|
|
8
10
|
def sum_(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
source: Observable[Any],
|
|
12
|
+
key_mapper: Mapper[Any, float] | None = None,
|
|
13
|
+
) -> Observable[float]:
|
|
14
|
+
"""Computes the sum of a sequence of values.
|
|
15
|
+
|
|
16
|
+
Examples:
|
|
17
|
+
>>> result = source.pipe(sum())
|
|
18
|
+
>>> result = sum()(source)
|
|
19
|
+
>>> result = source.pipe(sum(lambda x: x.value))
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
source: The source observable.
|
|
23
|
+
key_mapper: Optional mapper to extract numeric values.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
An observable sequence containing a single element with the sum.
|
|
27
|
+
"""
|
|
11
28
|
if key_mapper:
|
|
12
|
-
return
|
|
29
|
+
return source.pipe(ops.map(key_mapper), ops.sum())
|
|
13
30
|
|
|
14
31
|
def accumulator(prev: float, cur: float) -> float:
|
|
15
32
|
return prev + cur
|
|
16
33
|
|
|
17
|
-
return ops.reduce(seed=0, accumulator=accumulator)
|
|
34
|
+
return source.pipe(ops.reduce(seed=0, accumulator=accumulator))
|
|
18
35
|
|
|
19
36
|
|
|
20
37
|
__all__ = ["sum_"]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from asyncio import Future
|
|
2
|
-
from typing import Any,
|
|
2
|
+
from typing import Any, TypeVar, Union
|
|
3
3
|
|
|
4
4
|
from reactivex import Observable, abc, from_future
|
|
5
5
|
from reactivex.disposable import (
|
|
@@ -7,84 +7,86 @@ from reactivex.disposable import (
|
|
|
7
7
|
SerialDisposable,
|
|
8
8
|
SingleAssignmentDisposable,
|
|
9
9
|
)
|
|
10
|
+
from reactivex.internal import curry_flip
|
|
10
11
|
|
|
11
12
|
_T = TypeVar("_T")
|
|
12
13
|
|
|
13
14
|
|
|
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
|
-
has_latest[0] = False
|
|
68
|
-
if is_stopped[0]:
|
|
69
|
-
observer.on_completed()
|
|
70
|
-
|
|
71
|
-
d.disposable = obs.subscribe(
|
|
72
|
-
on_next, on_error, on_completed, scheduler=scheduler
|
|
73
|
-
)
|
|
15
|
+
@curry_flip
|
|
16
|
+
def switch_latest_(
|
|
17
|
+
source: Observable[Union[Observable[_T], "Future[_T]"]],
|
|
18
|
+
) -> Observable[_T]:
|
|
19
|
+
"""Transforms an observable sequence of observable sequences into
|
|
20
|
+
an observable sequence producing values only from the most
|
|
21
|
+
recent observable sequence.
|
|
22
|
+
|
|
23
|
+
Examples:
|
|
24
|
+
>>> res = source.pipe(switch_latest())
|
|
25
|
+
>>> res = switch_latest()(source)
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
source: Source observable of observables.
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
An observable sequence that at any point in time produces
|
|
32
|
+
the elements of the most recent inner observable sequence
|
|
33
|
+
that has been received.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def subscribe(
|
|
37
|
+
observer: abc.ObserverBase[_T],
|
|
38
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
39
|
+
) -> abc.DisposableBase:
|
|
40
|
+
inner_subscription = SerialDisposable()
|
|
41
|
+
has_latest = [False]
|
|
42
|
+
is_stopped = [False]
|
|
43
|
+
latest = [0]
|
|
44
|
+
|
|
45
|
+
def on_next(inner_source: Union[Observable[_T], "Future[_T]"]) -> None:
|
|
46
|
+
nonlocal source
|
|
47
|
+
|
|
48
|
+
d = SingleAssignmentDisposable()
|
|
49
|
+
with source.lock:
|
|
50
|
+
latest[0] += 1
|
|
51
|
+
_id = latest[0]
|
|
52
|
+
has_latest[0] = True
|
|
53
|
+
inner_subscription.disposable = d
|
|
54
|
+
|
|
55
|
+
# Check if Future or Observable
|
|
56
|
+
if isinstance(inner_source, Future):
|
|
57
|
+
obs = from_future(inner_source)
|
|
58
|
+
else:
|
|
59
|
+
obs = inner_source
|
|
60
|
+
|
|
61
|
+
def on_next(x: Any) -> None:
|
|
62
|
+
if latest[0] == _id:
|
|
63
|
+
observer.on_next(x)
|
|
64
|
+
|
|
65
|
+
def on_error(e: Exception) -> None:
|
|
66
|
+
if latest[0] == _id:
|
|
67
|
+
observer.on_error(e)
|
|
74
68
|
|
|
75
69
|
def on_completed() -> None:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
70
|
+
if latest[0] == _id:
|
|
71
|
+
has_latest[0] = False
|
|
72
|
+
if is_stopped[0]:
|
|
73
|
+
observer.on_completed()
|
|
79
74
|
|
|
80
|
-
|
|
81
|
-
on_next,
|
|
75
|
+
d.disposable = obs.subscribe(
|
|
76
|
+
on_next, on_error, on_completed, scheduler=scheduler
|
|
82
77
|
)
|
|
83
|
-
return CompositeDisposable(subscription, inner_subscription)
|
|
84
78
|
|
|
85
|
-
|
|
79
|
+
def on_completed() -> None:
|
|
80
|
+
is_stopped[0] = True
|
|
81
|
+
if not has_latest[0]:
|
|
82
|
+
observer.on_completed()
|
|
86
83
|
|
|
87
|
-
|
|
84
|
+
subscription = source.subscribe(
|
|
85
|
+
on_next, observer.on_error, on_completed, scheduler=scheduler
|
|
86
|
+
)
|
|
87
|
+
return CompositeDisposable(subscription, inner_subscription)
|
|
88
|
+
|
|
89
|
+
return Observable(subscribe)
|
|
88
90
|
|
|
89
91
|
|
|
90
92
|
__all__ = ["switch_latest_"]
|
reactivex/operators/_take.py
CHANGED
|
@@ -1,53 +1,57 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import TypeVar
|
|
2
2
|
|
|
3
3
|
from reactivex import Observable, abc, empty
|
|
4
|
-
from reactivex.internal import ArgumentOutOfRangeException
|
|
4
|
+
from reactivex.internal import ArgumentOutOfRangeException, curry_flip
|
|
5
5
|
|
|
6
6
|
_T = TypeVar("_T")
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def take(source: Observable[_T]) -> Observable[_T]:
|
|
14
|
-
"""Returns a specified number of contiguous elements from the start of
|
|
15
|
-
an observable sequence.
|
|
9
|
+
@curry_flip
|
|
10
|
+
def take_(source: Observable[_T], count: int) -> Observable[_T]:
|
|
11
|
+
"""Returns a specified number of contiguous elements from the start of
|
|
12
|
+
an observable sequence.
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
Example:
|
|
15
|
+
>>> result = source.pipe(take(5))
|
|
16
|
+
>>> result = take(5)(source)
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
Args:
|
|
19
|
+
source: The source observable sequence.
|
|
20
|
+
count: The number of elements to return.
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
Returns:
|
|
23
|
+
An observable sequence that contains the specified number of
|
|
23
24
|
elements from the start of the input sequence.
|
|
24
|
-
"""
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
Raises:
|
|
27
|
+
ArgumentOutOfRangeException: If count is negative.
|
|
28
|
+
"""
|
|
29
|
+
if count < 0:
|
|
30
|
+
raise ArgumentOutOfRangeException()
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
scheduler: Optional[abc.SchedulerBase] = None,
|
|
32
|
-
):
|
|
33
|
-
remaining = count
|
|
32
|
+
if not count:
|
|
33
|
+
return empty()
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
def subscribe(
|
|
36
|
+
observer: abc.ObserverBase[_T],
|
|
37
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
38
|
+
):
|
|
39
|
+
remaining = count
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
observer.on_next(value)
|
|
41
|
-
if not remaining:
|
|
42
|
-
observer.on_completed()
|
|
41
|
+
def on_next(value: _T) -> None:
|
|
42
|
+
nonlocal remaining
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
if remaining > 0:
|
|
45
|
+
remaining -= 1
|
|
46
|
+
observer.on_next(value)
|
|
47
|
+
if not remaining:
|
|
48
|
+
observer.on_completed()
|
|
47
49
|
|
|
48
|
-
return
|
|
50
|
+
return source.subscribe(
|
|
51
|
+
on_next, observer.on_error, observer.on_completed, scheduler=scheduler
|
|
52
|
+
)
|
|
49
53
|
|
|
50
|
-
return
|
|
54
|
+
return Observable(subscribe)
|
|
51
55
|
|
|
52
56
|
|
|
53
57
|
__all__ = ["take_"]
|
reactivex/operators/_takelast.py
CHANGED
|
@@ -1,55 +1,56 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import TypeVar
|
|
2
2
|
|
|
3
3
|
from reactivex import Observable, abc
|
|
4
|
+
from reactivex.internal import curry_flip
|
|
4
5
|
|
|
5
6
|
_T = TypeVar("_T")
|
|
6
7
|
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
@curry_flip
|
|
10
|
+
def take_last_(source: Observable[_T], count: int) -> Observable[_T]:
|
|
11
|
+
"""Returns a specified number of contiguous elements from the end of an
|
|
12
|
+
observable sequence.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
Examples:
|
|
15
|
+
>>> res = source.pipe(take_last(5))
|
|
16
|
+
>>> res = take_last(5)(source)
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
This operator accumulates a buffer with a length enough to store
|
|
19
|
+
elements count elements. Upon completion of the source sequence, this
|
|
20
|
+
buffer is drained on the result sequence. This causes the elements to be
|
|
21
|
+
delayed.
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
Args:
|
|
24
|
+
source: The source observable sequence.
|
|
25
|
+
count: Number of elements to take from the end of the source
|
|
23
26
|
sequence.
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
Returns:
|
|
29
|
+
An observable sequence containing the specified number of elements
|
|
30
|
+
from the end of the source sequence.
|
|
31
|
+
"""
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
def subscribe(
|
|
34
|
+
observer: abc.ObserverBase[_T],
|
|
35
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
36
|
+
) -> abc.DisposableBase:
|
|
37
|
+
q: list[_T] = []
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
def on_next(x: _T) -> None:
|
|
40
|
+
q.append(x)
|
|
41
|
+
if len(q) > count:
|
|
42
|
+
q.pop(0)
|
|
40
43
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
def on_completed():
|
|
45
|
+
while q:
|
|
46
|
+
observer.on_next(q.pop(0))
|
|
47
|
+
observer.on_completed()
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
return source.subscribe(
|
|
50
|
+
on_next, observer.on_error, on_completed, scheduler=scheduler
|
|
51
|
+
)
|
|
49
52
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return take_last
|
|
53
|
+
return Observable(subscribe)
|
|
53
54
|
|
|
54
55
|
|
|
55
56
|
__all__ = ["take_last_"]
|