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/_expand.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any,
|
|
1
|
+
from typing import Any, TypeVar
|
|
2
2
|
|
|
3
3
|
from reactivex import Observable, abc, typing
|
|
4
4
|
from reactivex.disposable import (
|
|
@@ -6,97 +6,102 @@ from reactivex.disposable import (
|
|
|
6
6
|
SerialDisposable,
|
|
7
7
|
SingleAssignmentDisposable,
|
|
8
8
|
)
|
|
9
|
+
from reactivex.internal import curry_flip
|
|
9
10
|
from reactivex.scheduler import ImmediateScheduler
|
|
10
11
|
|
|
11
12
|
_T = TypeVar("_T")
|
|
12
13
|
|
|
13
14
|
|
|
15
|
+
@curry_flip
|
|
14
16
|
def expand_(
|
|
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
|
-
|
|
17
|
+
source: Observable[_T],
|
|
18
|
+
mapper: typing.Mapper[_T, Observable[_T]],
|
|
19
|
+
) -> Observable[_T]:
|
|
20
|
+
"""Expands an observable sequence by recursively invoking
|
|
21
|
+
mapper.
|
|
22
|
+
|
|
23
|
+
Examples:
|
|
24
|
+
>>> source.pipe(expand(lambda x: of(x * 2)))
|
|
25
|
+
>>> expand(lambda x: of(x * 2))(source)
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
source: Source observable to expand.
|
|
29
|
+
mapper: Function to recursively map elements.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
An observable sequence containing all the elements produced
|
|
33
|
+
by the recursive expansion.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def subscribe(
|
|
37
|
+
observer: abc.ObserverBase[_T],
|
|
38
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
39
|
+
) -> abc.DisposableBase:
|
|
40
|
+
scheduler = scheduler or ImmediateScheduler.singleton()
|
|
41
|
+
|
|
42
|
+
queue: list[Observable[_T]] = []
|
|
43
|
+
m = SerialDisposable()
|
|
44
|
+
d = CompositeDisposable(m)
|
|
45
|
+
active_count = 0
|
|
46
|
+
is_acquired = False
|
|
47
|
+
|
|
48
|
+
def ensure_active():
|
|
49
|
+
nonlocal is_acquired
|
|
50
|
+
|
|
51
|
+
is_owner = False
|
|
52
|
+
if queue:
|
|
53
|
+
is_owner = not is_acquired
|
|
54
|
+
is_acquired = True
|
|
55
|
+
|
|
56
|
+
def action(scheduler: abc.SchedulerBase, state: Any = None):
|
|
57
|
+
nonlocal is_acquired, active_count
|
|
51
58
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
if queue:
|
|
60
|
+
work = queue.pop(0)
|
|
61
|
+
else:
|
|
62
|
+
is_acquired = False
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
sad = SingleAssignmentDisposable()
|
|
66
|
+
d.add(sad)
|
|
67
|
+
|
|
68
|
+
def on_next(value: _T) -> None:
|
|
69
|
+
nonlocal active_count
|
|
70
|
+
|
|
71
|
+
observer.on_next(value)
|
|
72
|
+
result = None
|
|
73
|
+
try:
|
|
74
|
+
result = mapper(value)
|
|
75
|
+
except Exception as ex:
|
|
76
|
+
observer.on_error(ex)
|
|
56
77
|
return
|
|
57
78
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def on_next(value: _T) -> None:
|
|
62
|
-
nonlocal active_count
|
|
63
|
-
|
|
64
|
-
observer.on_next(value)
|
|
65
|
-
result = None
|
|
66
|
-
try:
|
|
67
|
-
result = mapper(value)
|
|
68
|
-
except Exception as ex:
|
|
69
|
-
observer.on_error(ex)
|
|
70
|
-
return
|
|
71
|
-
|
|
72
|
-
queue.append(result)
|
|
73
|
-
active_count += 1
|
|
74
|
-
ensure_active()
|
|
75
|
-
|
|
76
|
-
def on_complete() -> None:
|
|
77
|
-
nonlocal active_count
|
|
79
|
+
queue.append(result)
|
|
80
|
+
active_count += 1
|
|
81
|
+
ensure_active()
|
|
78
82
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if active_count == 0:
|
|
82
|
-
observer.on_completed()
|
|
83
|
+
def on_complete() -> None:
|
|
84
|
+
nonlocal active_count
|
|
83
85
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
d.remove(sad)
|
|
87
|
+
active_count -= 1
|
|
88
|
+
if active_count == 0:
|
|
89
|
+
observer.on_completed()
|
|
88
90
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
+
sad.disposable = work.subscribe(
|
|
92
|
+
on_next, observer.on_error, on_complete, scheduler=scheduler
|
|
93
|
+
)
|
|
94
|
+
m.disposable = scheduler.schedule(action)
|
|
91
95
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
ensure_active()
|
|
95
|
-
return d
|
|
96
|
+
if is_owner:
|
|
97
|
+
m.disposable = scheduler.schedule(action)
|
|
96
98
|
|
|
97
|
-
|
|
99
|
+
queue.append(source)
|
|
100
|
+
active_count += 1
|
|
101
|
+
ensure_active()
|
|
102
|
+
return d
|
|
98
103
|
|
|
99
|
-
return
|
|
104
|
+
return Observable(subscribe)
|
|
100
105
|
|
|
101
106
|
|
|
102
107
|
__all__ = ["expand_"]
|
reactivex/operators/_filter.py
CHANGED
|
@@ -1,98 +1,93 @@
|
|
|
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
|
from reactivex.typing import Predicate, PredicateIndexed
|
|
5
6
|
|
|
6
7
|
_T = TypeVar("_T")
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
# pylint: disable=redefined-builtin
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
@curry_flip
|
|
12
|
+
def filter_(source: Observable[_T], predicate: Predicate[_T]) -> Observable[_T]:
|
|
13
|
+
"""Filters the elements of an observable sequence based on a predicate.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
Example:
|
|
16
|
+
>>> result = source.pipe(filter(lambda x: x > 5))
|
|
17
|
+
>>> result = filter(lambda x: x > 5)(source)
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
Args:
|
|
20
|
+
source: Source observable to filter.
|
|
21
|
+
predicate: A function to test each element for a condition.
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
Returns:
|
|
24
|
+
A filtered observable sequence.
|
|
25
|
+
"""
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
def subscribe(
|
|
28
|
+
observer: abc.ObserverBase[_T], scheduler: abc.SchedulerBase | None
|
|
29
|
+
) -> abc.DisposableBase:
|
|
30
|
+
def on_next(value: _T):
|
|
31
|
+
try:
|
|
32
|
+
should_run = predicate(value)
|
|
33
|
+
except Exception as ex: # pylint: disable=broad-except
|
|
34
|
+
observer.on_error(ex)
|
|
35
|
+
return
|
|
26
36
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
) -> abc.DisposableBase:
|
|
30
|
-
def on_next(value: _T):
|
|
31
|
-
try:
|
|
32
|
-
should_run = predicate(value)
|
|
33
|
-
except Exception as ex: # pylint: disable=broad-except
|
|
34
|
-
observer.on_error(ex)
|
|
35
|
-
return
|
|
36
|
-
|
|
37
|
-
if should_run:
|
|
38
|
-
observer.on_next(value)
|
|
39
|
-
|
|
40
|
-
return source.subscribe(
|
|
41
|
-
on_next, observer.on_error, observer.on_completed, scheduler=scheduler
|
|
42
|
-
)
|
|
37
|
+
if should_run:
|
|
38
|
+
observer.on_next(value)
|
|
43
39
|
|
|
44
|
-
return
|
|
40
|
+
return source.subscribe(
|
|
41
|
+
on_next, observer.on_error, observer.on_completed, scheduler=scheduler
|
|
42
|
+
)
|
|
45
43
|
|
|
46
|
-
return
|
|
44
|
+
return Observable(subscribe)
|
|
47
45
|
|
|
48
46
|
|
|
47
|
+
@curry_flip
|
|
49
48
|
def filter_indexed_(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
source: Observable[_T],
|
|
50
|
+
predicate_indexed: PredicateIndexed[_T] | None = None,
|
|
51
|
+
) -> Observable[_T]:
|
|
52
|
+
"""Filters the elements of an observable sequence based on a predicate
|
|
53
|
+
by incorporating the element's index.
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
Example:
|
|
56
|
+
>>> result = source.pipe(filter_indexed(lambda x, i: i % 2 == 0))
|
|
57
|
+
>>> result = filter_indexed(lambda x, i: i % 2 == 0)(source)
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
Args:
|
|
60
|
+
source: Source observable to filter.
|
|
61
|
+
predicate_indexed: A function to test each element with its index.
|
|
60
62
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
Returns:
|
|
64
|
+
A filtered observable sequence.
|
|
65
|
+
"""
|
|
63
66
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
"""
|
|
67
|
+
def subscribe(observer: abc.ObserverBase[_T], scheduler: abc.SchedulerBase | None):
|
|
68
|
+
count = 0
|
|
67
69
|
|
|
68
|
-
def
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
count = 0
|
|
70
|
+
def on_next(value: _T):
|
|
71
|
+
nonlocal count
|
|
72
|
+
should_run = True
|
|
72
73
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
observer.on_error(ex)
|
|
82
|
-
return
|
|
83
|
-
else:
|
|
84
|
-
count += 1
|
|
85
|
-
|
|
86
|
-
if should_run:
|
|
87
|
-
observer.on_next(value)
|
|
74
|
+
if predicate_indexed:
|
|
75
|
+
try:
|
|
76
|
+
should_run = predicate_indexed(value, count)
|
|
77
|
+
except Exception as ex: # pylint: disable=broad-except
|
|
78
|
+
observer.on_error(ex)
|
|
79
|
+
return
|
|
80
|
+
else:
|
|
81
|
+
count += 1
|
|
88
82
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
)
|
|
83
|
+
if should_run:
|
|
84
|
+
observer.on_next(value)
|
|
92
85
|
|
|
93
|
-
return
|
|
86
|
+
return source.subscribe(
|
|
87
|
+
on_next, observer.on_error, observer.on_completed, scheduler=scheduler
|
|
88
|
+
)
|
|
94
89
|
|
|
95
|
-
return
|
|
90
|
+
return Observable(subscribe)
|
|
96
91
|
|
|
97
92
|
|
|
98
93
|
__all__ = ["filter_", "filter_indexed_"]
|
|
@@ -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, abc, typing
|
|
4
5
|
from reactivex.disposable import Disposable
|
|
@@ -26,7 +27,7 @@ def finally_action_(
|
|
|
26
27
|
|
|
27
28
|
def subscribe(
|
|
28
29
|
observer: abc.ObserverBase[_T],
|
|
29
|
-
scheduler:
|
|
30
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
30
31
|
) -> abc.DisposableBase:
|
|
31
32
|
try:
|
|
32
33
|
subscription = source.subscribe(observer, scheduler=scheduler)
|
reactivex/operators/_find.py
CHANGED
|
@@ -1,46 +1,63 @@
|
|
|
1
|
-
from
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from typing import TypeVar
|
|
2
3
|
|
|
3
4
|
from reactivex import Observable, abc
|
|
5
|
+
from reactivex.internal import curry_flip
|
|
4
6
|
|
|
5
7
|
_T = TypeVar("_T")
|
|
6
8
|
|
|
7
9
|
|
|
10
|
+
@curry_flip
|
|
8
11
|
def find_value_(
|
|
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
|
-
|
|
12
|
+
source: Observable[_T],
|
|
13
|
+
predicate: Callable[[_T, int, Observable[_T]], bool],
|
|
14
|
+
yield_index: bool,
|
|
15
|
+
) -> Observable[_T | int | None]:
|
|
16
|
+
"""Searches for an element in an observable sequence.
|
|
17
|
+
|
|
18
|
+
Examples:
|
|
19
|
+
>>> res = source.pipe(find_value(lambda x, i, s: x > 3, False))
|
|
20
|
+
>>> res = find_value(lambda x, i, s: x > 3, False)(source)
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
source: The source observable sequence.
|
|
24
|
+
predicate: A function to test each element.
|
|
25
|
+
yield_index: Whether to yield the index or the value.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
An observable sequence containing the found element or index.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def subscribe(
|
|
32
|
+
observer: abc.ObserverBase[_T | int | None],
|
|
33
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
34
|
+
) -> abc.DisposableBase:
|
|
35
|
+
index = 0
|
|
36
|
+
|
|
37
|
+
def on_next(x: _T) -> None:
|
|
38
|
+
nonlocal index
|
|
39
|
+
should_run = False
|
|
40
|
+
try:
|
|
41
|
+
should_run = predicate(x, index, source)
|
|
42
|
+
except Exception as ex: # pylint: disable=broad-except
|
|
43
|
+
observer.on_error(ex)
|
|
44
|
+
return
|
|
45
|
+
|
|
46
|
+
if should_run:
|
|
47
|
+
observer.on_next(index if yield_index else x)
|
|
35
48
|
observer.on_completed()
|
|
49
|
+
else:
|
|
50
|
+
index += 1
|
|
36
51
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
)
|
|
52
|
+
def on_completed():
|
|
53
|
+
observer.on_next(-1 if yield_index else None)
|
|
54
|
+
observer.on_completed()
|
|
40
55
|
|
|
41
|
-
return
|
|
56
|
+
return source.subscribe(
|
|
57
|
+
on_next, observer.on_error, on_completed, scheduler=scheduler
|
|
58
|
+
)
|
|
42
59
|
|
|
43
|
-
return
|
|
60
|
+
return Observable(subscribe)
|
|
44
61
|
|
|
45
62
|
|
|
46
63
|
__all__ = ["find_value_"]
|
reactivex/operators/_first.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import TypeVar, cast
|
|
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 Predicate
|
|
6
7
|
|
|
7
8
|
from ._firstordefault import first_or_default_async_
|
|
@@ -9,32 +10,38 @@ from ._firstordefault import first_or_default_async_
|
|
|
9
10
|
_T = TypeVar("_T")
|
|
10
11
|
|
|
11
12
|
|
|
13
|
+
@curry_flip
|
|
12
14
|
def first_(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
source: Observable[_T],
|
|
16
|
+
predicate: Predicate[_T] | None = None,
|
|
17
|
+
) -> Observable[_T]:
|
|
15
18
|
"""Returns the first element of an observable sequence that
|
|
16
19
|
satisfies the condition in the predicate if present else the first
|
|
17
20
|
item in the sequence.
|
|
18
21
|
|
|
19
22
|
Examples:
|
|
20
|
-
>>> res =
|
|
21
|
-
>>> res =
|
|
23
|
+
>>> res = source.pipe(first())
|
|
24
|
+
>>> res = first()(source)
|
|
25
|
+
>>> res = source.pipe(first(lambda x: x > 3))
|
|
22
26
|
|
|
23
27
|
Args:
|
|
24
|
-
|
|
28
|
+
source: The source observable sequence.
|
|
29
|
+
predicate: [Optional] A predicate function to evaluate for
|
|
25
30
|
elements in the source sequence.
|
|
26
31
|
|
|
27
32
|
Returns:
|
|
28
|
-
|
|
29
|
-
observable sequence containing the first element in the
|
|
33
|
+
An observable sequence containing the first element in the
|
|
30
34
|
observable sequence that satisfies the condition in the predicate if
|
|
31
35
|
provided, else the first item in the sequence.
|
|
32
36
|
"""
|
|
33
37
|
|
|
34
38
|
if predicate:
|
|
35
|
-
return
|
|
39
|
+
return source.pipe(ops.filter(predicate), ops.first())
|
|
36
40
|
|
|
37
|
-
|
|
41
|
+
# first_or_default_async_(False) returns
|
|
42
|
+
# Callable[[Observable[_T]], Observable[_T]] but the type checker
|
|
43
|
+
# cannot infer it. This cast is safe - implementation preserves type.
|
|
44
|
+
return cast(Observable[_T], first_or_default_async_(False)(source))
|
|
38
45
|
|
|
39
46
|
|
|
40
47
|
__all__ = ["first_"]
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
from
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from typing import TypeVar, cast
|
|
2
3
|
|
|
3
4
|
from reactivex import Observable, abc, compose
|
|
4
5
|
from reactivex import operators as ops
|
|
@@ -9,12 +10,12 @@ _T = TypeVar("_T")
|
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def first_or_default_async_(
|
|
12
|
-
has_default: bool = False, default_value:
|
|
13
|
+
has_default: bool = False, default_value: _T | None = None
|
|
13
14
|
) -> Callable[[Observable[_T]], Observable[_T]]:
|
|
14
15
|
def first_or_default_async(source: Observable[_T]) -> Observable[_T]:
|
|
15
16
|
def subscribe(
|
|
16
17
|
observer: abc.ObserverBase[_T],
|
|
17
|
-
scheduler:
|
|
18
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
18
19
|
):
|
|
19
20
|
def on_next(x: _T):
|
|
20
21
|
observer.on_next(x)
|
|
@@ -37,7 +38,7 @@ def first_or_default_async_(
|
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
def first_or_default_(
|
|
40
|
-
predicate:
|
|
41
|
+
predicate: Predicate[_T] | None = None, default_value: _T | None = None
|
|
41
42
|
) -> Callable[[Observable[_T]], Observable[_T]]:
|
|
42
43
|
"""Returns the first element of an observable sequence that
|
|
43
44
|
satisfies the condition in the predicate, or a default value if no
|