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
|
@@ -1,52 +1,55 @@
|
|
|
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
|
|
|
9
|
+
@curry_flip
|
|
8
10
|
def default_if_empty_(
|
|
9
|
-
|
|
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
|
-
|
|
11
|
+
source: Observable[_T],
|
|
12
|
+
default_value: _T | None = None,
|
|
13
|
+
) -> Observable[_T | None]:
|
|
14
|
+
"""Returns the elements of the specified sequence or the
|
|
15
|
+
specified value in a singleton sequence if the sequence is
|
|
16
|
+
empty.
|
|
17
|
+
|
|
18
|
+
Examples:
|
|
19
|
+
>>> obs = source.pipe(default_if_empty())
|
|
20
|
+
>>> obs = default_if_empty()(source)
|
|
21
|
+
>>> obs = source.pipe(default_if_empty(42))
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
source: Source observable.
|
|
25
|
+
default_value: The value to return if the sequence is empty.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
An observable sequence that contains the specified default
|
|
29
|
+
value if the source is empty otherwise, the elements of the
|
|
30
|
+
source.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def subscribe(
|
|
34
|
+
observer: abc.ObserverBase[_T | None],
|
|
35
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
36
|
+
) -> abc.DisposableBase:
|
|
37
|
+
found = [False]
|
|
38
|
+
|
|
39
|
+
def on_next(x: _T):
|
|
40
|
+
found[0] = True
|
|
41
|
+
observer.on_next(x)
|
|
42
|
+
|
|
43
|
+
def on_completed():
|
|
44
|
+
if not found[0]:
|
|
45
|
+
observer.on_next(default_value)
|
|
46
|
+
observer.on_completed()
|
|
47
|
+
|
|
48
|
+
return source.subscribe(
|
|
49
|
+
on_next, observer.on_error, on_completed, scheduler=scheduler
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
return Observable(subscribe)
|
|
50
53
|
|
|
51
54
|
|
|
52
55
|
__all__ = ["default_if_empty_"]
|
reactivex/operators/_delay.py
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
|
-
from typing import Any,
|
|
2
|
+
from typing import Any, TypeVar
|
|
3
3
|
|
|
4
|
-
from reactivex import Notification, Observable, abc
|
|
4
|
+
from reactivex import Notification, Observable, abc, typing
|
|
5
5
|
from reactivex import operators as ops
|
|
6
|
-
from reactivex import typing
|
|
7
6
|
from reactivex.disposable import (
|
|
8
7
|
CompositeDisposable,
|
|
9
8
|
MultipleAssignmentDisposable,
|
|
10
9
|
SerialDisposable,
|
|
11
10
|
)
|
|
11
|
+
from reactivex.internal import curry_flip
|
|
12
12
|
from reactivex.internal.constants import DELTA_ZERO
|
|
13
13
|
from reactivex.notification import OnError
|
|
14
14
|
from reactivex.scheduler import TimeoutScheduler
|
|
@@ -21,10 +21,10 @@ _T = TypeVar("_T")
|
|
|
21
21
|
def observable_delay_timespan(
|
|
22
22
|
source: Observable[_T],
|
|
23
23
|
duetime: typing.RelativeTime,
|
|
24
|
-
scheduler:
|
|
24
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
25
25
|
) -> Observable[_T]:
|
|
26
26
|
def subscribe(
|
|
27
|
-
observer: abc.ObserverBase[_T], scheduler_:
|
|
27
|
+
observer: abc.ObserverBase[_T], scheduler_: abc.SchedulerBase | None = None
|
|
28
28
|
):
|
|
29
29
|
nonlocal duetime
|
|
30
30
|
|
|
@@ -36,10 +36,10 @@ def observable_delay_timespan(
|
|
|
36
36
|
duetime_ = _scheduler.to_timedelta(duetime)
|
|
37
37
|
|
|
38
38
|
cancelable = SerialDisposable()
|
|
39
|
-
exception:
|
|
39
|
+
exception: Exception | None = None
|
|
40
40
|
active = [False]
|
|
41
41
|
running = [False]
|
|
42
|
-
queue:
|
|
42
|
+
queue: list[Timestamp[Notification[_T]]] = []
|
|
43
43
|
|
|
44
44
|
def on_next(notification: Timestamp[Notification[_T]]) -> None:
|
|
45
45
|
nonlocal exception
|
|
@@ -116,26 +116,27 @@ def observable_delay_timespan(
|
|
|
116
116
|
return Observable(subscribe)
|
|
117
117
|
|
|
118
118
|
|
|
119
|
+
@curry_flip
|
|
119
120
|
def delay_(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
A partially applied delay operator function.
|
|
126
|
-
|
|
127
|
-
Examples:
|
|
128
|
-
>>> res = delay(source)
|
|
121
|
+
source: Observable[_T],
|
|
122
|
+
duetime: typing.RelativeTime,
|
|
123
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
124
|
+
) -> Observable[_T]:
|
|
125
|
+
"""Time shifts the observable sequence.
|
|
129
126
|
|
|
130
|
-
|
|
131
|
-
|
|
127
|
+
Examples:
|
|
128
|
+
>>> res = source.pipe(delay(5.0))
|
|
129
|
+
>>> res = delay(5.0)(source)
|
|
132
130
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
131
|
+
Args:
|
|
132
|
+
source: The observable sequence to delay.
|
|
133
|
+
duetime: Time to shift the sequence by.
|
|
134
|
+
scheduler: Scheduler to use for time operations.
|
|
137
135
|
|
|
138
|
-
|
|
136
|
+
Returns:
|
|
137
|
+
A time-shifted observable sequence.
|
|
138
|
+
"""
|
|
139
|
+
return observable_delay_timespan(source, duetime, scheduler)
|
|
139
140
|
|
|
140
141
|
|
|
141
142
|
__all__ = ["delay_"]
|
|
@@ -1,38 +1,40 @@
|
|
|
1
|
-
from typing import Any,
|
|
1
|
+
from typing import Any, TypeVar
|
|
2
2
|
|
|
3
3
|
import reactivex
|
|
4
|
-
from reactivex import Observable, abc
|
|
4
|
+
from reactivex import Observable, abc, typing
|
|
5
5
|
from reactivex import operators as ops
|
|
6
|
-
from reactivex import
|
|
6
|
+
from reactivex.internal import curry_flip
|
|
7
7
|
|
|
8
8
|
_T = TypeVar("_T")
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
@curry_flip
|
|
11
12
|
def delay_subscription_(
|
|
13
|
+
source: Observable[_T],
|
|
12
14
|
duetime: typing.AbsoluteOrRelativeTime,
|
|
13
|
-
scheduler:
|
|
14
|
-
) ->
|
|
15
|
-
|
|
16
|
-
"""Time shifts the observable sequence by delaying the subscription.
|
|
15
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
16
|
+
) -> Observable[_T]:
|
|
17
|
+
"""Time shifts the observable sequence by delaying the subscription.
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
Examples:
|
|
20
|
+
>>> source.pipe(delay_subscription(5))
|
|
21
|
+
>>> delay_subscription(5)(source)
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
Args:
|
|
24
|
+
source: Source subscription to delay.
|
|
25
|
+
duetime: Time to delay subscription.
|
|
26
|
+
scheduler: Scheduler to use for timing.
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
Returns:
|
|
29
|
+
Time-shifted sequence.
|
|
30
|
+
"""
|
|
27
31
|
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
def mapper(_: Any) -> Observable[_T]:
|
|
33
|
+
return reactivex.empty()
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return delay_subscription
|
|
35
|
+
return source.pipe(
|
|
36
|
+
ops.delay_with_mapper(reactivex.timer(duetime, scheduler=scheduler), mapper)
|
|
37
|
+
)
|
|
36
38
|
|
|
37
39
|
|
|
38
40
|
__all__ = ["delay_subscription_"]
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
from
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from typing import Any, TypeVar, cast
|
|
2
3
|
|
|
3
4
|
from reactivex import Observable, abc, typing
|
|
4
5
|
from reactivex.disposable import (
|
|
@@ -11,12 +12,10 @@ _T = TypeVar("_T")
|
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
def delay_with_mapper_(
|
|
14
|
-
subscription_delay:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
] = None,
|
|
19
|
-
delay_duration_mapper: Optional[typing.Mapper[_T, Observable[Any]]] = None,
|
|
15
|
+
subscription_delay: Observable[Any]
|
|
16
|
+
| typing.Mapper[Any, Observable[Any]]
|
|
17
|
+
| None = None,
|
|
18
|
+
delay_duration_mapper: typing.Mapper[_T, Observable[Any]] | None = None,
|
|
20
19
|
) -> Callable[[Observable[_T]], Observable[_T]]:
|
|
21
20
|
def delay_with_mapper(source: Observable[_T]) -> Observable[_T]:
|
|
22
21
|
"""Time shifts the observable sequence based on a subscription
|
|
@@ -35,18 +34,18 @@ def delay_with_mapper_(
|
|
|
35
34
|
Returns:
|
|
36
35
|
Time-shifted observable sequence.
|
|
37
36
|
"""
|
|
38
|
-
sub_delay:
|
|
39
|
-
mapper:
|
|
37
|
+
sub_delay: Observable[Any] | None = None
|
|
38
|
+
mapper: typing.Mapper[Any, Observable[Any]] | None = None
|
|
40
39
|
|
|
41
40
|
if isinstance(subscription_delay, abc.ObservableBase):
|
|
42
41
|
mapper = delay_duration_mapper
|
|
43
|
-
sub_delay = subscription_delay
|
|
42
|
+
sub_delay = cast(Observable[Any], subscription_delay)
|
|
44
43
|
else:
|
|
45
44
|
mapper = subscription_delay
|
|
46
45
|
|
|
47
46
|
def subscribe(
|
|
48
47
|
observer: abc.ObserverBase[_T],
|
|
49
|
-
scheduler:
|
|
48
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
50
49
|
) -> abc.DisposableBase:
|
|
51
50
|
delays = CompositeDisposable()
|
|
52
51
|
at_end = [False]
|
|
@@ -1,36 +1,40 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import TypeVar
|
|
2
2
|
|
|
3
3
|
from reactivex import Notification, Observable, abc
|
|
4
|
+
from reactivex.internal import curry_flip
|
|
4
5
|
|
|
5
6
|
_T = TypeVar("_T")
|
|
6
7
|
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
@curry_flip
|
|
10
|
+
def dematerialize_(source: Observable[Notification[_T]]) -> Observable[_T]:
|
|
11
|
+
"""Dematerializes the explicit notification values of an
|
|
12
|
+
observable sequence as implicit notifications.
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
Examples:
|
|
15
|
+
>>> res = source.pipe(dematerialize())
|
|
16
|
+
>>> res = dematerialize()(source)
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
corresponding to the source sequence's notification values.
|
|
18
|
-
"""
|
|
18
|
+
Args:
|
|
19
|
+
source: Source observable with notifications to dematerialize.
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def on_next(value: Notification[_T]) -> None:
|
|
25
|
-
return value.accept(observer)
|
|
21
|
+
Returns:
|
|
22
|
+
An observable sequence exhibiting the behavior
|
|
23
|
+
corresponding to the source sequence's notification values.
|
|
24
|
+
"""
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
def subscribe(
|
|
27
|
+
observer: abc.ObserverBase[_T],
|
|
28
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
29
|
+
):
|
|
30
|
+
def on_next(value: Notification[_T]) -> None:
|
|
31
|
+
return value.accept(observer)
|
|
30
32
|
|
|
31
|
-
return
|
|
33
|
+
return source.subscribe(
|
|
34
|
+
on_next, observer.on_error, observer.on_completed, scheduler=scheduler
|
|
35
|
+
)
|
|
32
36
|
|
|
33
|
-
return
|
|
37
|
+
return Observable(subscribe)
|
|
34
38
|
|
|
35
39
|
|
|
36
40
|
__all__ = ["dematerialize_"]
|
reactivex/operators/_distinct.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Generic, TypeVar, cast
|
|
2
2
|
|
|
3
3
|
from reactivex import Observable, abc, typing
|
|
4
|
+
from reactivex.internal import curry_flip
|
|
4
5
|
from reactivex.internal.basic import default_comparer
|
|
5
6
|
|
|
6
7
|
_T = TypeVar("_T")
|
|
@@ -8,7 +9,7 @@ _TKey = TypeVar("_TKey")
|
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
def array_index_of_comparer(
|
|
11
|
-
array:
|
|
12
|
+
array: list[_TKey], item: _TKey, comparer: typing.Comparer[_TKey]
|
|
12
13
|
):
|
|
13
14
|
for i, a in enumerate(array):
|
|
14
15
|
if comparer(a, item):
|
|
@@ -19,7 +20,7 @@ def array_index_of_comparer(
|
|
|
19
20
|
class HashSet(Generic[_TKey]):
|
|
20
21
|
def __init__(self, comparer: typing.Comparer[_TKey]):
|
|
21
22
|
self.comparer = comparer
|
|
22
|
-
self.set:
|
|
23
|
+
self.set: list[_TKey] = []
|
|
23
24
|
|
|
24
25
|
def push(self, value: _TKey):
|
|
25
26
|
ret_value = array_index_of_comparer(self.set, value, self.comparer) == -1
|
|
@@ -28,57 +29,60 @@ class HashSet(Generic[_TKey]):
|
|
|
28
29
|
return ret_value
|
|
29
30
|
|
|
30
31
|
|
|
32
|
+
@curry_flip
|
|
31
33
|
def distinct_(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
source: Observable[_T],
|
|
35
|
+
key_mapper: typing.Mapper[_T, _TKey] | None = None,
|
|
36
|
+
comparer: typing.Comparer[_TKey] | None = None,
|
|
37
|
+
) -> Observable[_T]:
|
|
38
|
+
"""Returns an observable sequence that contains only distinct elements.
|
|
39
|
+
|
|
40
|
+
Returns an observable sequence that contains only distinct
|
|
41
|
+
elements according to the key_mapper and the comparer. Usage of
|
|
42
|
+
this operator should be considered carefully due to the
|
|
43
|
+
maintenance of an internal lookup structure which can grow large.
|
|
44
|
+
|
|
45
|
+
Examples:
|
|
46
|
+
>>> result = source.pipe(distinct())
|
|
47
|
+
>>> result = distinct()(source)
|
|
48
|
+
>>> result = source.pipe(distinct(lambda x: x.id))
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
source: Source observable to return distinct items from.
|
|
52
|
+
key_mapper: Optional function to compute a comparison key.
|
|
53
|
+
comparer: Optional equality comparer for computed keys.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
An observable sequence only containing the distinct
|
|
57
|
+
elements, based on a computed key value, from the source
|
|
58
|
+
sequence.
|
|
59
|
+
"""
|
|
35
60
|
comparer_ = comparer or cast(typing.Comparer[_TKey], default_comparer)
|
|
36
61
|
|
|
37
|
-
def
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
large.
|
|
62
|
+
def subscribe(
|
|
63
|
+
observer: abc.ObserverBase[_T],
|
|
64
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
65
|
+
) -> abc.DisposableBase:
|
|
66
|
+
hashset = HashSet(comparer_)
|
|
43
67
|
|
|
44
|
-
|
|
45
|
-
|
|
68
|
+
def on_next(x: _T) -> None:
|
|
69
|
+
key = cast(_TKey, x)
|
|
46
70
|
|
|
47
|
-
|
|
48
|
-
|
|
71
|
+
if key_mapper:
|
|
72
|
+
try:
|
|
73
|
+
key = key_mapper(x)
|
|
74
|
+
except Exception as ex:
|
|
75
|
+
observer.on_error(ex)
|
|
76
|
+
return
|
|
49
77
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
elements, based on a computed key value, from the source
|
|
53
|
-
sequence.
|
|
54
|
-
"""
|
|
78
|
+
if hashset.push(key):
|
|
79
|
+
observer.on_next(x)
|
|
55
80
|
|
|
56
|
-
|
|
57
|
-
observer
|
|
58
|
-
|
|
59
|
-
) -> abc.DisposableBase:
|
|
60
|
-
hashset = HashSet(comparer_)
|
|
81
|
+
return source.subscribe(
|
|
82
|
+
on_next, observer.on_error, observer.on_completed, scheduler=scheduler
|
|
83
|
+
)
|
|
61
84
|
|
|
62
|
-
|
|
63
|
-
key = cast(_TKey, x)
|
|
64
|
-
|
|
65
|
-
if key_mapper:
|
|
66
|
-
try:
|
|
67
|
-
key = key_mapper(x)
|
|
68
|
-
except Exception as ex:
|
|
69
|
-
observer.on_error(ex)
|
|
70
|
-
return
|
|
71
|
-
|
|
72
|
-
if hashset.push(key):
|
|
73
|
-
observer.on_next(x)
|
|
74
|
-
|
|
75
|
-
return source.subscribe(
|
|
76
|
-
on_next, observer.on_error, observer.on_completed, scheduler=scheduler
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
return Observable(subscribe)
|
|
80
|
-
|
|
81
|
-
return distinct
|
|
85
|
+
return Observable(subscribe)
|
|
82
86
|
|
|
83
87
|
|
|
84
88
|
__all__ = ["distinct_"]
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
from
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from typing import TypeVar, cast
|
|
2
3
|
|
|
3
4
|
from reactivex import Observable, abc
|
|
5
|
+
from reactivex.internal import curry_flip
|
|
4
6
|
from reactivex.internal.basic import default_comparer, identity
|
|
5
7
|
from reactivex.typing import Comparer, Mapper
|
|
6
8
|
|
|
@@ -8,73 +10,74 @@ _T = TypeVar("_T")
|
|
|
8
10
|
_TKey = TypeVar("_TKey")
|
|
9
11
|
|
|
10
12
|
|
|
13
|
+
@curry_flip
|
|
11
14
|
def distinct_until_changed_(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
source: Observable[_T],
|
|
16
|
+
key_mapper: Mapper[_T, _TKey] | None = None,
|
|
17
|
+
comparer: Comparer[_TKey] | None = None,
|
|
18
|
+
) -> Observable[_T]:
|
|
19
|
+
"""Returns an observable sequence that contains only distinct
|
|
20
|
+
contiguous elements according to the key_mapper and the
|
|
21
|
+
comparer.
|
|
22
|
+
|
|
23
|
+
Examples:
|
|
24
|
+
>>> res = source.pipe(distinct_until_changed())
|
|
25
|
+
>>> res = distinct_until_changed()(source)
|
|
26
|
+
>>> res = source.pipe(distinct_until_changed(lambda x: x.id))
|
|
27
|
+
>>> res = source.pipe(
|
|
28
|
+
... distinct_until_changed(lambda x: x.id, lambda x, y: x == y)
|
|
29
|
+
... )
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
source: The source observable sequence.
|
|
33
|
+
key_mapper: [Optional] A function to compute the comparison
|
|
34
|
+
key for each element. If not provided, it projects the
|
|
35
|
+
value.
|
|
36
|
+
comparer: [Optional] Equality comparer for computed key
|
|
37
|
+
values. If not provided, defaults to an equality
|
|
38
|
+
comparer function.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
An observable sequence only containing the distinct
|
|
42
|
+
contiguous elements, based on a computed key value, from
|
|
43
|
+
the source sequence.
|
|
44
|
+
"""
|
|
16
45
|
key_mapper_ = key_mapper or cast(Callable[[_T], _TKey], identity)
|
|
17
46
|
comparer_ = comparer or default_comparer
|
|
18
47
|
|
|
19
|
-
def
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
Returns:
|
|
38
|
-
An observable sequence only containing the distinct
|
|
39
|
-
contiguous elements, based on a computed key value, from
|
|
40
|
-
the source sequence.
|
|
41
|
-
"""
|
|
42
|
-
|
|
43
|
-
def subscribe(
|
|
44
|
-
observer: abc.ObserverBase[_T],
|
|
45
|
-
scheduler: Optional[abc.SchedulerBase] = None,
|
|
46
|
-
) -> abc.DisposableBase:
|
|
47
|
-
has_current_key = False
|
|
48
|
-
current_key: _TKey = cast(_TKey, None)
|
|
49
|
-
|
|
50
|
-
def on_next(value: _T) -> None:
|
|
51
|
-
nonlocal has_current_key, current_key
|
|
52
|
-
comparer_equals = False
|
|
48
|
+
def subscribe(
|
|
49
|
+
observer: abc.ObserverBase[_T],
|
|
50
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
51
|
+
) -> abc.DisposableBase:
|
|
52
|
+
has_current_key = False
|
|
53
|
+
current_key: _TKey = cast(_TKey, None)
|
|
54
|
+
|
|
55
|
+
def on_next(value: _T) -> None:
|
|
56
|
+
nonlocal has_current_key, current_key
|
|
57
|
+
comparer_equals = False
|
|
58
|
+
try:
|
|
59
|
+
key = key_mapper_(value)
|
|
60
|
+
except Exception as exception: # pylint: disable=broad-except
|
|
61
|
+
observer.on_error(exception)
|
|
62
|
+
return
|
|
63
|
+
|
|
64
|
+
if has_current_key:
|
|
53
65
|
try:
|
|
54
|
-
|
|
66
|
+
comparer_equals = comparer_(current_key, key)
|
|
55
67
|
except Exception as exception: # pylint: disable=broad-except
|
|
56
68
|
observer.on_error(exception)
|
|
57
69
|
return
|
|
58
70
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
observer.on_error(exception)
|
|
64
|
-
return
|
|
65
|
-
|
|
66
|
-
if not has_current_key or not comparer_equals:
|
|
67
|
-
has_current_key = True
|
|
68
|
-
current_key = key
|
|
69
|
-
observer.on_next(value)
|
|
70
|
-
|
|
71
|
-
return source.subscribe(
|
|
72
|
-
on_next, observer.on_error, observer.on_completed, scheduler=scheduler
|
|
73
|
-
)
|
|
71
|
+
if not has_current_key or not comparer_equals:
|
|
72
|
+
has_current_key = True
|
|
73
|
+
current_key = key
|
|
74
|
+
observer.on_next(value)
|
|
74
75
|
|
|
75
|
-
return
|
|
76
|
+
return source.subscribe(
|
|
77
|
+
on_next, observer.on_error, observer.on_completed, scheduler=scheduler
|
|
78
|
+
)
|
|
76
79
|
|
|
77
|
-
return
|
|
80
|
+
return Observable(subscribe)
|
|
78
81
|
|
|
79
82
|
|
|
80
83
|
__all__ = ["distinct_until_changed_"]
|