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/_todict.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import TypeVar, cast
|
|
2
2
|
|
|
3
3
|
from reactivex import Observable, abc
|
|
4
|
+
from reactivex.internal import curry_flip
|
|
4
5
|
from reactivex.typing import Mapper
|
|
5
6
|
|
|
6
7
|
_T = TypeVar("_T")
|
|
@@ -8,57 +9,64 @@ _TKey = TypeVar("_TKey")
|
|
|
8
9
|
_TValue = TypeVar("_TValue")
|
|
9
10
|
|
|
10
11
|
|
|
12
|
+
@curry_flip
|
|
11
13
|
def to_dict_(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
14
|
+
source: Observable[_T],
|
|
15
|
+
key_mapper: Mapper[_T, _TKey],
|
|
16
|
+
element_mapper: Mapper[_T, _TValue] | None = None,
|
|
17
|
+
) -> Observable[dict[_TKey, _TValue]]:
|
|
18
|
+
"""Converts the observable sequence to a dictionary.
|
|
19
|
+
|
|
20
|
+
Examples:
|
|
21
|
+
>>> result = source.pipe(to_dict(lambda x: x.id))
|
|
22
|
+
>>> result = to_dict(lambda x: x.id)(source)
|
|
23
|
+
>>> result = source.pipe(to_dict(lambda x: x.id, lambda x: x.name))
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
source: Source observable to convert.
|
|
27
|
+
key_mapper: Function to extract the key from each element.
|
|
28
|
+
element_mapper: Optional function to extract the value from each element.
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
An observable sequence with a single value of a dictionary
|
|
32
|
+
containing the values from the observable sequence.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def subscribe(
|
|
36
|
+
observer: abc.ObserverBase[dict[_TKey, _TValue]],
|
|
37
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
38
|
+
) -> abc.DisposableBase:
|
|
39
|
+
m: dict[_TKey, _TValue] = dict()
|
|
40
|
+
|
|
41
|
+
def on_next(x: _T) -> None:
|
|
42
|
+
try:
|
|
43
|
+
key = key_mapper(x)
|
|
44
|
+
except Exception as ex: # pylint: disable=broad-except
|
|
45
|
+
observer.on_error(ex)
|
|
46
|
+
return
|
|
47
|
+
|
|
48
|
+
if element_mapper:
|
|
32
49
|
try:
|
|
33
|
-
|
|
50
|
+
element = element_mapper(x)
|
|
34
51
|
except Exception as ex: # pylint: disable=broad-except
|
|
35
52
|
observer.on_error(ex)
|
|
36
53
|
return
|
|
54
|
+
else:
|
|
55
|
+
element = cast(_TValue, x)
|
|
37
56
|
|
|
38
|
-
|
|
39
|
-
try:
|
|
40
|
-
element = element_mapper(x)
|
|
41
|
-
except Exception as ex: # pylint: disable=broad-except
|
|
42
|
-
observer.on_error(ex)
|
|
43
|
-
return
|
|
44
|
-
else:
|
|
45
|
-
element = cast(_TValue, x)
|
|
57
|
+
m[key] = element
|
|
46
58
|
|
|
47
|
-
|
|
59
|
+
def on_completed() -> None:
|
|
60
|
+
nonlocal m
|
|
61
|
+
observer.on_next(m)
|
|
62
|
+
m = dict()
|
|
63
|
+
observer.on_completed()
|
|
48
64
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
m = dict()
|
|
53
|
-
observer.on_completed()
|
|
65
|
+
return source.subscribe(
|
|
66
|
+
on_next, observer.on_error, on_completed, scheduler=scheduler
|
|
67
|
+
)
|
|
54
68
|
|
|
55
|
-
|
|
56
|
-
on_next, observer.on_error, on_completed, scheduler=scheduler
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
return Observable(subscribe)
|
|
60
|
-
|
|
61
|
-
return to_dict
|
|
69
|
+
return Observable(subscribe)
|
|
62
70
|
|
|
63
71
|
|
|
64
72
|
__all__ = ["to_dict_"]
|
reactivex/operators/_tofuture.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
from asyncio import Future
|
|
3
|
-
from
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
from typing import TypeVar, cast
|
|
4
5
|
|
|
5
6
|
from reactivex import Observable, abc
|
|
6
7
|
from reactivex.internal.exceptions import SequenceContainsNoElementsError
|
|
@@ -9,15 +10,10 @@ _T = TypeVar("_T")
|
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def to_future_(
|
|
12
|
-
future_ctor:
|
|
13
|
-
scheduler:
|
|
14
|
-
) -> Callable[[Observable[_T]],
|
|
15
|
-
|
|
16
|
-
future_ctor or asyncio.get_event_loop().create_future
|
|
17
|
-
)
|
|
18
|
-
future: "Future[_T]" = future_ctor_()
|
|
19
|
-
|
|
20
|
-
def to_future(source: Observable[_T]) -> "Future[_T]":
|
|
13
|
+
future_ctor: Callable[[], Future[_T]] | None = None,
|
|
14
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
15
|
+
) -> Callable[[Observable[_T]], Future[_T]]:
|
|
16
|
+
def to_future(source: Observable[_T]) -> Future[_T]:
|
|
21
17
|
"""Converts an existing observable sequence to a Future.
|
|
22
18
|
|
|
23
19
|
If the observable emits a single item, then this item is set as the
|
|
@@ -33,25 +29,38 @@ def to_future_(
|
|
|
33
29
|
Returns:
|
|
34
30
|
A future with the last value from the observable sequence.
|
|
35
31
|
"""
|
|
32
|
+
if future_ctor is not None:
|
|
33
|
+
future_ctor_ = future_ctor
|
|
34
|
+
else:
|
|
35
|
+
try:
|
|
36
|
+
future_ctor_ = asyncio.get_running_loop().create_future
|
|
37
|
+
except RuntimeError:
|
|
38
|
+
|
|
39
|
+
def create_future() -> Future[_T]:
|
|
40
|
+
return Future() # Explicitly using Future[_T]
|
|
41
|
+
|
|
42
|
+
future_ctor_ = create_future # If no running loop
|
|
43
|
+
|
|
44
|
+
future: Future[_T] = future_ctor_()
|
|
36
45
|
|
|
37
46
|
has_value = False
|
|
38
|
-
last_value
|
|
47
|
+
last_value: _T | None = None
|
|
39
48
|
|
|
40
|
-
def on_next(value: _T):
|
|
49
|
+
def on_next(value: _T) -> None:
|
|
41
50
|
nonlocal last_value
|
|
42
51
|
nonlocal has_value
|
|
43
52
|
last_value = value
|
|
44
53
|
has_value = True
|
|
45
54
|
|
|
46
|
-
def on_error(err: Exception):
|
|
55
|
+
def on_error(err: Exception) -> None:
|
|
47
56
|
if not future.cancelled():
|
|
48
57
|
future.set_exception(err)
|
|
49
58
|
|
|
50
|
-
def on_completed():
|
|
59
|
+
def on_completed() -> None:
|
|
51
60
|
nonlocal last_value
|
|
52
61
|
if not future.cancelled():
|
|
53
62
|
if has_value:
|
|
54
|
-
future.set_result(last_value)
|
|
63
|
+
future.set_result(cast(_T, last_value))
|
|
55
64
|
else:
|
|
56
65
|
future.set_exception(SequenceContainsNoElementsError())
|
|
57
66
|
last_value = None
|
|
@@ -1,44 +1,50 @@
|
|
|
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
|
-
|
|
9
|
+
@curry_flip
|
|
10
|
+
def to_iterable_(source: Observable[_T]) -> Observable[list[_T]]:
|
|
11
|
+
"""Creates an iterable from an observable sequence.
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
sequence.
|
|
16
|
-
"""
|
|
13
|
+
Examples:
|
|
14
|
+
>>> res = source.pipe(to_iterable())
|
|
15
|
+
>>> res = to_iterable()(source)
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
scheduler: Optional[abc.SchedulerBase] = None,
|
|
21
|
-
):
|
|
22
|
-
nonlocal source
|
|
17
|
+
Args:
|
|
18
|
+
source: Source observable.
|
|
23
19
|
|
|
24
|
-
|
|
20
|
+
Returns:
|
|
21
|
+
An observable sequence containing a single element with an
|
|
22
|
+
iterable containing all the elements of the source
|
|
23
|
+
sequence.
|
|
24
|
+
"""
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
def subscribe(
|
|
27
|
+
observer: abc.ObserverBase[list[_T]],
|
|
28
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
29
|
+
):
|
|
30
|
+
nonlocal source
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
nonlocal queue
|
|
31
|
-
observer.on_next(queue)
|
|
32
|
-
queue = []
|
|
33
|
-
observer.on_completed()
|
|
32
|
+
queue: list[_T] = []
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
)
|
|
34
|
+
def on_next(item: _T):
|
|
35
|
+
queue.append(item)
|
|
38
36
|
|
|
39
|
-
|
|
37
|
+
def on_completed():
|
|
38
|
+
nonlocal queue
|
|
39
|
+
observer.on_next(queue)
|
|
40
|
+
queue = []
|
|
41
|
+
observer.on_completed()
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
return source.subscribe(
|
|
44
|
+
on_next, observer.on_error, on_completed, scheduler=scheduler
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
return Observable(subscribe)
|
|
42
48
|
|
|
43
49
|
|
|
44
50
|
__all__ = ["to_iterable_"]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any
|
|
1
|
+
from typing import Any
|
|
2
2
|
|
|
3
3
|
from reactivex import Observable, abc
|
|
4
4
|
from reactivex.scheduler import NewThreadScheduler
|
|
@@ -8,7 +8,7 @@ new_thread_scheduler = NewThreadScheduler()
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def to_marbles(
|
|
11
|
-
timespan: RelativeTime = 0.1, scheduler:
|
|
11
|
+
timespan: RelativeTime = 0.1, scheduler: abc.SchedulerBase | None = None
|
|
12
12
|
):
|
|
13
13
|
def to_marbles(source: Observable[Any]) -> Observable[str]:
|
|
14
14
|
"""Convert an observable sequence into a marble diagram string.
|
|
@@ -25,11 +25,11 @@ def to_marbles(
|
|
|
25
25
|
|
|
26
26
|
def subscribe(
|
|
27
27
|
observer: abc.ObserverBase[str],
|
|
28
|
-
scheduler:
|
|
28
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
29
29
|
):
|
|
30
30
|
scheduler = scheduler or new_thread_scheduler
|
|
31
31
|
|
|
32
|
-
result:
|
|
32
|
+
result: list[str] = []
|
|
33
33
|
last = scheduler.now
|
|
34
34
|
|
|
35
35
|
def add_timespan():
|
|
@@ -70,7 +70,7 @@ def stringify(value: Any) -> str:
|
|
|
70
70
|
"""Utility for stringifying an event."""
|
|
71
71
|
string = str(value)
|
|
72
72
|
if len(string) > 1:
|
|
73
|
-
string = "(
|
|
73
|
+
string = f"({string})"
|
|
74
74
|
|
|
75
75
|
return string
|
|
76
76
|
|
reactivex/operators/_toset.py
CHANGED
|
@@ -1,37 +1,47 @@
|
|
|
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
|
+
@curry_flip
|
|
10
|
+
def to_set_(source: Observable[_T]) -> Observable[set[_T]]:
|
|
9
11
|
"""Converts the observable sequence to a set.
|
|
10
12
|
|
|
11
13
|
Returns an observable sequence with a single value of a set
|
|
12
14
|
containing the values from the observable sequence.
|
|
13
|
-
"""
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
Examples:
|
|
17
|
+
>>> res = source.pipe(to_set())
|
|
18
|
+
>>> res = to_set()(source)
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
source: Source observable.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
An observable sequence with a single value of a set
|
|
25
|
+
containing the values from the observable sequence.
|
|
26
|
+
"""
|
|
21
27
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
def subscribe(
|
|
29
|
+
observer: abc.ObserverBase[set[_T]],
|
|
30
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
31
|
+
) -> abc.DisposableBase:
|
|
32
|
+
s: set[_T] = set()
|
|
27
33
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
)
|
|
34
|
+
def on_completed() -> None:
|
|
35
|
+
nonlocal s
|
|
36
|
+
observer.on_next(s)
|
|
37
|
+
s = set()
|
|
38
|
+
observer.on_completed()
|
|
31
39
|
|
|
32
|
-
return
|
|
40
|
+
return source.subscribe(
|
|
41
|
+
s.add, observer.on_error, on_completed, scheduler=scheduler
|
|
42
|
+
)
|
|
33
43
|
|
|
34
|
-
return
|
|
44
|
+
return Observable(subscribe)
|
|
35
45
|
|
|
36
46
|
|
|
37
47
|
__all__ = ["to_set_"]
|
reactivex/operators/_whiledo.py
CHANGED
reactivex/operators/_window.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from
|
|
2
|
+
from collections.abc import Callable
|
|
3
|
+
from typing import Any, TypeVar
|
|
3
4
|
|
|
4
5
|
from reactivex import Observable, abc, empty
|
|
5
6
|
from reactivex import operators as ops
|
|
@@ -9,7 +10,7 @@ from reactivex.disposable import (
|
|
|
9
10
|
SerialDisposable,
|
|
10
11
|
SingleAssignmentDisposable,
|
|
11
12
|
)
|
|
12
|
-
from reactivex.internal import add_ref, noop
|
|
13
|
+
from reactivex.internal import add_ref, curry_flip, noop
|
|
13
14
|
from reactivex.subject import Subject
|
|
14
15
|
|
|
15
16
|
log = logging.getLogger("Rx")
|
|
@@ -17,161 +18,161 @@ log = logging.getLogger("Rx")
|
|
|
17
18
|
_T = TypeVar("_T")
|
|
18
19
|
|
|
19
20
|
|
|
21
|
+
@curry_flip
|
|
20
22
|
def window_toggle_(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
source: Observable[_T],
|
|
24
|
+
openings: Observable[Any],
|
|
25
|
+
closing_mapper: Callable[[Any], Observable[Any]],
|
|
26
|
+
) -> Observable[Observable[_T]]:
|
|
23
27
|
"""Projects each element of an observable sequence into zero or
|
|
24
28
|
more windows.
|
|
25
29
|
|
|
26
30
|
Args:
|
|
27
31
|
source: Source observable to project into windows.
|
|
32
|
+
openings: Observable that triggers window opening.
|
|
33
|
+
closing_mapper: Function to create closing observable.
|
|
28
34
|
|
|
29
35
|
Returns:
|
|
30
36
|
An observable sequence of windows.
|
|
31
37
|
"""
|
|
32
38
|
|
|
33
|
-
def
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return window
|
|
37
|
-
|
|
38
|
-
return openings.pipe(
|
|
39
|
-
ops.group_join(
|
|
40
|
-
source,
|
|
41
|
-
closing_mapper,
|
|
42
|
-
lambda _: empty(),
|
|
43
|
-
),
|
|
44
|
-
ops.map(mapper),
|
|
45
|
-
)
|
|
39
|
+
def mapper(args: tuple[Any, Observable[_T]]):
|
|
40
|
+
_, window = args
|
|
41
|
+
return window
|
|
46
42
|
|
|
47
|
-
return
|
|
43
|
+
return openings.pipe(
|
|
44
|
+
ops.group_join(
|
|
45
|
+
source,
|
|
46
|
+
closing_mapper,
|
|
47
|
+
lambda _: empty(),
|
|
48
|
+
),
|
|
49
|
+
ops.map(mapper),
|
|
50
|
+
)
|
|
48
51
|
|
|
49
52
|
|
|
53
|
+
@curry_flip
|
|
50
54
|
def window_(
|
|
55
|
+
source: Observable[_T],
|
|
51
56
|
boundaries: Observable[Any],
|
|
52
|
-
) ->
|
|
57
|
+
) -> Observable[Observable[_T]]:
|
|
53
58
|
"""Projects each element of an observable sequence into zero or
|
|
54
59
|
more windows.
|
|
55
60
|
|
|
56
61
|
Args:
|
|
57
62
|
source: Source observable to project into windows.
|
|
63
|
+
boundaries: Observable that triggers window boundaries.
|
|
58
64
|
|
|
59
65
|
Returns:
|
|
60
66
|
An observable sequence of windows.
|
|
61
67
|
"""
|
|
62
68
|
|
|
63
|
-
def
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
r = RefCountDisposable(d)
|
|
69
|
+
def subscribe(
|
|
70
|
+
observer: abc.ObserverBase[Observable[_T]],
|
|
71
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
72
|
+
) -> abc.DisposableBase:
|
|
73
|
+
window_subject: Subject[_T] = Subject()
|
|
74
|
+
d = CompositeDisposable()
|
|
75
|
+
r = RefCountDisposable(d)
|
|
71
76
|
|
|
72
|
-
|
|
77
|
+
observer.on_next(add_ref(window_subject, r))
|
|
73
78
|
|
|
74
|
-
|
|
75
|
-
|
|
79
|
+
def on_next_window(x: _T) -> None:
|
|
80
|
+
window_subject.on_next(x)
|
|
76
81
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
def on_error(err: Exception) -> None:
|
|
83
|
+
window_subject.on_error(err)
|
|
84
|
+
observer.on_error(err)
|
|
80
85
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
86
|
+
def on_completed() -> None:
|
|
87
|
+
window_subject.on_completed()
|
|
88
|
+
observer.on_completed()
|
|
84
89
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
)
|
|
90
|
+
d.add(
|
|
91
|
+
source.subscribe(
|
|
92
|
+
on_next_window, on_error, on_completed, scheduler=scheduler
|
|
89
93
|
)
|
|
94
|
+
)
|
|
90
95
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
+
def on_next_observer(w: Observable[_T]):
|
|
97
|
+
nonlocal window_subject
|
|
98
|
+
window_subject.on_completed()
|
|
99
|
+
window_subject = Subject()
|
|
100
|
+
observer.on_next(add_ref(window_subject, r))
|
|
96
101
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
)
|
|
102
|
+
d.add(
|
|
103
|
+
boundaries.subscribe(
|
|
104
|
+
on_next_observer, on_error, on_completed, scheduler=scheduler
|
|
101
105
|
)
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return Observable(subscribe)
|
|
106
|
+
)
|
|
107
|
+
return r
|
|
105
108
|
|
|
106
|
-
return
|
|
109
|
+
return Observable(subscribe)
|
|
107
110
|
|
|
108
111
|
|
|
112
|
+
@curry_flip
|
|
109
113
|
def window_when_(
|
|
110
|
-
|
|
111
|
-
|
|
114
|
+
source: Observable[_T],
|
|
115
|
+
closing_mapper: Callable[[], Observable[Any]],
|
|
116
|
+
) -> Observable[Observable[_T]]:
|
|
112
117
|
"""Projects each element of an observable sequence into zero or
|
|
113
118
|
more windows.
|
|
114
119
|
|
|
115
120
|
Args:
|
|
116
121
|
source: Source observable to project into windows.
|
|
122
|
+
closing_mapper: Function that returns an observable signaling window close.
|
|
117
123
|
|
|
118
124
|
Returns:
|
|
119
125
|
An observable sequence of windows.
|
|
120
126
|
"""
|
|
121
127
|
|
|
122
|
-
def
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
)
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
window: Subject[_T] = Subject()
|
|
128
|
+
def subscribe(
|
|
129
|
+
observer: abc.ObserverBase[Observable[_T]],
|
|
130
|
+
scheduler: abc.SchedulerBase | None = None,
|
|
131
|
+
):
|
|
132
|
+
m = SerialDisposable()
|
|
133
|
+
d = CompositeDisposable(m)
|
|
134
|
+
r = RefCountDisposable(d)
|
|
135
|
+
window: Subject[_T] = Subject()
|
|
131
136
|
|
|
132
|
-
|
|
137
|
+
observer.on_next(add_ref(window, r))
|
|
133
138
|
|
|
134
|
-
|
|
135
|
-
|
|
139
|
+
def on_next(value: _T) -> None:
|
|
140
|
+
window.on_next(value)
|
|
136
141
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
142
|
+
def on_error(error: Exception) -> None:
|
|
143
|
+
window.on_error(error)
|
|
144
|
+
observer.on_error(error)
|
|
140
145
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
d.add(
|
|
146
|
-
source.subscribe(on_next, on_error, on_completed, scheduler=scheduler)
|
|
147
|
-
)
|
|
146
|
+
def on_completed() -> None:
|
|
147
|
+
window.on_completed()
|
|
148
|
+
observer.on_completed()
|
|
148
149
|
|
|
149
|
-
|
|
150
|
-
try:
|
|
151
|
-
window_close = closing_mapper()
|
|
152
|
-
except Exception as exception:
|
|
153
|
-
observer.on_error(exception)
|
|
154
|
-
return
|
|
150
|
+
d.add(source.subscribe(on_next, on_error, on_completed, scheduler=scheduler))
|
|
155
151
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
152
|
+
def create_window_on_completed():
|
|
153
|
+
try:
|
|
154
|
+
window_close = closing_mapper()
|
|
155
|
+
except Exception as exception:
|
|
156
|
+
observer.on_error(exception)
|
|
157
|
+
return
|
|
162
158
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
)
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
159
|
+
def on_completed():
|
|
160
|
+
nonlocal window
|
|
161
|
+
window.on_completed()
|
|
162
|
+
window = Subject()
|
|
163
|
+
observer.on_next(add_ref(window, r))
|
|
164
|
+
create_window_on_completed()
|
|
165
|
+
|
|
166
|
+
m1 = SingleAssignmentDisposable()
|
|
167
|
+
m.disposable = m1
|
|
168
|
+
m1.disposable = window_close.pipe(ops.take(1)).subscribe(
|
|
169
|
+
noop, on_error, on_completed, scheduler=scheduler
|
|
170
|
+
)
|
|
171
171
|
|
|
172
|
-
|
|
172
|
+
create_window_on_completed()
|
|
173
|
+
return r
|
|
173
174
|
|
|
174
|
-
return
|
|
175
|
+
return Observable(subscribe)
|
|
175
176
|
|
|
176
177
|
|
|
177
178
|
__all__ = ["window_", "window_when_", "window_toggle_"]
|