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/observable/interval.py
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
1
|
from reactivex import Observable, abc, timer, typing
|
|
4
2
|
|
|
5
3
|
|
|
6
4
|
def interval_(
|
|
7
|
-
period: typing.RelativeTime, scheduler:
|
|
5
|
+
period: typing.RelativeTime, scheduler: abc.SchedulerBase | None = None
|
|
8
6
|
) -> Observable[int]:
|
|
9
|
-
|
|
10
7
|
return timer(period, period, scheduler)
|
|
11
8
|
|
|
12
9
|
|
reactivex/observable/marbles.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import re
|
|
2
2
|
import threading
|
|
3
|
+
from collections.abc import Mapping
|
|
3
4
|
from datetime import datetime, timedelta
|
|
4
|
-
from typing import Any
|
|
5
|
+
from typing import Any
|
|
5
6
|
|
|
6
7
|
from reactivex import Notification, Observable, abc, notification, typing
|
|
7
8
|
from reactivex.disposable import CompositeDisposable, Disposable
|
|
@@ -34,9 +35,9 @@ def hot(
|
|
|
34
35
|
string: str,
|
|
35
36
|
timespan: typing.RelativeTime = 0.1,
|
|
36
37
|
duetime: typing.AbsoluteOrRelativeTime = 0.0,
|
|
37
|
-
lookup:
|
|
38
|
-
error:
|
|
39
|
-
scheduler:
|
|
38
|
+
lookup: Mapping[str | float, Any] | None = None,
|
|
39
|
+
error: Exception | None = None,
|
|
40
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
40
41
|
) -> Observable[Any]:
|
|
41
42
|
_scheduler = scheduler or new_thread_scheduler
|
|
42
43
|
|
|
@@ -54,10 +55,10 @@ def hot(
|
|
|
54
55
|
|
|
55
56
|
lock = threading.RLock()
|
|
56
57
|
is_stopped = False
|
|
57
|
-
observers:
|
|
58
|
+
observers: list[abc.ObserverBase[Any]] = []
|
|
58
59
|
|
|
59
60
|
def subscribe(
|
|
60
|
-
observer: abc.ObserverBase[Any], scheduler:
|
|
61
|
+
observer: abc.ObserverBase[Any], scheduler: abc.SchedulerBase | None = None
|
|
61
62
|
) -> abc.DisposableBase:
|
|
62
63
|
# should a hot observable already completed or on error
|
|
63
64
|
# re-push on_completed/on_error at subscription time?
|
|
@@ -100,22 +101,22 @@ def hot(
|
|
|
100
101
|
def from_marbles(
|
|
101
102
|
string: str,
|
|
102
103
|
timespan: typing.RelativeTime = 0.1,
|
|
103
|
-
lookup:
|
|
104
|
-
error:
|
|
105
|
-
scheduler:
|
|
104
|
+
lookup: Mapping[str | float, Any] | None = None,
|
|
105
|
+
error: Exception | None = None,
|
|
106
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
106
107
|
) -> Observable[Any]:
|
|
107
108
|
messages = parse(
|
|
108
109
|
string, timespan=timespan, lookup=lookup, error=error, raise_stopped=True
|
|
109
110
|
)
|
|
110
111
|
|
|
111
112
|
def subscribe(
|
|
112
|
-
observer: abc.ObserverBase[Any], scheduler_:
|
|
113
|
+
observer: abc.ObserverBase[Any], scheduler_: abc.SchedulerBase | None = None
|
|
113
114
|
) -> abc.DisposableBase:
|
|
114
115
|
_scheduler = scheduler or scheduler_ or new_thread_scheduler
|
|
115
116
|
disp = CompositeDisposable()
|
|
116
117
|
|
|
117
118
|
def schedule_msg(
|
|
118
|
-
message:
|
|
119
|
+
message: tuple[typing.RelativeTime, Notification[Any]],
|
|
119
120
|
) -> None:
|
|
120
121
|
duetime, notification = message
|
|
121
122
|
|
|
@@ -137,10 +138,10 @@ def parse(
|
|
|
137
138
|
string: str,
|
|
138
139
|
timespan: typing.RelativeTime = 1.0,
|
|
139
140
|
time_shift: typing.RelativeTime = 0.0,
|
|
140
|
-
lookup:
|
|
141
|
-
error:
|
|
141
|
+
lookup: Mapping[str | float, Any] | None = None,
|
|
142
|
+
error: Exception | None = None,
|
|
142
143
|
raise_stopped: bool = False,
|
|
143
|
-
) ->
|
|
144
|
+
) -> list[tuple[typing.RelativeTime, notification.Notification[Any]]]:
|
|
144
145
|
"""Convert a marble diagram string to a list of messages.
|
|
145
146
|
|
|
146
147
|
Each character in the string will advance time by timespan
|
|
@@ -209,7 +210,7 @@ def parse(
|
|
|
209
210
|
string = string.replace(" ", "")
|
|
210
211
|
|
|
211
212
|
# try to cast a string to an int, then to a float
|
|
212
|
-
def try_number(element: str) ->
|
|
213
|
+
def try_number(element: str) -> float | str:
|
|
213
214
|
try:
|
|
214
215
|
return int(element)
|
|
215
216
|
except ValueError:
|
|
@@ -220,7 +221,7 @@ def parse(
|
|
|
220
221
|
|
|
221
222
|
def map_element(
|
|
222
223
|
time: typing.RelativeTime, element: str
|
|
223
|
-
) ->
|
|
224
|
+
) -> tuple[typing.RelativeTime, Notification[Any]]:
|
|
224
225
|
if element == "|":
|
|
225
226
|
return (time, notification.OnCompleted())
|
|
226
227
|
elif element == "#":
|
|
@@ -242,7 +243,7 @@ def parse(
|
|
|
242
243
|
is_stopped = True
|
|
243
244
|
|
|
244
245
|
iframe = 0
|
|
245
|
-
messages:
|
|
246
|
+
messages: list[tuple[typing.RelativeTime, Notification[Any]]] = []
|
|
246
247
|
|
|
247
248
|
for results in tokens.findall(string):
|
|
248
249
|
timestamp = iframe * timespan + time_shift
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Mixins for Observable method chaining.
|
|
2
|
+
|
|
3
|
+
This module contains mixin classes that provide operator methods for Observable.
|
|
4
|
+
Each mixin focuses on a specific category of operators, making the codebase
|
|
5
|
+
more maintainable and organized.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .combination import CombinationMixin
|
|
9
|
+
from .conditional import ConditionalMixin
|
|
10
|
+
from .error_handling import ErrorHandlingMixin
|
|
11
|
+
from .filtering import FilteringMixin
|
|
12
|
+
from .mathematical import MathematicalMixin
|
|
13
|
+
from .multicasting import MulticastingMixin
|
|
14
|
+
from .testing import TestingMixin
|
|
15
|
+
from .time_based import TimeBasedMixin
|
|
16
|
+
from .transformation import TransformationMixin
|
|
17
|
+
from .utility import UtilityMixin
|
|
18
|
+
from .windowing import WindowingMixin
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"CombinationMixin",
|
|
22
|
+
"ConditionalMixin",
|
|
23
|
+
"ErrorHandlingMixin",
|
|
24
|
+
"FilteringMixin",
|
|
25
|
+
"MathematicalMixin",
|
|
26
|
+
"MulticastingMixin",
|
|
27
|
+
"TestingMixin",
|
|
28
|
+
"TimeBasedMixin",
|
|
29
|
+
"TransformationMixin",
|
|
30
|
+
"UtilityMixin",
|
|
31
|
+
"WindowingMixin",
|
|
32
|
+
]
|
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
"""Combination operators mixin for Observable."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Callable, Iterable
|
|
6
|
+
from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from asyncio import Future
|
|
10
|
+
|
|
11
|
+
from reactivex.observable import Observable
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
_T = TypeVar("_T", covariant=True)
|
|
15
|
+
_T2 = TypeVar("_T2")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class CombinationMixin(Generic[_T]):
|
|
19
|
+
"""Mixin providing combination operators for Observable.
|
|
20
|
+
|
|
21
|
+
This mixin adds operators that combine multiple observable sequences,
|
|
22
|
+
including merge, concat, zip, and various other combination strategies.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def _as_observable(self) -> Observable[_T]:
|
|
26
|
+
"""Cast mixin instance to Observable preserving type parameter.
|
|
27
|
+
|
|
28
|
+
This is safe because this mixin is only ever used as part of the Observable
|
|
29
|
+
class through multiple inheritance. At runtime, `self` in mixin methods will
|
|
30
|
+
always be an Observable[_T] instance. The type checker cannot infer this
|
|
31
|
+
because it analyzes mixins in isolation.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
The instance cast to Observable[_T] for type-safe method access.
|
|
35
|
+
"""
|
|
36
|
+
return cast("Observable[_T]", self)
|
|
37
|
+
|
|
38
|
+
def merge(
|
|
39
|
+
self, *sources: Observable[_T], max_concurrent: int | None = None
|
|
40
|
+
) -> Observable[_T]:
|
|
41
|
+
"""Merge with other observables.
|
|
42
|
+
|
|
43
|
+
Merges an observable sequence of observable sequences into an observable
|
|
44
|
+
sequence, limiting the number of concurrent subscriptions to inner sequences.
|
|
45
|
+
|
|
46
|
+
Examples:
|
|
47
|
+
Fluent style:
|
|
48
|
+
>>> result = source.merge(other1, other2)
|
|
49
|
+
>>> result = source.merge(other, max_concurrent=2)
|
|
50
|
+
|
|
51
|
+
Equivalent pipe style:
|
|
52
|
+
>>> from reactivex import operators as ops
|
|
53
|
+
>>> result = source.pipe(ops.merge(other1, other2))
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
*sources: Observable sequences to merge with the source.
|
|
57
|
+
max_concurrent: Maximum number of concurrent subscriptions.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
The observable sequence that merges the elements of the observable
|
|
61
|
+
sequences.
|
|
62
|
+
|
|
63
|
+
See Also:
|
|
64
|
+
- :func:`merge <reactivex.operators.merge>`
|
|
65
|
+
- :meth:`concat`
|
|
66
|
+
- :meth:`combine_latest`
|
|
67
|
+
"""
|
|
68
|
+
from reactivex import operators as ops
|
|
69
|
+
|
|
70
|
+
return self._as_observable().pipe(
|
|
71
|
+
ops.merge(*sources, max_concurrent=max_concurrent)
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
def concat(self, *sources: Observable[_T]) -> Observable[_T]:
|
|
75
|
+
"""Concatenate with other observables.
|
|
76
|
+
|
|
77
|
+
Concatenates all the observable sequences.
|
|
78
|
+
|
|
79
|
+
Examples:
|
|
80
|
+
Fluent style:
|
|
81
|
+
>>> result = source.concat(other1, other2)
|
|
82
|
+
|
|
83
|
+
Equivalent pipe style:
|
|
84
|
+
>>> from reactivex import operators as ops
|
|
85
|
+
>>> result = source.pipe(ops.concat(other1, other2))
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
*sources: Observable sequences to concatenate with the source.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
An observable sequence that contains the elements of each given
|
|
92
|
+
sequence, in sequential order.
|
|
93
|
+
|
|
94
|
+
See Also:
|
|
95
|
+
- :func:`concat <reactivex.operators.concat>`
|
|
96
|
+
- :meth:`merge`
|
|
97
|
+
- :meth:`concat_map`
|
|
98
|
+
"""
|
|
99
|
+
from reactivex import operators as ops
|
|
100
|
+
|
|
101
|
+
return self._as_observable().pipe(ops.concat(*sources))
|
|
102
|
+
|
|
103
|
+
def zip(self, *sources: Observable[Any]) -> Observable[Any]:
|
|
104
|
+
"""Zip with other observables.
|
|
105
|
+
|
|
106
|
+
Merges the specified observable sequences into one observable sequence
|
|
107
|
+
by creating a tuple whenever all of the observable sequences have
|
|
108
|
+
produced an element at a corresponding index.
|
|
109
|
+
|
|
110
|
+
Examples:
|
|
111
|
+
Fluent style:
|
|
112
|
+
>>> result = source.zip(other1, other2)
|
|
113
|
+
|
|
114
|
+
Equivalent pipe style:
|
|
115
|
+
>>> from reactivex import operators as ops
|
|
116
|
+
>>> result = source.pipe(ops.zip(other1, other2))
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
*sources: Observable sequences to zip with the source.
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
An observable sequence containing the result of combining elements
|
|
123
|
+
of the sources as tuples.
|
|
124
|
+
|
|
125
|
+
See Also:
|
|
126
|
+
- :func:`zip <reactivex.operators.zip>`
|
|
127
|
+
- :meth:`combine_latest`
|
|
128
|
+
- :meth:`with_latest_from`
|
|
129
|
+
"""
|
|
130
|
+
from reactivex import operators as ops
|
|
131
|
+
|
|
132
|
+
return self._as_observable().pipe(ops.zip(*sources))
|
|
133
|
+
|
|
134
|
+
def combine_latest(self, *sources: Observable[Any]) -> Observable[Any]:
|
|
135
|
+
"""Combine latest values from observables.
|
|
136
|
+
|
|
137
|
+
Merges the specified observable sequences into one observable sequence
|
|
138
|
+
by creating a tuple whenever any of the observable sequences produces
|
|
139
|
+
an element.
|
|
140
|
+
|
|
141
|
+
Examples:
|
|
142
|
+
Fluent style:
|
|
143
|
+
>>> result = source.combine_latest(other1, other2)
|
|
144
|
+
|
|
145
|
+
Equivalent pipe style:
|
|
146
|
+
>>> from reactivex import operators as ops
|
|
147
|
+
>>> result = source.pipe(ops.combine_latest(other1, other2))
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
*sources: Observable sequences to combine with the source.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
An observable sequence containing the result of combining elements
|
|
154
|
+
of the sources as tuples.
|
|
155
|
+
|
|
156
|
+
See Also:
|
|
157
|
+
- :func:`combine_latest <reactivex.operators.combine_latest>`
|
|
158
|
+
- :meth:`zip`
|
|
159
|
+
- :meth:`with_latest_from`
|
|
160
|
+
"""
|
|
161
|
+
from reactivex import operators as ops
|
|
162
|
+
|
|
163
|
+
return self._as_observable().pipe(ops.combine_latest(*sources))
|
|
164
|
+
|
|
165
|
+
def with_latest_from(self, *sources: Observable[Any]) -> Observable[Any]:
|
|
166
|
+
"""Combine with latest values from other observables.
|
|
167
|
+
|
|
168
|
+
Merges the specified observable sequences into one observable sequence
|
|
169
|
+
by creating a tuple only when the first observable sequence (self)
|
|
170
|
+
produces an element.
|
|
171
|
+
|
|
172
|
+
Examples:
|
|
173
|
+
Fluent style:
|
|
174
|
+
>>> result = source.with_latest_from(other1, other2)
|
|
175
|
+
|
|
176
|
+
Equivalent pipe style:
|
|
177
|
+
>>> from reactivex import operators as ops
|
|
178
|
+
>>> result = source.pipe(ops.with_latest_from(other1, other2))
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
*sources: Observable sequences whose latest values to include.
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
An observable sequence containing the result of combining the source
|
|
185
|
+
with the latest values from other sources as tuples.
|
|
186
|
+
|
|
187
|
+
See Also:
|
|
188
|
+
- :func:`with_latest_from <reactivex.operators.with_latest_from>`
|
|
189
|
+
- :meth:`combine_latest`
|
|
190
|
+
"""
|
|
191
|
+
from reactivex import operators as ops
|
|
192
|
+
|
|
193
|
+
return self._as_observable().pipe(ops.with_latest_from(*sources))
|
|
194
|
+
|
|
195
|
+
def start_with(self, *args: Any) -> Observable[Any]:
|
|
196
|
+
"""Prepend values to the sequence.
|
|
197
|
+
|
|
198
|
+
Prepends a sequence of values to an observable sequence.
|
|
199
|
+
|
|
200
|
+
Examples:
|
|
201
|
+
Fluent style:
|
|
202
|
+
>>> result = source.start_with(1, 2, 3)
|
|
203
|
+
|
|
204
|
+
Equivalent pipe style:
|
|
205
|
+
>>> from reactivex import operators as ops
|
|
206
|
+
>>> result = source.pipe(ops.start_with(1, 2, 3))
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
*args: Values to prepend to the observable sequence.
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
The source sequence prepended with the specified values.
|
|
213
|
+
|
|
214
|
+
See Also:
|
|
215
|
+
- :func:`start_with <reactivex.operators.start_with>`
|
|
216
|
+
"""
|
|
217
|
+
from reactivex import operators as ops
|
|
218
|
+
|
|
219
|
+
return self._as_observable().pipe(ops.start_with(*args))
|
|
220
|
+
|
|
221
|
+
def fork_join(self, *others: Observable[Any]) -> Observable[tuple[Any, ...]]:
|
|
222
|
+
"""Wait for all observables to complete and combine last values.
|
|
223
|
+
|
|
224
|
+
Wait for observables to complete and then combine last values
|
|
225
|
+
they emitted into a tuple. Whenever any of those observables
|
|
226
|
+
completes without emitting any value, result sequence will
|
|
227
|
+
complete at that moment as well.
|
|
228
|
+
|
|
229
|
+
Examples:
|
|
230
|
+
Fluent style:
|
|
231
|
+
>>> result = source.fork_join(observable2, observable3)
|
|
232
|
+
|
|
233
|
+
Equivalent pipe style:
|
|
234
|
+
>>> from reactivex import operators as ops
|
|
235
|
+
>>> result = source.pipe(ops.fork_join(observable2, observable3))
|
|
236
|
+
|
|
237
|
+
Args:
|
|
238
|
+
*others: Other observable sequences to combine with.
|
|
239
|
+
|
|
240
|
+
Returns:
|
|
241
|
+
An observable sequence containing a tuple with the last elements
|
|
242
|
+
from all sequences.
|
|
243
|
+
|
|
244
|
+
See Also:
|
|
245
|
+
- :func:`fork_join <reactivex.operators.fork_join>`
|
|
246
|
+
- :meth:`zip`
|
|
247
|
+
- :meth:`combine_latest`
|
|
248
|
+
"""
|
|
249
|
+
from reactivex import operators as ops
|
|
250
|
+
|
|
251
|
+
return self._as_observable().pipe(ops.fork_join(*others))
|
|
252
|
+
|
|
253
|
+
def switch_latest(self) -> Observable[Any]:
|
|
254
|
+
"""Switch to the most recent inner observable.
|
|
255
|
+
|
|
256
|
+
Transforms an observable sequence of observable sequences into an
|
|
257
|
+
observable sequence producing values only from the most recent
|
|
258
|
+
observable sequence.
|
|
259
|
+
|
|
260
|
+
Examples:
|
|
261
|
+
Fluent style:
|
|
262
|
+
>>> result = source_of_observables.switch_latest()
|
|
263
|
+
|
|
264
|
+
Equivalent pipe style:
|
|
265
|
+
>>> from reactivex import operators as ops
|
|
266
|
+
>>> result = source.pipe(ops.switch_latest())
|
|
267
|
+
|
|
268
|
+
Returns:
|
|
269
|
+
The observable sequence that at any point in time produces the
|
|
270
|
+
elements of the most recent inner observable sequence that has
|
|
271
|
+
been received.
|
|
272
|
+
|
|
273
|
+
See Also:
|
|
274
|
+
- :func:`switch_latest <reactivex.operators.switch_latest>`
|
|
275
|
+
- :meth:`switch_map`
|
|
276
|
+
- :meth:`merge`
|
|
277
|
+
"""
|
|
278
|
+
# Cast is safe: switch_latest is meant to be called on Observable
|
|
279
|
+
# of Observables. The fluent API allows chaining this on nested
|
|
280
|
+
# observable sequences. The cast preserves type safety for the
|
|
281
|
+
# intended use case where _T is an Observable or Future.
|
|
282
|
+
|
|
283
|
+
from reactivex import operators as ops
|
|
284
|
+
|
|
285
|
+
source: Observable[Observable[Any] | Future[Any]] = cast(
|
|
286
|
+
"Observable[Observable[Any] | Future[Any]]", self._as_observable()
|
|
287
|
+
)
|
|
288
|
+
return ops.switch_latest()(source)
|
|
289
|
+
|
|
290
|
+
def amb(self, right_source: Observable[_T]) -> Observable[_T]:
|
|
291
|
+
"""Propagate the observable that reacts first.
|
|
292
|
+
|
|
293
|
+
Propagates the observable sequence that reacts first.
|
|
294
|
+
|
|
295
|
+
Examples:
|
|
296
|
+
Fluent style:
|
|
297
|
+
>>> result = source1.amb(source2)
|
|
298
|
+
|
|
299
|
+
Equivalent pipe style:
|
|
300
|
+
>>> from reactivex import operators as ops
|
|
301
|
+
>>> result = source1.pipe(ops.amb(source2))
|
|
302
|
+
|
|
303
|
+
Args:
|
|
304
|
+
right_source: Second observable sequence.
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
An observable sequence that surfaces any of the given sequences,
|
|
308
|
+
whichever reacted first.
|
|
309
|
+
|
|
310
|
+
See Also:
|
|
311
|
+
- :func:`amb <reactivex.operators.amb>`
|
|
312
|
+
"""
|
|
313
|
+
from reactivex import operators as ops
|
|
314
|
+
|
|
315
|
+
return self._as_observable().pipe(ops.amb(right_source))
|
|
316
|
+
|
|
317
|
+
def merge_all(self) -> Observable[Any]:
|
|
318
|
+
"""Merge all inner observables.
|
|
319
|
+
|
|
320
|
+
Merges an observable sequence of observable sequences into an observable
|
|
321
|
+
sequence.
|
|
322
|
+
|
|
323
|
+
Examples:
|
|
324
|
+
Fluent style:
|
|
325
|
+
>>> result = source_of_sources.merge_all()
|
|
326
|
+
|
|
327
|
+
Equivalent pipe style:
|
|
328
|
+
>>> from reactivex import operators as ops
|
|
329
|
+
>>> result = source_of_sources.pipe(ops.merge_all())
|
|
330
|
+
|
|
331
|
+
Returns:
|
|
332
|
+
An observable sequence that merges the elements of the inner sequences.
|
|
333
|
+
|
|
334
|
+
See Also:
|
|
335
|
+
- :func:`merge_all <reactivex.operators.merge_all>`
|
|
336
|
+
- :meth:`merge`
|
|
337
|
+
- :meth:`concat_all`
|
|
338
|
+
"""
|
|
339
|
+
# Cast is safe: merge_all is meant to be called on Observable of Observables.
|
|
340
|
+
# The fluent API allows chaining this on nested observable sequences where
|
|
341
|
+
# _T is Observable[_T2]. We return Observable[Any] as the inner type cannot
|
|
342
|
+
# be statically inferred from _T without higher-kinded types.
|
|
343
|
+
from reactivex import operators as ops
|
|
344
|
+
|
|
345
|
+
op: Callable[[Observable[Any]], Observable[Any]] = cast(
|
|
346
|
+
"Callable[[Observable[Any]], Observable[Any]]", ops.merge_all()
|
|
347
|
+
)
|
|
348
|
+
return self._as_observable().pipe(op)
|
|
349
|
+
|
|
350
|
+
def zip_with_iterable(self, second: Iterable[_T2]) -> Observable[tuple[_T, _T2]]:
|
|
351
|
+
"""Zip with iterable.
|
|
352
|
+
|
|
353
|
+
Merges the specified observable sequence and iterable into one observable
|
|
354
|
+
sequence by creating a tuple whenever both sequences have produced an element
|
|
355
|
+
at a corresponding index.
|
|
356
|
+
|
|
357
|
+
Examples:
|
|
358
|
+
Fluent style:
|
|
359
|
+
>>> result = source.zip_with_iterable([1, 2, 3])
|
|
360
|
+
|
|
361
|
+
Equivalent pipe style:
|
|
362
|
+
>>> from reactivex import operators as ops
|
|
363
|
+
>>> result = source.pipe(ops.zip_with_iterable([1, 2, 3]))
|
|
364
|
+
|
|
365
|
+
Args:
|
|
366
|
+
second: Iterable to zip with the source observable.
|
|
367
|
+
|
|
368
|
+
Returns:
|
|
369
|
+
An observable sequence containing the result of combining elements of the
|
|
370
|
+
sources as a tuple.
|
|
371
|
+
|
|
372
|
+
See Also:
|
|
373
|
+
- :func:`zip_with_iterable <reactivex.operators.zip_with_iterable>`
|
|
374
|
+
- :meth:`zip`
|
|
375
|
+
"""
|
|
376
|
+
from reactivex import operators as ops
|
|
377
|
+
|
|
378
|
+
return self._as_observable().pipe(ops.zip_with_iterable(second))
|
|
379
|
+
|
|
380
|
+
def join(
|
|
381
|
+
self,
|
|
382
|
+
right: Observable[_T2],
|
|
383
|
+
left_duration_mapper: Callable[[_T], Observable[Any]],
|
|
384
|
+
right_duration_mapper: Callable[[_T2], Observable[Any]],
|
|
385
|
+
) -> Observable[tuple[_T, _T2]]:
|
|
386
|
+
"""Join based on overlapping durations.
|
|
387
|
+
|
|
388
|
+
Correlates the elements of two sequences based on overlapping durations.
|
|
389
|
+
|
|
390
|
+
Examples:
|
|
391
|
+
Fluent style:
|
|
392
|
+
>>> result = left.join(
|
|
393
|
+
... right,
|
|
394
|
+
... lambda x: rx.timer(0.5),
|
|
395
|
+
... lambda x: rx.timer(0.5)
|
|
396
|
+
... )
|
|
397
|
+
|
|
398
|
+
Equivalent pipe style:
|
|
399
|
+
>>> from reactivex import operators as ops
|
|
400
|
+
>>> result = left.pipe(
|
|
401
|
+
... ops.join(
|
|
402
|
+
... right,
|
|
403
|
+
... lambda x: rx.timer(0.5),
|
|
404
|
+
... lambda x: rx.timer(0.5)
|
|
405
|
+
... )
|
|
406
|
+
... )
|
|
407
|
+
|
|
408
|
+
Args:
|
|
409
|
+
right: The right observable sequence to join elements for.
|
|
410
|
+
left_duration_mapper: A function to select the duration (expressed as an
|
|
411
|
+
observable sequence) of each element of the left observable sequence,
|
|
412
|
+
used to determine overlap.
|
|
413
|
+
right_duration_mapper: A function to select the duration (expressed as an
|
|
414
|
+
observable sequence) of each element of the right observable sequence,
|
|
415
|
+
used to determine overlap.
|
|
416
|
+
|
|
417
|
+
Returns:
|
|
418
|
+
An observable sequence that contains elements combined into a tuple from
|
|
419
|
+
source elements that have an overlapping duration.
|
|
420
|
+
|
|
421
|
+
See Also:
|
|
422
|
+
- :func:`join <reactivex.operators.join>`
|
|
423
|
+
- :meth:`group_join`
|
|
424
|
+
"""
|
|
425
|
+
from reactivex import operators as ops
|
|
426
|
+
|
|
427
|
+
return self._as_observable().pipe(
|
|
428
|
+
ops.join(right, left_duration_mapper, right_duration_mapper)
|
|
429
|
+
)
|
|
430
|
+
|
|
431
|
+
def group_join(
|
|
432
|
+
self,
|
|
433
|
+
right: Observable[_T2],
|
|
434
|
+
left_duration_mapper: Callable[[_T], Observable[Any]],
|
|
435
|
+
right_duration_mapper: Callable[[_T2], Observable[Any]],
|
|
436
|
+
) -> Observable[tuple[_T, Observable[_T2]]]:
|
|
437
|
+
"""Group join based on overlapping durations.
|
|
438
|
+
|
|
439
|
+
Correlates the elements of two sequences based on overlapping durations, and
|
|
440
|
+
groups the results.
|
|
441
|
+
|
|
442
|
+
Examples:
|
|
443
|
+
Fluent style:
|
|
444
|
+
>>> result = left.group_join(
|
|
445
|
+
... right,
|
|
446
|
+
... lambda x: rx.timer(0.5),
|
|
447
|
+
... lambda x: rx.timer(0.5)
|
|
448
|
+
... )
|
|
449
|
+
|
|
450
|
+
Equivalent pipe style:
|
|
451
|
+
>>> from reactivex import operators as ops
|
|
452
|
+
>>> result = left.pipe(
|
|
453
|
+
... ops.group_join(
|
|
454
|
+
... right,
|
|
455
|
+
... lambda x: rx.timer(0.5),
|
|
456
|
+
... lambda x: rx.timer(0.5)
|
|
457
|
+
... )
|
|
458
|
+
... )
|
|
459
|
+
|
|
460
|
+
Args:
|
|
461
|
+
right: The right observable sequence to join elements for.
|
|
462
|
+
left_duration_mapper: A function to select the duration (expressed as an
|
|
463
|
+
observable sequence) of each element of the left observable sequence,
|
|
464
|
+
used to determine overlap.
|
|
465
|
+
right_duration_mapper: A function to select the duration (expressed as an
|
|
466
|
+
observable sequence) of each element of the right observable sequence,
|
|
467
|
+
used to determine overlap.
|
|
468
|
+
|
|
469
|
+
Returns:
|
|
470
|
+
An observable sequence that contains elements combined into a tuple from
|
|
471
|
+
source elements that have an overlapping duration.
|
|
472
|
+
|
|
473
|
+
See Also:
|
|
474
|
+
- :func:`group_join <reactivex.operators.group_join>`
|
|
475
|
+
- :meth:`join`
|
|
476
|
+
"""
|
|
477
|
+
from reactivex import operators as ops
|
|
478
|
+
|
|
479
|
+
return self._as_observable().pipe(
|
|
480
|
+
ops.group_join(right, left_duration_mapper, right_duration_mapper)
|
|
481
|
+
)
|