1340 lines
39 KiB
Python
1340 lines
39 KiB
Python
# pylint: disable=too-many-lines,redefined-outer-name,redefined-builtin
|
|
|
|
from asyncio import Future
|
|
from typing import (
|
|
Any,
|
|
Callable,
|
|
Iterable,
|
|
Mapping,
|
|
Optional,
|
|
Tuple,
|
|
TypeVar,
|
|
Union,
|
|
overload,
|
|
)
|
|
|
|
from . import abc, typing
|
|
from ._version import __version__
|
|
from .internal.utils import alias
|
|
from .notification import Notification
|
|
from .observable import ConnectableObservable, GroupedObservable, Observable
|
|
from .observer import Observer
|
|
from .pipe import compose, pipe
|
|
from .subject import Subject
|
|
|
|
_T = TypeVar("_T")
|
|
_T1 = TypeVar("_T1")
|
|
_T2 = TypeVar("_T2")
|
|
_TKey = TypeVar("_TKey")
|
|
_TState = TypeVar("_TState")
|
|
|
|
_A = TypeVar("_A")
|
|
_B = TypeVar("_B")
|
|
_C = TypeVar("_C")
|
|
_D = TypeVar("_D")
|
|
_E = TypeVar("_E")
|
|
_F = TypeVar("_F")
|
|
_G = TypeVar("_G")
|
|
|
|
|
|
def amb(*sources: Observable[_T]) -> Observable[_T]:
|
|
"""Propagates the observable sequence that emits first.
|
|
|
|
.. marble::
|
|
:alt: amb
|
|
|
|
---8--6--9-----------|
|
|
--1--2--3---5--------|
|
|
----------10-20-30---|
|
|
[ amb() ]
|
|
--1--2--3---5--------|
|
|
|
|
Example:
|
|
>>> winner = reactivex.amb(xs, ys, zs)
|
|
|
|
Args:
|
|
sources: Sequence of observables to monitor for first emission.
|
|
|
|
Returns:
|
|
An observable sequence that surfaces any of the given sequences,
|
|
whichever emitted the first element.
|
|
"""
|
|
|
|
from .observable.amb import amb_ as amb_
|
|
|
|
return amb_(*sources)
|
|
|
|
|
|
def case(
|
|
mapper: Callable[[], _TKey],
|
|
sources: Mapping[_TKey, Observable[_T]],
|
|
default_source: Optional[Union[Observable[_T], "Future[_T]"]] = None,
|
|
) -> Observable[_T]:
|
|
"""Uses mapper to determine which source in sources to use.
|
|
|
|
.. marble::
|
|
:alt: case
|
|
|
|
--1---------------|
|
|
a--1--2--3--4--|
|
|
b--10-20-30---|
|
|
[case(mapper, { 1: a, 2: b })]
|
|
---1--2--3--4--|
|
|
|
|
Examples:
|
|
>>> res = reactivex.case(mapper, { '1': obs1, '2': obs2 })
|
|
>>> res = reactivex.case(mapper, { '1': obs1, '2': obs2 }, obs0)
|
|
|
|
Args:
|
|
mapper: The function which extracts the value for to test in a
|
|
case statement.
|
|
sources: An object which has keys which correspond to the case
|
|
statement labels.
|
|
default_source: [Optional] The observable sequence or Future that will
|
|
be run if the sources are not matched. If this is not provided,
|
|
it defaults to :func:`empty`.
|
|
|
|
Returns:
|
|
An observable sequence which is determined by a case statement.
|
|
"""
|
|
|
|
from .observable.case import case_
|
|
|
|
return case_(mapper, sources, default_source)
|
|
|
|
|
|
def catch(*sources: Observable[_T]) -> Observable[_T]:
|
|
"""Continues observable sequences which are terminated with an
|
|
exception by switching over to the next observable sequence.
|
|
|
|
.. marble::
|
|
:alt: catch
|
|
|
|
---1---2---3-*
|
|
a-7-8-|
|
|
[ catch(a) ]
|
|
---1---2---3---7-8-|
|
|
|
|
Examples:
|
|
>>> res = reactivex.catch(xs, ys, zs)
|
|
|
|
Args:
|
|
sources: Sequence of observables.
|
|
|
|
Returns:
|
|
An observable sequence containing elements from consecutive observables
|
|
from the sequence of sources until one of them terminates successfully.
|
|
"""
|
|
|
|
from .observable.catch import catch_with_iterable_
|
|
|
|
return catch_with_iterable_(sources)
|
|
|
|
|
|
def catch_with_iterable(sources: Iterable[Observable[_T]]) -> Observable[_T]:
|
|
"""Continues observable sequences that are terminated with an
|
|
exception by switching over to the next observable sequence.
|
|
|
|
.. marble::
|
|
:alt: catch
|
|
|
|
---1---2---3-*
|
|
a-7-8-|
|
|
[ catch(a) ]
|
|
---1---2---3---7-8-|
|
|
|
|
Examples:
|
|
>>> res = reactivex.catch([xs, ys, zs])
|
|
>>> res = reactivex.catch(src for src in [xs, ys, zs])
|
|
|
|
Args:
|
|
sources: An Iterable of observables; thus, a generator can also
|
|
be used here.
|
|
|
|
Returns:
|
|
An observable sequence containing elements from consecutive observables
|
|
from the sequence of sources until one of them terminates successfully.
|
|
"""
|
|
|
|
from .observable.catch import catch_with_iterable_
|
|
|
|
return catch_with_iterable_(sources)
|
|
|
|
|
|
def create(subscribe: typing.Subscription[_T]) -> Observable[_T]:
|
|
"""Creates an observable sequence object from the specified
|
|
subscription function.
|
|
|
|
.. marble::
|
|
:alt: create
|
|
|
|
[ create(a) ]
|
|
---1---2---3---4---|
|
|
|
|
Args:
|
|
subscribe: Subscription function.
|
|
|
|
Returns:
|
|
An observable sequence that can be subscribed to via the given
|
|
subscription function.
|
|
"""
|
|
|
|
return Observable(subscribe)
|
|
|
|
|
|
@overload
|
|
def combine_latest(
|
|
__a: Observable[_A], __b: Observable[_B]
|
|
) -> Observable[Tuple[_A, _B]]:
|
|
...
|
|
|
|
|
|
@overload
|
|
def combine_latest(
|
|
__a: Observable[_A], __b: Observable[_B], __c: Observable[_C]
|
|
) -> Observable[Tuple[_A, _B, _C]]:
|
|
...
|
|
|
|
|
|
@overload
|
|
def combine_latest(
|
|
__a: Observable[_A], __b: Observable[_B], __c: Observable[_C], __d: Observable[_D]
|
|
) -> Observable[Tuple[_A, _B, _C, _D]]:
|
|
...
|
|
|
|
|
|
def combine_latest(*__sources: Observable[Any]) -> Observable[Any]:
|
|
"""Merges the specified observable sequences into one observable
|
|
sequence by creating a tuple whenever any of the observable
|
|
sequences emits an element.
|
|
|
|
.. marble::
|
|
:alt: combine_latest
|
|
|
|
---a-----b--c------|
|
|
--1---2--------3---|
|
|
[ combine_latest() ]
|
|
---a1-a2-b2-c2-c3--|
|
|
|
|
Examples:
|
|
>>> obs = rx.combine_latest(obs1, obs2, obs3)
|
|
|
|
Args:
|
|
sources: Sequence of observables.
|
|
|
|
Returns:
|
|
An observable sequence containing the result of combining elements from
|
|
each source in given sequence.
|
|
"""
|
|
|
|
from .observable.combinelatest import combine_latest_
|
|
|
|
return combine_latest_(*__sources)
|
|
|
|
|
|
def concat(*sources: Observable[_T]) -> Observable[_T]:
|
|
"""Concatenates all of the specified observable sequences.
|
|
|
|
.. marble::
|
|
:alt: concat
|
|
|
|
---1--2--3--|
|
|
--6--8--|
|
|
[ concat() ]
|
|
---1--2--3----6--8-|
|
|
|
|
Examples:
|
|
>>> res = reactivex.concat(xs, ys, zs)
|
|
|
|
Args:
|
|
sources: Sequence of observables.
|
|
|
|
Returns:
|
|
An observable sequence that contains the elements of each source in
|
|
the given sequence, in sequential order.
|
|
"""
|
|
|
|
from .observable.concat import concat_with_iterable_
|
|
|
|
return concat_with_iterable_(sources)
|
|
|
|
|
|
def concat_with_iterable(sources: Iterable[Observable[_T]]) -> Observable[_T]:
|
|
"""Concatenates all of the specified observable sequences.
|
|
|
|
.. marble::
|
|
:alt: concat
|
|
|
|
---1--2--3--|
|
|
--6--8--|
|
|
[ concat() ]
|
|
---1--2--3----6--8-|
|
|
|
|
Examples:
|
|
>>> res = reactivex.concat_with_iterable([xs, ys, zs])
|
|
>>> res = reactivex.concat_with_iterable(for src in [xs, ys, zs])
|
|
|
|
Args:
|
|
sources: An Iterable of observables; thus, a generator can also
|
|
be used here.
|
|
|
|
Returns:
|
|
An observable sequence that contains the elements of each given
|
|
sequence, in sequential order.
|
|
"""
|
|
|
|
from .observable.concat import concat_with_iterable_
|
|
|
|
return concat_with_iterable_(sources)
|
|
|
|
|
|
def defer(
|
|
factory: Callable[[abc.SchedulerBase], Union[Observable[_T], "Future[_T]"]]
|
|
) -> Observable[_T]:
|
|
"""Returns an observable sequence that invokes the specified
|
|
factory function whenever a new observer subscribes.
|
|
|
|
.. marble::
|
|
:alt: defer
|
|
|
|
[ defer(1,2,3) ]
|
|
---1--2--3--|
|
|
---1--2--3--|
|
|
|
|
Example:
|
|
>>> res = reactivex.defer(lambda scheduler: of(1, 2, 3))
|
|
|
|
Args:
|
|
factory: Observable factory function to invoke for each observer
|
|
which invokes :func:`subscribe()
|
|
<reactivex.Observable.subscribe>` on the resulting sequence.
|
|
The factory takes a single argument, the scheduler used.
|
|
|
|
Returns:
|
|
An observable sequence whose observers trigger an invocation
|
|
of the given factory function.
|
|
"""
|
|
|
|
from .observable.defer import defer_
|
|
|
|
return defer_(factory)
|
|
|
|
|
|
def empty(scheduler: Optional[abc.SchedulerBase] = None) -> Observable[Any]:
|
|
"""Returns an empty observable sequence.
|
|
|
|
.. marble::
|
|
:alt: empty
|
|
|
|
[ empty() ]
|
|
--|
|
|
|
|
Example:
|
|
>>> obs = reactivex.empty()
|
|
|
|
Args:
|
|
scheduler: [Optional] Scheduler instance to send the termination call
|
|
on. By default, this will use an instance of
|
|
:class:`ImmediateScheduler <reactivex.scheduler.ImmediateScheduler>`.
|
|
|
|
Returns:
|
|
An observable sequence with no elements.
|
|
"""
|
|
|
|
from .observable.empty import empty_
|
|
|
|
return empty_(scheduler)
|
|
|
|
|
|
def for_in(
|
|
values: Iterable[_T1], mapper: typing.Mapper[_T1, Observable[_T2]]
|
|
) -> Observable[_T2]:
|
|
"""Concatenates the observable sequences obtained by running the
|
|
specified result mapper for each element in the specified values.
|
|
|
|
.. marble::
|
|
:alt: for_in
|
|
|
|
a--1--2-|
|
|
b--10--20-|
|
|
[for_in((a, b), lambda i: i+1)]
|
|
---2--3--11--21-|
|
|
|
|
|
|
Note:
|
|
This is just a wrapper for
|
|
:func:`reactivex.concat(map(mapper, values)) <reactivex.concat>`
|
|
|
|
Args:
|
|
values: An Iterable of values to turn into an observable
|
|
source.
|
|
mapper: A function to apply to each item in the values list to turn
|
|
it into an observable sequence; this should return instances of
|
|
:class:`reactivex.Observable`.
|
|
|
|
Returns:
|
|
An observable sequence from the concatenated observable
|
|
sequences.
|
|
"""
|
|
|
|
mapped: Iterable[Observable[_T2]] = map(mapper, values)
|
|
return concat_with_iterable(mapped)
|
|
|
|
|
|
@overload
|
|
def fork_join(__a: Observable[_A], __b: Observable[_B]) -> Observable[Tuple[_A, _B]]:
|
|
...
|
|
|
|
|
|
@overload
|
|
def fork_join(
|
|
__a: Observable[_A], __b: Observable[_B], __c: Observable[_C]
|
|
) -> Observable[Tuple[_A, _B, _C]]:
|
|
...
|
|
|
|
|
|
@overload
|
|
def fork_join(
|
|
__a: Observable[_A], __b: Observable[_B], __c: Observable[_C], __d: Observable[_D]
|
|
) -> Observable[Tuple[_A, _B, _C, _D]]:
|
|
...
|
|
|
|
|
|
@overload
|
|
def fork_join(
|
|
__a: Observable[_A],
|
|
__b: Observable[_B],
|
|
__c: Observable[_C],
|
|
__d: Observable[_D],
|
|
__e: Observable[_E],
|
|
) -> Observable[Tuple[_A, _B, _C, _D, _E]]:
|
|
...
|
|
|
|
|
|
def fork_join(*sources: Observable[Any]) -> Observable[Any]:
|
|
"""Wait for observables to complete and then combine last values
|
|
they emitted into a tuple. Whenever any of that observables completes
|
|
without emitting any value, result sequence will complete at that moment as well.
|
|
|
|
.. marble::
|
|
:alt: fork_join
|
|
|
|
---a-----b--c---d-|
|
|
--1---2------3-4---|
|
|
-a---------b---|
|
|
[ fork_join() ]
|
|
--------------------d4b|
|
|
|
|
Examples:
|
|
>>> obs = reactivex.fork_join(obs1, obs2, obs3)
|
|
|
|
Args:
|
|
sources: Sequence of observables.
|
|
|
|
Returns:
|
|
An observable sequence containing the result of combining last element from
|
|
each source in given sequence.
|
|
"""
|
|
|
|
from .observable.forkjoin import fork_join_
|
|
|
|
return fork_join_(*sources)
|
|
|
|
|
|
def from_callable(
|
|
supplier: Callable[[], _T], scheduler: Optional[abc.SchedulerBase] = None
|
|
) -> Observable[_T]:
|
|
"""Returns an observable sequence that contains a single element generated
|
|
by the given supplier, using the specified scheduler to send out observer
|
|
messages.
|
|
|
|
.. marble::
|
|
:alt: from_callable
|
|
|
|
[ from_callable() ]
|
|
--1--|
|
|
|
|
Examples:
|
|
>>> res = reactivex.from_callable(lambda: calculate_value())
|
|
>>> res = reactivex.from_callable(lambda: 1 / 0) # emits an error
|
|
|
|
Args:
|
|
supplier: Function which is invoked to obtain the single element.
|
|
scheduler: [Optional] Scheduler instance to schedule the values on.
|
|
If not specified, the default is to use an instance of
|
|
:class:`CurrentThreadScheduler
|
|
<reactivex.scheduler.CurrentThreadScheduler>`.
|
|
|
|
Returns:
|
|
An observable sequence containing the single element obtained by
|
|
invoking the given supplier function.
|
|
"""
|
|
|
|
from .observable.returnvalue import from_callable_
|
|
|
|
return from_callable_(supplier, scheduler)
|
|
|
|
|
|
def from_callback(
|
|
func: Callable[..., Callable[..., None]],
|
|
mapper: Optional[typing.Mapper[Any, Any]] = None,
|
|
) -> Callable[[], Observable[Any]]:
|
|
"""Converts a callback function to an observable sequence.
|
|
|
|
Args:
|
|
func: Function with a callback as the last argument to
|
|
convert to an Observable sequence.
|
|
mapper: [Optional] A mapper which takes the arguments
|
|
from the callback to produce a single item to yield on
|
|
next.
|
|
|
|
Returns:
|
|
A function, when executed with the required arguments minus
|
|
the callback, produces an Observable sequence with a single
|
|
value of the arguments to the callback as a list.
|
|
"""
|
|
from .observable.fromcallback import from_callback_
|
|
|
|
return from_callback_(func, mapper)
|
|
|
|
|
|
def from_future(future: "Future[_T]") -> Observable[_T]:
|
|
"""Converts a Future to an Observable sequence
|
|
|
|
.. marble::
|
|
:alt: from_future
|
|
|
|
[ from_future() ]
|
|
------1|
|
|
|
|
Args:
|
|
future: A Python 3 compatible future.
|
|
https://docs.python.org/3/library/asyncio-task.html#future
|
|
|
|
Returns:
|
|
An observable sequence which wraps the existing future success
|
|
and failure.
|
|
"""
|
|
from .observable.fromfuture import from_future_
|
|
|
|
return from_future_(future)
|
|
|
|
|
|
def from_iterable(
|
|
iterable: Iterable[_T], scheduler: Optional[abc.SchedulerBase] = None
|
|
) -> Observable[_T]:
|
|
"""Converts an iterable to an observable sequence.
|
|
|
|
.. marble::
|
|
:alt: from_iterable
|
|
|
|
[ from_iterable(1,2,3) ]
|
|
---1--2--3--|
|
|
|
|
|
|
Example:
|
|
>>> reactivex.from_iterable([1,2,3])
|
|
|
|
Args:
|
|
iterable: An Iterable to change into an observable sequence.
|
|
scheduler: [Optional] Scheduler instance to schedule the values on.
|
|
If not specified, the default is to use an instance of
|
|
:class:`CurrentThreadScheduler
|
|
<reactivex.scheduler.CurrentThreadScheduler>`.
|
|
|
|
Returns:
|
|
The observable sequence whose elements are pulled from the
|
|
given iterable sequence.
|
|
"""
|
|
from .observable.fromiterable import from_iterable_ as from_iterable_
|
|
|
|
return from_iterable_(iterable, scheduler)
|
|
|
|
|
|
from_ = alias("from_", "Alias for :func:`reactivex.from_iterable`.", from_iterable)
|
|
from_list = alias(
|
|
"from_list", "Alias for :func:`reactivex.from_iterable`.", from_iterable
|
|
)
|
|
|
|
|
|
def from_marbles(
|
|
string: str,
|
|
timespan: typing.RelativeTime = 0.1,
|
|
scheduler: Optional[abc.SchedulerBase] = None,
|
|
lookup: Optional[Mapping[Union[str, float], Any]] = None,
|
|
error: Optional[Exception] = None,
|
|
) -> Observable[Any]:
|
|
"""Convert a marble diagram string to a cold observable sequence, using
|
|
an optional scheduler to enumerate the events.
|
|
|
|
.. marble::
|
|
:alt: from_marbles
|
|
|
|
[ from_marbles(-1-2-3-) ]
|
|
-1-2-3-|
|
|
|
|
Each character in the string will advance time by timespan
|
|
(except for space). Characters that are not special (see the table below)
|
|
will be interpreted as a value to be emitted. Numbers will be cast
|
|
to int or float.
|
|
|
|
Special characters:
|
|
+------------+--------------------------------------------------------+
|
|
| :code:`-` | advance time by timespan |
|
|
+------------+--------------------------------------------------------+
|
|
| :code:`#` | on_error() |
|
|
+------------+--------------------------------------------------------+
|
|
| :code:`|` | on_completed() |
|
|
+------------+--------------------------------------------------------+
|
|
| :code:`(` | open a group of marbles sharing the same timestamp |
|
|
+------------+--------------------------------------------------------+
|
|
| :code:`)` | close a group of marbles |
|
|
+------------+--------------------------------------------------------+
|
|
| :code:`,` | separate elements in a group |
|
|
+------------+--------------------------------------------------------+
|
|
| <space> | used to align multiple diagrams, does not advance time |
|
|
+------------+--------------------------------------------------------+
|
|
|
|
In a group of elements, the position of the initial :code:`(` determines the
|
|
timestamp at which grouped elements will be emitted.
|
|
E.g. :code:`--(12,3,4)--` will emit 12, 3, 4 at 2 * timespan and then
|
|
advance virtual time by 8 * timespan.
|
|
|
|
Examples:
|
|
>>> from_marbles('--1--(2,3)-4--|')
|
|
>>> from_marbles('a--b--c-', lookup={'a': 1, 'b': 2, 'c': 3})
|
|
>>> from_marbles('a--b---#', error=ValueError('foo'))
|
|
|
|
Args:
|
|
string: String with marble diagram
|
|
timespan: [Optional] Duration of each character in seconds.
|
|
If not specified, defaults to :code:`0.1`.
|
|
scheduler: [Optional] Scheduler to run the the input sequence
|
|
on. If not specified, defaults to the subscribe scheduler
|
|
if defined, else to an instance of
|
|
:class:`NewThreadScheduler <reactivex.scheduler.NewThreadScheduler`.
|
|
lookup: [Optional] A dict used to convert an element into a specified
|
|
value. If not specified, defaults to :code:`{}`.
|
|
error: [Optional] Exception that will be use in place of the :code:`#`
|
|
symbol. If not specified, defaults to :code:`Exception('error')`.
|
|
|
|
Returns:
|
|
The observable sequence whose elements are pulled from the
|
|
given marble diagram string.
|
|
"""
|
|
|
|
from .observable.marbles import from_marbles as _from_marbles
|
|
|
|
return _from_marbles(
|
|
string, timespan, lookup=lookup, error=error, scheduler=scheduler
|
|
)
|
|
|
|
|
|
cold = alias("cold", "Alias for :func:`reactivex.from_marbles`.", from_marbles)
|
|
|
|
|
|
def generate_with_relative_time(
|
|
initial_state: _TState,
|
|
condition: typing.Predicate[_TState],
|
|
iterate: typing.Mapper[_TState, _TState],
|
|
time_mapper: Callable[[_TState], typing.RelativeTime],
|
|
) -> Observable[_TState]:
|
|
"""Generates an observable sequence by iterating a state from an
|
|
initial state until the condition fails.
|
|
|
|
.. marble::
|
|
:alt: generate_with_relative_time
|
|
|
|
[generate_with_relative_time()]
|
|
-1-2-3-4-|
|
|
|
|
Example:
|
|
>>> res = reactivex.generate_with_relative_time(
|
|
0, lambda x: True, lambda x: x + 1, lambda x: 0.5
|
|
)
|
|
|
|
Args:
|
|
initial_state: Initial state.
|
|
condition: Condition to terminate generation (upon returning
|
|
:code:`False`).
|
|
iterate: Iteration step function.
|
|
time_mapper: Time mapper function to control the speed of
|
|
values being produced each iteration, returning relative times, i.e.
|
|
either a :class:`float` denoting seconds, or an instance of
|
|
:class:`timedelta`.
|
|
|
|
Returns:
|
|
The generated sequence.
|
|
"""
|
|
from .observable.generatewithrelativetime import generate_with_relative_time_
|
|
|
|
return generate_with_relative_time_(initial_state, condition, iterate, time_mapper)
|
|
|
|
|
|
def generate(
|
|
initial_state: _TState,
|
|
condition: typing.Predicate[_TState],
|
|
iterate: typing.Mapper[_TState, _TState],
|
|
) -> Observable[_TState]:
|
|
"""Generates an observable sequence by running a state-driven loop
|
|
producing the sequence's elements.
|
|
|
|
.. marble::
|
|
:alt: generate
|
|
|
|
[ generate() ]
|
|
-1-2-3-4-|
|
|
|
|
Example:
|
|
>>> res = reactivex.generate(0, lambda x: x < 10, lambda x: x + 1)
|
|
|
|
Args:
|
|
initial_state: Initial state.
|
|
condition: Condition to terminate generation (upon returning
|
|
:code:`False`).
|
|
iterate: Iteration step function.
|
|
|
|
Returns:
|
|
The generated sequence.
|
|
"""
|
|
from .observable.generate import generate_
|
|
|
|
return generate_(initial_state, condition, iterate)
|
|
|
|
|
|
def hot(
|
|
string: str,
|
|
timespan: typing.RelativeTime = 0.1,
|
|
duetime: typing.AbsoluteOrRelativeTime = 0.0,
|
|
scheduler: Optional[abc.SchedulerBase] = None,
|
|
lookup: Optional[Mapping[Union[str, float], Any]] = None,
|
|
error: Optional[Exception] = None,
|
|
) -> Observable[Any]:
|
|
"""Convert a marble diagram string to a hot observable sequence, using
|
|
an optional scheduler to enumerate the events.
|
|
|
|
.. marble::
|
|
:alt: hot
|
|
|
|
[ from_marbles(-1-2-3-) ]
|
|
-1-2-3-|
|
|
-2-3-|
|
|
|
|
Each character in the string will advance time by timespan
|
|
(except for space). Characters that are not special (see the table below)
|
|
will be interpreted as a value to be emitted. Numbers will be cast
|
|
to int or float.
|
|
|
|
Special characters:
|
|
+------------+--------------------------------------------------------+
|
|
| :code:`-` | advance time by timespan |
|
|
+------------+--------------------------------------------------------+
|
|
| :code:`#` | on_error() |
|
|
+------------+--------------------------------------------------------+
|
|
| :code:`|` | on_completed() |
|
|
+------------+--------------------------------------------------------+
|
|
| :code:`(` | open a group of elements sharing the same timestamp |
|
|
+------------+--------------------------------------------------------+
|
|
| :code:`)` | close a group of elements |
|
|
+------------+--------------------------------------------------------+
|
|
| :code:`,` | separate elements in a group |
|
|
+------------+--------------------------------------------------------+
|
|
| <space> | used to align multiple diagrams, does not advance time |
|
|
+------------+--------------------------------------------------------+
|
|
|
|
In a group of elements, the position of the initial :code:`(` determines the
|
|
timestamp at which grouped elements will be emitted.
|
|
E.g. :code:`--(12,3,4)--` will emit 12, 3, 4 at 2 * timespan and then
|
|
advance virtual time by 8 * timespan.
|
|
|
|
Examples:
|
|
>>> hot("--1--(2,3)-4--|")
|
|
>>> hot("a--b--c-", lookup={'a': 1, 'b': 2, 'c': 3})
|
|
>>> hot("a--b---#", error=ValueError("foo"))
|
|
|
|
Args:
|
|
string: String with marble diagram
|
|
timespan: [Optional] Duration of each character in seconds.
|
|
If not specified, defaults to :code:`0.1`.
|
|
duetime: [Optional] Absolute datetime or timedelta from now that
|
|
determines when to start the emission of elements.
|
|
scheduler: [Optional] Scheduler to run the the input sequence
|
|
on. If not specified, defaults to an instance of
|
|
:class:`NewThreadScheduler <reactivex.scheduler.NewThreadScheduler>`.
|
|
lookup: [Optional] A dict used to convert an element into a specified
|
|
value. If not specified, defaults to :code:`{}`.
|
|
error: [Optional] Exception that will be use in place of the :code:`#`
|
|
symbol. If not specified, defaults to :code:`Exception('error')`.
|
|
|
|
Returns:
|
|
The observable sequence whose elements are pulled from the
|
|
given marble diagram string.
|
|
"""
|
|
|
|
from .observable.marbles import hot as _hot
|
|
|
|
return _hot(
|
|
string, timespan, duetime, lookup=lookup, error=error, scheduler=scheduler
|
|
)
|
|
|
|
|
|
def if_then(
|
|
condition: Callable[[], bool],
|
|
then_source: Union[Observable[_T], "Future[_T]"],
|
|
else_source: Union[None, Observable[_T], "Future[_T]"] = None,
|
|
) -> Observable[_T]:
|
|
"""Determines whether an observable collection contains values.
|
|
|
|
.. marble::
|
|
:alt: if_then
|
|
|
|
---1--2--3--|
|
|
--6--8--|
|
|
[ if_then() ]
|
|
---1--2--3--|
|
|
|
|
|
|
Examples:
|
|
>>> res = reactivex.if_then(condition, obs1)
|
|
>>> res = reactivex.if_then(condition, obs1, obs2)
|
|
|
|
Args:
|
|
condition: The condition which determines if the then_source or
|
|
else_source will be run.
|
|
then_source: The observable sequence or :class:`Future` that
|
|
will be run if the condition function returns :code:`True`.
|
|
else_source: [Optional] The observable sequence or :class:`Future`
|
|
that will be run if the condition function returns :code:`False`.
|
|
If this is not provided, it defaults to :func:`empty() <reactivex.empty>`.
|
|
|
|
Returns:
|
|
An observable sequence which is either the then_source or
|
|
else_source.
|
|
"""
|
|
from .observable.ifthen import if_then_
|
|
|
|
return if_then_(condition, then_source, else_source)
|
|
|
|
|
|
def interval(
|
|
period: typing.RelativeTime, scheduler: Optional[abc.SchedulerBase] = None
|
|
) -> Observable[int]:
|
|
"""Returns an observable sequence that produces a value after each period.
|
|
|
|
.. marble::
|
|
:alt: interval
|
|
|
|
[ interval() ]
|
|
---1---2---3---4--->
|
|
|
|
Example:
|
|
>>> res = reactivex.interval(1.0)
|
|
|
|
Args:
|
|
period: Period for producing the values in the resulting sequence
|
|
(specified as a :class:`float` denoting seconds or an instance of
|
|
:class:`timedelta`).
|
|
scheduler: Scheduler to run the interval on. If not specified, an
|
|
instance of :class:`TimeoutScheduler <reactivex.scheduler.TimeoutScheduler>`
|
|
is used.
|
|
|
|
Returns:
|
|
An observable sequence that produces a value after each period.
|
|
"""
|
|
from .observable.interval import interval_
|
|
|
|
return interval_(period, scheduler)
|
|
|
|
|
|
def merge(*sources: Observable[Any]) -> Observable[Any]:
|
|
"""Merges all the observable sequences into a single observable sequence.
|
|
|
|
.. marble::
|
|
:alt: merge
|
|
|
|
---1---2---3---4-|
|
|
-a---b---c---d--|
|
|
[ merge() ]
|
|
-a-1-b-2-c-3-d-4-|
|
|
|
|
Example:
|
|
>>> res = reactivex.merge(obs1, obs2, obs3)
|
|
|
|
Args:
|
|
sources: Sequence of observables.
|
|
|
|
Returns:
|
|
The observable sequence that merges the elements of the
|
|
observable sequences.
|
|
"""
|
|
from .observable.merge import merge_
|
|
|
|
return merge_(*sources)
|
|
|
|
|
|
def never() -> Observable[Any]:
|
|
"""Returns a non-terminating observable sequence, which can be used
|
|
to denote an infinite duration (e.g. when using reactive joins).
|
|
|
|
.. marble::
|
|
:alt: never
|
|
|
|
[ never() ]
|
|
-->
|
|
|
|
Returns:
|
|
An observable sequence whose observers will never get called.
|
|
"""
|
|
from .observable.never import never_
|
|
|
|
return never_()
|
|
|
|
|
|
def of(*args: _T) -> Observable[_T]:
|
|
"""This method creates a new observable sequence whose elements are taken
|
|
from the arguments.
|
|
|
|
.. marble::
|
|
:alt: of
|
|
|
|
[ of(1,2,3) ]
|
|
---1--2--3--|
|
|
|
|
Note:
|
|
This is just a wrapper for
|
|
:func:`reactivex.from_iterable(args) <reactivex.from_iterable>`
|
|
|
|
Example:
|
|
>>> res = reactivex.of(1,2,3)
|
|
|
|
Args:
|
|
args: The variable number elements to emit from the observable.
|
|
|
|
Returns:
|
|
The observable sequence whose elements are pulled from the
|
|
given arguments
|
|
"""
|
|
return from_iterable(args)
|
|
|
|
|
|
def on_error_resume_next(
|
|
*sources: Union[
|
|
Observable[_T], "Future[_T]", Callable[[Optional[Exception]], Observable[_T]]
|
|
]
|
|
) -> Observable[_T]:
|
|
"""Continues an observable sequence that is terminated normally or
|
|
by an exception with the next observable sequence.
|
|
|
|
.. marble::
|
|
:alt: on_error_resume_next
|
|
|
|
--1--2--*
|
|
a--3--4--*
|
|
b--6-|
|
|
[on_error_resume_next(a,b)]
|
|
--1--2----3--4----6-|
|
|
|
|
Examples:
|
|
>>> res = reactivex.on_error_resume_next(xs, ys, zs)
|
|
|
|
Args:
|
|
sources: Sequence of sources, each of which is expected to be an
|
|
instance of either :class:`Observable` or :class:`Future`.
|
|
|
|
Returns:
|
|
An observable sequence that concatenates the source sequences,
|
|
even if a sequence terminates with an exception.
|
|
"""
|
|
from .observable.onerrorresumenext import on_error_resume_next_
|
|
|
|
return on_error_resume_next_(*sources)
|
|
|
|
|
|
def range(
|
|
start: int,
|
|
stop: Optional[int] = None,
|
|
step: Optional[int] = None,
|
|
scheduler: Optional[abc.SchedulerBase] = None,
|
|
) -> Observable[int]:
|
|
"""Generates an observable sequence of integral numbers within a
|
|
specified range, using the specified scheduler to send out observer
|
|
messages.
|
|
|
|
.. marble::
|
|
:alt: range
|
|
|
|
[ range(4) ]
|
|
--0--1--2--3--|
|
|
|
|
Examples:
|
|
>>> res = reactivex.range(10)
|
|
>>> res = reactivex.range(0, 10)
|
|
>>> res = reactivex.range(0, 10, 1)
|
|
|
|
Args:
|
|
start: The value of the first integer in the sequence.
|
|
stop: [Optional] Generate number up to (exclusive) the stop
|
|
value. Default is `sys.maxsize`.
|
|
step: [Optional] The step to be used (default is 1).
|
|
scheduler: [Optional] The scheduler to schedule the values on.
|
|
If not specified, the default is to use an instance of
|
|
:class:`CurrentThreadScheduler
|
|
<reactivex.scheduler.CurrentThreadScheduler>`.
|
|
|
|
Returns:
|
|
An observable sequence that contains a range of sequential
|
|
integral numbers.
|
|
"""
|
|
from .observable.range import range_
|
|
|
|
return range_(start, stop, step, scheduler)
|
|
|
|
|
|
def return_value(
|
|
value: _T, scheduler: Optional[abc.SchedulerBase] = None
|
|
) -> Observable[_T]:
|
|
"""Returns an observable sequence that contains a single element,
|
|
using the specified scheduler to send out observer messages.
|
|
There is an alias called 'just'.
|
|
|
|
.. marble::
|
|
:alt: return_value
|
|
|
|
[ return_value(4) ]
|
|
-4-|
|
|
|
|
Examples:
|
|
>>> res = reactivex.return_value(42)
|
|
>>> res = reactivex.return_value(42, timeout_scheduler)
|
|
|
|
Args:
|
|
value: Single element in the resulting observable sequence.
|
|
|
|
Returns:
|
|
An observable sequence containing the single specified element.
|
|
"""
|
|
from .observable.returnvalue import return_value_
|
|
|
|
return return_value_(value, scheduler)
|
|
|
|
|
|
just = alias("just", "Alias for :func:`reactivex.return_value`.", return_value)
|
|
|
|
|
|
def repeat_value(value: _T, repeat_count: Optional[int] = None) -> Observable[_T]:
|
|
"""Generates an observable sequence that repeats the given element
|
|
the specified number of times.
|
|
|
|
.. marble::
|
|
:alt: repeat_value
|
|
|
|
[ repeat_value(4) ]
|
|
-4-4-4-4->
|
|
|
|
Examples:
|
|
>>> res = reactivex.repeat_value(42)
|
|
>>> res = reactivex.repeat_value(42, 4)
|
|
|
|
Args:
|
|
value: Element to repeat.
|
|
repeat_count: [Optional] Number of times to repeat the element.
|
|
If not specified, repeats indefinitely.
|
|
|
|
Returns:
|
|
An observable sequence that repeats the given element the
|
|
specified number of times.
|
|
"""
|
|
from .observable.repeat import repeat_value_
|
|
|
|
return repeat_value_(value, repeat_count)
|
|
|
|
|
|
def start(
|
|
func: Callable[[], _T], scheduler: Optional[abc.SchedulerBase] = None
|
|
) -> Observable[_T]:
|
|
"""Invokes the specified function asynchronously on the specified
|
|
scheduler, surfacing the result through an observable sequence.
|
|
|
|
.. marble::
|
|
:alt: start
|
|
|
|
[ start(lambda i: return 4) ]
|
|
-4-|
|
|
-4-|
|
|
|
|
Note:
|
|
The function is called immediately, not during the subscription
|
|
of the resulting sequence. Multiple subscriptions to the
|
|
resulting sequence can observe the function's result.
|
|
|
|
Example:
|
|
>>> res = reactivex.start(lambda: pprint('hello'))
|
|
>>> res = reactivex.start(lambda: pprint('hello'), rx.Scheduler.timeout)
|
|
|
|
Args:
|
|
func: Function to run asynchronously.
|
|
scheduler: [Optional] Scheduler to run the function on. If
|
|
not specified, defaults to an instance of
|
|
:class:`TimeoutScheduler <reactivex.scheduler.TimeoutScheduler>`.
|
|
|
|
Returns:
|
|
An observable sequence exposing the function's result value,
|
|
or an exception.
|
|
"""
|
|
from .observable.start import start_
|
|
|
|
return start_(func, scheduler)
|
|
|
|
|
|
def start_async(function_async: Callable[[], "Future[_T]"]) -> Observable[_T]:
|
|
"""Invokes the asynchronous function, surfacing the result through
|
|
an observable sequence.
|
|
|
|
.. marble::
|
|
:alt: start_async
|
|
|
|
[ start_async() ]
|
|
------1|
|
|
|
|
Args:
|
|
function_async: Asynchronous function which returns a :class:`Future`
|
|
to run.
|
|
|
|
Returns:
|
|
An observable sequence exposing the function's result value,
|
|
or an exception.
|
|
"""
|
|
from .observable.startasync import start_async_
|
|
|
|
return start_async_(function_async)
|
|
|
|
|
|
def throw(
|
|
exception: Union[str, Exception], scheduler: Optional[abc.SchedulerBase] = None
|
|
) -> Observable[Any]:
|
|
"""Returns an observable sequence that terminates with an exception,
|
|
using the specified scheduler to send out the single OnError message.
|
|
|
|
.. marble::
|
|
:alt: throw
|
|
|
|
[ throw() ]
|
|
-*
|
|
|
|
Example:
|
|
>>> res = reactivex.throw(Exception('Error'))
|
|
|
|
Args:
|
|
exception: An object used for the sequence's termination.
|
|
scheduler: [Optional] Scheduler to schedule the error notification on.
|
|
If not specified, the default is to use an instance of
|
|
:class:`ImmediateScheduler <reactivex.scheduler.ImmediateScheduler>`.
|
|
|
|
Returns:
|
|
The observable sequence that terminates exceptionally with the
|
|
specified exception object.
|
|
"""
|
|
from .observable.throw import throw_
|
|
|
|
return throw_(exception, scheduler)
|
|
|
|
|
|
def timer(
|
|
duetime: typing.AbsoluteOrRelativeTime,
|
|
period: Optional[typing.RelativeTime] = None,
|
|
scheduler: Optional[abc.SchedulerBase] = None,
|
|
) -> Observable[int]:
|
|
"""Returns an observable sequence that produces a value after
|
|
duetime has elapsed and then after each period.
|
|
|
|
.. marble::
|
|
:alt: timer
|
|
|
|
[ timer(2) ]
|
|
--0-|
|
|
|
|
Examples:
|
|
>>> res = reactivex.timer(datetime(...))
|
|
>>> res = reactivex.timer(datetime(...), 0.1)
|
|
>>> res = reactivex.timer(5.0)
|
|
>>> res = reactivex.timer(5.0, 1.0)
|
|
|
|
Args:
|
|
duetime: Absolute (specified as a datetime object) or relative time
|
|
(specified as a float denoting seconds or an instance of timedelta)
|
|
at which to produce the first value.
|
|
period: [Optional] Period to produce subsequent values (specified as a
|
|
float denoting seconds or an instance of timedelta).
|
|
If not specified, the resulting timer is not recurring.
|
|
scheduler: [Optional] Scheduler to run the timer on. If not specified,
|
|
the default is to use an instance of
|
|
:class:`TimeoutScheduler <reactivex.scheduler.TimeoutScheduler>`.
|
|
|
|
Returns:
|
|
An observable sequence that produces a value after due time has
|
|
elapsed and then each period.
|
|
"""
|
|
from .observable.timer import timer_
|
|
|
|
return timer_(duetime, period, scheduler)
|
|
|
|
|
|
def to_async(
|
|
func: Callable[..., _T], scheduler: Optional[abc.SchedulerBase] = None
|
|
) -> Callable[..., Observable[_T]]:
|
|
"""Converts the function into an asynchronous function. Each
|
|
invocation of the resulting asynchronous function causes an
|
|
invocation of the original synchronous function on the specified
|
|
scheduler.
|
|
|
|
.. marble::
|
|
:alt: to_async
|
|
|
|
[ to_async()() ]
|
|
------1|
|
|
|
|
Examples:
|
|
>>> res = reactivex.to_async(lambda x, y: x + y)(4, 3)
|
|
>>> res = reactivex.to_async(lambda x, y: x + y, Scheduler.timeout)(4, 3)
|
|
>>> res = reactivex.to_async(lambda x: log.debug(x), Scheduler.timeout)('hello')
|
|
|
|
Args:
|
|
func: Function to convert to an asynchronous function.
|
|
scheduler: [Optional] Scheduler to run the function on. If not
|
|
specified, defaults to an instance of
|
|
:class:`TimeoutScheduler <reactivex.scheduler.TimeoutScheduler>`.
|
|
|
|
Returns:
|
|
Asynchronous function.
|
|
"""
|
|
from .observable.toasync import to_async_
|
|
|
|
return to_async_(func, scheduler)
|
|
|
|
|
|
def using(
|
|
resource_factory: Callable[[], abc.DisposableBase],
|
|
observable_factory: Callable[[abc.DisposableBase], Observable[_T]],
|
|
) -> Observable[_T]:
|
|
"""Constructs an observable sequence that depends on a resource
|
|
object, whose lifetime is tied to the resulting observable
|
|
sequence's lifetime.
|
|
|
|
Example:
|
|
>>> res = reactivex.using(lambda: AsyncSubject(), lambda: s: s)
|
|
|
|
Args:
|
|
resource_factory: Factory function to obtain a resource object.
|
|
observable_factory: Factory function to obtain an observable
|
|
sequence that depends on the obtained resource.
|
|
|
|
Returns:
|
|
An observable sequence whose lifetime controls the lifetime
|
|
of the dependent resource object.
|
|
"""
|
|
from .observable.using import using_
|
|
|
|
return using_(resource_factory, observable_factory)
|
|
|
|
|
|
def with_latest_from(*sources: Observable[Any]) -> Observable[Tuple[Any, ...]]:
|
|
"""Merges the specified observable sequences into one observable
|
|
sequence by creating a :class:`tuple` only when the first
|
|
observable sequence produces an element.
|
|
|
|
.. marble::
|
|
:alt: with_latest_from
|
|
|
|
---1---2---3----4-|
|
|
--a-----b----c-d----|
|
|
[with_latest_from() ]
|
|
---1,a-2,a-3,b--4,d-|
|
|
|
|
Examples:
|
|
>>> obs = rx.with_latest_from(obs1)
|
|
>>> obs = rx.with_latest_from([obs1, obs2, obs3])
|
|
|
|
Args:
|
|
sources: Sequence of observables.
|
|
|
|
Returns:
|
|
An observable sequence containing the result of combining
|
|
elements of the sources into a :class:`tuple`.
|
|
"""
|
|
from .observable.withlatestfrom import with_latest_from_
|
|
|
|
return with_latest_from_(*sources)
|
|
|
|
|
|
def zip(*args: Observable[Any]) -> Observable[Tuple[Any, ...]]:
|
|
"""Merges the specified observable sequences into one observable
|
|
sequence by creating a :class:`tuple` whenever all of the
|
|
observable sequences have produced an element at a corresponding
|
|
index.
|
|
|
|
.. marble::
|
|
:alt: zip
|
|
|
|
--1--2---3-----4---|
|
|
-a----b----c-d------|
|
|
[ zip() ]
|
|
--1,a-2,b--3,c-4,d-|
|
|
|
|
Example:
|
|
>>> res = rx.zip(obs1, obs2)
|
|
|
|
Args:
|
|
args: Observable sources to zip.
|
|
|
|
Returns:
|
|
An observable sequence containing the result of combining
|
|
elements of the sources as a :class:`tuple`.
|
|
"""
|
|
from .observable.zip import zip_
|
|
|
|
return zip_(*args)
|
|
|
|
|
|
__all__ = [
|
|
"abc",
|
|
"amb",
|
|
"case",
|
|
"catch",
|
|
"catch_with_iterable",
|
|
"create",
|
|
"combine_latest",
|
|
"compose",
|
|
"concat",
|
|
"concat_with_iterable",
|
|
"ConnectableObservable",
|
|
"defer",
|
|
"empty",
|
|
"fork_join",
|
|
"from_callable",
|
|
"from_callback",
|
|
"from_future",
|
|
"from_iterable",
|
|
"GroupedObservable",
|
|
"never",
|
|
"Notification",
|
|
"on_error_resume_next",
|
|
"of",
|
|
"Observable",
|
|
"Observer",
|
|
"return_value",
|
|
"pipe",
|
|
"range",
|
|
"repeat_value",
|
|
"Subject",
|
|
"start",
|
|
"start_async",
|
|
"throw",
|
|
"timer",
|
|
"typing",
|
|
"to_async",
|
|
"using",
|
|
"with_latest_from",
|
|
"zip",
|
|
"__version__",
|
|
]
|