Example #1
0
    def to_future(source: Observable) -> Future:
        """Converts an existing observable sequence to a Future.

        Example:
            future = rx.return_value(42).pipe(ops.to_future(asyncio.Future))

        Args:
            future_ctor: [Optional] The constructor of the future.

        Returns:
            A future with the last value from the observable sequence.
        """

        has_value = []

        def on_next(value):
            has_value.append(value)

        def on_error(err):
            future.set_exception(err)

        def on_completed():
            if has_value:
                future.set_result(has_value.pop())

        source.subscribe_(on_next, on_error, on_completed)

        # No cancellation can be done
        return future
Example #2
0
    def test_repeat_observable_repeat_count_throws(self):
        scheduler1 = TestScheduler()
        xs = Observable.return_value(1, scheduler1).repeat(3)
        xs.subscribe(lambda x: _raise('ex'))

        with self.assertRaises(RxException):
            scheduler1.start()

        scheduler2 = TestScheduler()
        ys = Observable.throw_exception('ex1', scheduler2).repeat(3)
        ys.subscribe(on_error=lambda ex: _raise('ex2'))

        with self.assertRaises(RxException):
            scheduler2.start()

        scheduler3 = TestScheduler()
        zs = Observable.return_value(1, scheduler3).repeat(100)
        d = zs.subscribe(on_completed=lambda: _raise('ex3'))

        scheduler3.schedule_absolute(10, lambda sc, st: d.dispose())
        scheduler3.start()

        xss = Observable.create(lambda o: _raise('ex4')).repeat(3)
        with self.assertRaises(RxException):
            xss.subscribe()
Example #3
0
    def subscribe(observer):
        try:
            result = observable_factory()
        except Exception as ex:
            return Observable.throw_exception(ex).subscribe(observer)

        result = Observable.from_future(result)
        return result.subscribe(observer)
Example #4
0
    def test_zip_never_never(self):
        scheduler = TestScheduler()
        o1 = Observable.never()
        o2 = Observable.never()

        def create():
            return o1.zip(o2, lambda x, y: x + y)

        results = scheduler.start(create)
        results.messages.assert_equal()
Example #5
0
def mode(source: Observable) -> Observable:
    """
    Returns the most frequently emitted value (or "values" if they have the same number of occurrences).
    The sequence must be finite.
    """
    return source.group_by(lambda v: v) \
        .flat_map(lambda grp: grp.count().map(lambda ct: (grp.key, ct))) \
        .to_sorted_list(lambda t: t[1], reverse=True) \
        .flat_map(lambda l: Observable.from_(l).take_while(lambda t: t[1] == l[0][1])) \
        .map(lambda t: t[0])
Example #6
0
    def test_for_each_index_some_data(self):
        lstX = []
        lstI = []

        def action(x, i):
            lstX.append(x)
            lstI.append(i)

        Observable.range(10, 10).to_blocking().for_each(action)
        assert(lstX == [x for x in range(10, 20)])
        assert(lstI == [x for x in range(10)])
Example #7
0
    def test_for_each_index_return(self):
        lstX = []
        lstI = []

        def action(x, i):
            lstX.append(x)
            lstI.append(i)

        Observable.return_value(42).to_blocking().for_each(action)
        assert(lstX == [42])
        assert(lstI == [0])
Example #8
0
 def create():
     import sys
     sys.setrecursionlimit(1000)
     def predicate(x):
         n[0] += 1
         return n[0] < 1000
     def subscribe(o):
         o.on_next(1)
         o.on_completed()
         return lambda: None
     return Observable.while_do(predicate, Observable.create(subscribe))
Example #9
0
def do_while(self, condition):
    """Repeats source as long as condition holds emulating a do while loop.

    Keyword arguments:
    condition -- {Function} The condition which determines if the source
        will be repeated.

    Returns an observable {Observable} sequence which is repeated as long
    as the condition holds.
    """

    return Observable.concat([self, Observable.while_do(condition, self)])
Example #10
0
    def test_when_never_never(self):
        scheduler = TestScheduler()
        xs = Observable.never()
        ys = Observable.never()

        def create():
            def selector(x, y):
                return x + y
            return Observable.when(xs.and_(ys).then_do(selector))

        results = scheduler.start(create)
        results.messages.assert_equal()
Example #11
0
    def test_return_observer_throws(self):
        scheduler1 = TestScheduler()
        xs = Observable.return_value(1, scheduler1)
        xs.subscribe(lambda x: _raise('ex'))

        self.assertRaises(RxException, scheduler1.start)

        scheduler2 = TestScheduler()
        ys = Observable.return_value(1, scheduler2)
        ys.subscribe(lambda x: x, lambda ex: ex, lambda: _raise('ex'))

        self.assertRaises(RxException, scheduler2.start)
Example #12
0
def variance(source: ObservableBase) -> ObservableBase:
    """
    Returns the statistical variance of the numerical emissions.
    The sequence must be finite.
    """
    squared_values = source.to_list() \
        .flat_map(lambda l: Observable.from_(l).average().flat_map(lambda avg: Observable.from_(l).map(lambda i: i - avg))) \
        .map(lambda i: i * i) \
        .publish() \
        .auto_connect(2)

    return Observable.zip(squared_values.sum(), squared_values.count(), lambda sum, ct: sum / (ct - 1))
Example #13
0
def repeat(self, repeat_count=None):
    """Repeats the observable sequence a specified number of times. If the
    repeat count is not specified, the sequence repeats indefinitely.

    1 - repeated = source.repeat()
    2 - repeated = source.repeat(42)

    Keyword arguments:
    repeat_count -- Number of times to repeat the sequence. If not
        provided, repeats the sequence indefinitely.

    Returns the observable sequence producing the elements of the given
    sequence repeatedly."""

    return Observable.defer(lambda: Observable.concat(Enumerable.repeat(self, repeat_count)))
Example #14
0
def merge(cls, *args):
    """Merges all the observable sequences into a single observable
    sequence. The scheduler is optional and if not specified, the
    immediate scheduler is used.

    1 - merged = rx.Observable.merge(xs, ys, zs)
    2 - merged = rx.Observable.merge([xs, ys, zs])
    3 - merged = rx.Observable.merge(scheduler, xs, ys, zs)
    4 - merged = rx.Observable.merge(scheduler, [xs, ys, zs])

    Returns the observable sequence that merges the elements of the
    observable sequences.
    """

    if not args[0]:
        scheduler = immediate_scheduler
        sources = args[1:]
    elif isinstance(args[0], Scheduler):
        scheduler = args[0]
        sources = args[1:]
    else:
        scheduler = immediate_scheduler
        sources = args[:]

    if isinstance(sources[0], list):
        sources = sources[0]

    return Observable.from_(sources, scheduler).merge_all()
Example #15
0
    def some(source: Observable) -> Observable:
        """Partially applied operator.

        Determines whether some element of an observable sequence satisfies a
        condition if present, else if some items are in the sequence.

        Example:
            >>> obs = some(source)

        Args:
            predicate -- A function to test each element for a condition.

        Returns:
            An observable sequence containing a single element
            determining whether some elements in the source sequence
            pass the test in the specified predicate if given, else if
            some items are in the sequence.
        """
        def subscribe(observer, scheduler=None):
            def on_next(_):
                observer.on_next(True)
                observer.on_completed()

            def on_error():
                observer.on_next(False)
                observer.on_completed()
            return source.subscribe_(on_next, observer.on_error, on_error, scheduler)

        if predicate:
            return source.pipe(
                ops.filter(predicate),
                _some(),
            )

        return Observable(subscribe)
Example #16
0
            def on_next(inner_source: Observable):
                nonlocal source

                d = SingleAssignmentDisposable()
                with source.lock:
                    latest[0] += 1
                    _id = latest[0]
                has_latest[0] = True
                inner_subscription.disposable = d

                # Check if Future or Observable
                inner_source = from_future(inner_source) if is_future(inner_source) else inner_source

                def on_next(x: Any) -> None:
                    if latest[0] == _id:
                        observer.on_next(x)

                def on_error(e: Exception) -> None:
                    if latest[0] == _id:
                        observer.on_error(e)

                def on_completed() -> None:
                    if latest[0] == _id:
                        has_latest[0] = False
                        if is_stopped[0]:
                            observer.on_completed()

                d.disposable = inner_source.subscribe_(on_next, on_error, on_completed, scheduler=scheduler)
Example #17
0
    def test_for_each_index_on_next_throws(self):
        ex = Exception()
        xs = Observable.range(0, 10)

        def action(x, i):
            _raise(ex)
        self.assertRaises(RxException, lambda: xs.to_blocking().for_each(action))
Example #18
0
 async def go():
     nonlocal result
     source = Observable.throw(error)
     try:
         result = await source
     except Exception as ex:
         result = ex
Example #19
0
        def create():
            def subscribe(o):
                o.on_next(1)
                o.on_next(2)
                return Disposable.empty()

            return Observable.create_with_disposable(subscribe)
Example #20
0
 def test_time_interval_default_scheduler(self):
     import datetime
     xs = Observable.from_((1,2)).time_interval().pluck_attr('interval')
     l = []
     d = xs.subscribe(lambda x: l.append(x))
     self.assertEqual(len(l), 2)
     [self.assertIsInstance(el, datetime.timedelta) for el in l]
Example #21
0
        def create():
            def subscribe(o):
                o.on_next(1)
                o.on_next(2)
                return lambda: None

            return Observable.create(subscribe)
Example #22
0
def repeat(cls, value=None, repeat_count=None, scheduler=None):
    """Generates an observable sequence that repeats the given element the
    specified number of times, using the specified scheduler to send out
    observer messages.

    1 - res = rx.Observable.repeat(42)
    2 - res = rx.Observable.repeat(42, 4)
    3 - res = rx.Observable.repeat(42, 4, Rx.Scheduler.timeout)
    4 - res = rx.Observable.repeat(42, None, Rx.Scheduler.timeout)

    Keyword arguments:
    value -- Element to repeat.
    repeat_count -- [Optional] Number of times to repeat the element. If not
        specified, repeats indefinitely.
    scheduler -- Scheduler to run the producer loop on. If not specified,
        defaults to ImmediateScheduler.

    Returns an observable sequence that repeats the given element the
    specified number of times."""

    scheduler = scheduler or current_thread_scheduler
    if repeat_count == -1:
        repeat_count = None

    xs = Observable.return_value(value, scheduler)
    return xs.repeat(repeat_count)
Example #23
0
    def partition(source: Observable) -> List[Observable]:
        """The partially applied `partition` operator.

        Returns two observables which partition the observations of the
        source by the given function. The first will trigger
        observations for those values for which the predicate returns
        true. The second will trigger observations for those values
        where the predicate returns false. The predicate is executed
        once for each subscribed observer. Both also propagate all
        error observations arising from the source and each completes
        when the source completes.

        Args:
            source: Source obserable to partition.

        Returns:
            A list of observables. The first triggers when the
            predicate returns True, and the second triggers when the
            predicate returns False.
        """

        published = source.pipe(
            ops.publish(),
            ops.ref_count()
        )
        return [
            published.pipe(ops.filter(predicate)),
            published.pipe(ops.filter(lambda x: not predicate(x)))
        ]
Example #24
0
def time_interval(self, scheduler):
    """Records the time interval between consecutive values in an
    observable sequence.

    1 - res = source.time_interval();
    2 - res = source.time_interval(Scheduler.timeout)

    Keyword arguments:
    scheduler -- [Optional] Scheduler used to compute time intervals. If
        not specified, the timeout scheduler is used.

    Return An observable sequence with time interval information on values.
    """

    source = self
    scheduler = scheduler or timeout_scheduler

    def defer():
        last = [scheduler.now]

        def selector(x):
            now = scheduler.now
            span = now - last[0]
            last[0] = now
            return TimeInterval(value=x, interval=span)

        return source.map(selector)
    return Observable.defer(defer)
Example #25
0
    def test_many_select_law_1(self):
        xs = Observable.range(1, 0)

        left = xs.many_select(lambda x: x.first())
        right = xs

        left.sequence_equal(right).first().subscribe(self.assertTrue)
Example #26
0
    def last(source: Observable) -> Observable:
        """Partially applied last operator.

        Returns the last element of an observable sequence that
        satisfies the condition in the predicate if specified, else
        the last element.

        Examples:
            >>> res = last(source)

        Args:
            source: Source observable to get last item from.

        Returns:
            An observable sequence containing the last element in the
            observable sequence that satisfies the condition in the
            predicate.
        """

        if predicate:
            return source.pipe(
                operators.filter(predicate),
                operators.last()
            )

        return last_or_default_async(source, False)
Example #27
0
def take_until(self, other):
    """Returns the values from the source observable sequence until the
    other observable sequence produces a value.

    Keyword arguments:
    other -- Observable sequence that terminates propagation of elements of
        the source sequence.

    Returns an observable sequence containing the elements of the source
    sequence up to the point the other sequence interrupted further
    propagation.
    """

    source = self
    other = Observable.from_future(other)

    def subscribe(observer):

        def on_completed(x):
            observer.on_completed()

        return CompositeDisposable(
            source.subscribe(observer),
            other.subscribe(on_completed, observer.on_error, noop)
        )
    return AnonymousObservable(subscribe)
Example #28
0
    def test_empty_observer_throw_exception(self):
        scheduler = TestScheduler()
        xs = Observable.empty(scheduler)
        xs.subscribe(lambda x: None, lambda ex: None, lambda: _raise('ex'))

        with self.assertRaises(RxException):
            scheduler.start()
Example #29
0
        def create():
            def subscribe(o):
                d = BooleanDisposable()
                o.on_next(1)
                o.on_next(2)

                def action1(scheduler, state):
                    if not d.is_disposed:
                        o.on_next(3)

                scheduler.schedule_relative(600, action1)

                def action2(scheduler, state):
                    if not d.is_disposed:
                        o.on_next(4)

                scheduler.schedule_relative(700, action2)

                def action3(scheduler, state):
                    if not d.is_disposed:
                        o.on_next(5)

                scheduler.schedule_relative(900, action3)

                def action4(scheduler, state):
                    if not d.is_disposed:
                        o.on_next(6)

                scheduler.schedule_relative(1100, action4)

                return d

            return Observable.create_with_disposable(subscribe)
Example #30
0
        def on_next(inner_source):
            d = SingleAssignmentDisposable()
            with self.lock:
                latest[0] += 1
                _id = latest[0]
            has_latest[0] = True
            inner_subscription.disposable = d

            # Check if Future or Observable
            inner_source = Observable.from_future(inner_source)

            def on_next(x):
                if latest[0] == _id:
                    observer.on_next(x)

            def on_error(e):
                if latest[0] == _id:
                    observer.on_error(e)

            def on_completed():
                if latest[0] == _id:
                    has_latest[0] = False
                    if is_stopped[0]:
                        observer.on_completed()

            d.disposable = inner_source.subscribe(on_next, on_error, on_completed)
    def delay_subscription(source: Observable) -> Observable:
        """Time shifts the observable sequence by delaying the subscription.

        Exampeles.
            >>> res = source.delay_subscription(5)

        Args:
            source: Source subscription to delay.

        Returns:
            Time-shifted sequence.
        """

        def mapper(_) -> Observable:
            return rx.empty()

        return source.pipe(
            ops.delay_with_mapper(rx.timer(duetime, scheduler=scheduler), mapper)
        )
Example #32
0
        def on_next(inner_source):
            if not has_current[0]:
                has_current[0] = True

                inner_source = Observable.from_future(
                    inner_source) if is_future(inner_source) else inner_source

                inner_subscription = SingleAssignmentDisposable()
                g.add(inner_subscription)

                def on_completed_inner():
                    g.remove(inner_subscription)
                    has_current[0] = False
                    if is_stopped[0] and len(g) == 1:
                        observer.on_completed()

                inner_subscription.disposable = inner_source.subscribe_(
                    observer.on_next, observer.on_error, on_completed_inner,
                    scheduler)
    def flat_map_latest(source: Observable) -> Observable:
        """Projects each element of an observable sequence into a new
        sequence of observable sequences by incorporating the element's
        index and then transforms an observable sequence of observable
        sequences into an observable sequence producing values only
        from the most recent observable sequence.

        Args:
            source: Source observable to flat map latest.

        Returns:
            An observable sequence whose elements are the result of
            invoking the transform function on each element of source
            producing an observable of Observable sequences and that at
            any point in time produces the elements of the most recent
            inner observable sequence that has been received.
        """

        return source.pipe(ops.map(mapper), ops.switch_latest())
Example #34
0
def interval(cls, period, scheduler=None):
    """Returns an observable sequence that produces a value after each
    period.

    Example:
    1 - res = rx.Observable.interval(1000)
    2 - res = rx.Observable.interval(1000, rx.Scheduler.timeout)

    Keyword arguments:
    period -- Period for producing the values in the resulting sequence
        (specified as an integer denoting milliseconds).
    scheduler -- [Optional] Scheduler to run the timer on. If not specified,
        rx.Scheduler.timeout is used.

    Returns an observable sequence that produces a value after each period.
    """

    scheduler = scheduler or TimeoutScheduler()
    return Observable.timer(period, period, scheduler)
Example #35
0
    def skip_with_time(source: Observable) -> Observable:
        """Skips elements for the specified duration from the start of
        the observable source sequence.

        Args:
            >>> res = skip_with_time(5.0)

        Specifying a zero value for duration doesn't guarantee no
        elements will be dropped from the start of the source sequence.
        This is a side-effect of the asynchrony introduced by the
        scheduler, where the action that causes callbacks from the
        source sequence to be forwarded may not execute immediately,
        despite the zero due time.

        Errors produced by the source sequence are always forwarded to
        the result sequence, even if the error occurs before the
        duration.

        Args:
            duration: Duration for skipping elements from the start of
            the sequence.

        Returns:
            An observable sequence with the elements skipped during the
            specified duration from the start of the source sequence.
        """

        def subscribe(observer, scheduler_=None):
            _scheduler = scheduler or scheduler_ or timeout_scheduler
            open = [False]

            def action(scheduler, state):
                open[0] = True

            t = _scheduler.schedule_relative(duration, action)

            def on_next(x):
                if open[0]:
                    observer.on_next(x)

            d = source.subscribe_(on_next, observer.on_error, observer.on_completed, scheduler_)
            return CompositeDisposable(t, d)
        return Observable(subscribe)
Example #36
0
        def action(scheduler, state=None):
            try:
                source = next(sources)
            except StopIteration:
                observer.on_completed()
                return

            # Allow source to be a factory method taking an error
            source = source(state) if callable(source) else source
            current = Observable.from_future(source)

            d = SingleAssignmentDisposable()
            subscription.disposable = d

            def on_resume(state=None):
                scheduler.schedule(action, state)

            d.disposable = current.subscribe(observer.on_next, on_resume,
                                             on_resume)
Example #37
0
def skip_until(self, other):
    """Returns the values from the source observable sequence only after
    the other observable sequence produces a value.

    other -- The observable sequence that triggers propagation of elements
        of the source sequence.

    Returns an observable sequence containing the elements of the source
    sequence starting from the point the other sequence triggered
    propagation.
    """

    source = self
    other = Observable.from_future(other)

    def subscribe(observer):
        is_open = [False]

        def on_next(left):
            if is_open[0]:
                observer.on_next(left)

        def on_completed():
            if is_open[0]:
                observer.on_completed()

        subs = source.subscribe(on_next, observer.on_error, on_completed)
        disposables = CompositeDisposable(subs)

        right_subscription = SingleAssignmentDisposable()
        disposables.add(right_subscription)

        def on_next2(x):
            is_open[0] = True
            right_subscription.dispose()

        def on_completed2():
            right_subscription.dispose()

        right_subscription.disposable = other.subscribe(on_next2, observer.on_error, on_completed2)

        return disposables
    return AnonymousObservable(subscribe)
Example #38
0
def from_iterable(iterable: Iterable,
                  scheduler: Optional[typing.Scheduler] = None) -> Observable:
    """Converts an iterable to an observable sequence.

    Example:
        >>> from_iterable([1,2,3])

    Args:
        iterable: A Python iterable
        scheduler: An optional scheduler to schedule the values on.

    Returns:
        The observable sequence whose elements are pulled from the
        given iterable sequence.
    """
    def subscribe(
            observer: typing.Observer,
            scheduler_: Optional[typing.Scheduler] = None
    ) -> typing.Disposable:
        _scheduler = scheduler or scheduler_ or current_thread_scheduler
        iterator = iter(iterable)
        disposed = False

        def action(_: typing.Scheduler, __: Any = None) -> None:
            nonlocal disposed

            try:
                while not disposed:
                    value = next(iterator)
                    observer.on_next(value)
            except StopIteration:
                observer.on_completed()
            except Exception as error:  # pylint: disable=broad-except
                observer.on_error(error)

        def dispose() -> None:
            nonlocal disposed
            disposed = True

        disp = Disposable(dispose)
        return CompositeDisposable(_scheduler.schedule(action), disp)

    return Observable(subscribe)
def _concat_with_iterable(sources: Iterable[Observable]) -> Observable:

    sources_ = iter(sources)

    def subscribe(observer, scheduler=None):
        scheduler = scheduler or CurrentThreadScheduler.singleton()

        subscription = SerialDisposable()
        cancelable = SerialDisposable()
        is_disposed = False

        def action(action1, state=None):
            nonlocal is_disposed
            if is_disposed:
                return

            def on_completed():
                cancelable.disposable = scheduler.schedule(action)

            try:
                current = next(sources_)
            except StopIteration:
                observer.on_completed()
            except Exception as ex:  # pylint: disable=broad-except
                observer.on_error(ex)
            else:
                d = SingleAssignmentDisposable()
                subscription.disposable = d
                d.disposable = current.subscribe_(observer.on_next,
                                                  observer.on_error,
                                                  on_completed, scheduler)

        cancelable.disposable = scheduler.schedule(action)

        def dispose():
            nonlocal is_disposed
            is_disposed = True

        return CompositeDisposable(subscription, cancelable,
                                   Disposable(dispose))

    return Observable(subscribe)
    def window_with_count(source: Observable) -> Observable:
        def subscribe(observer, scheduler=None):
            m = SingleAssignmentDisposable()
            refCountDisposable = RefCountDisposable(m)
            n = [0]
            q = []

            def create_window():
                s = Subject()
                q.append(s)
                observer.on_next(add_ref(s, refCountDisposable))

            create_window()

            def on_next(x):
                for item in q:
                    item.on_next(x)

                c = n[0] - count + 1
                if c >= 0 and c % skip == 0:
                    s = q.pop(0)
                    s.on_completed()

                n[0] += 1
                if (n[0] % skip) == 0:
                    create_window()

            def on_error(exception):
                while q:
                    q.pop(0).on_error(exception)
                observer.on_error(exception)

            def on_completed():
                while q:
                    q.pop(0).on_completed()
                observer.on_completed()

            m.disposable = source.subscribe_(on_next, on_error, on_completed,
                                             scheduler)
            return refCountDisposable

        return Observable(subscribe)
Example #41
0
def extrema_by(source: Observable,
               key_mapper: Mapper,
               comparer: Comparer
               ) -> Observable:

    def subscribe(observer, scheduler=None):
        has_value = [False]
        last_key = [None]
        items = []

        def on_next(x):
            try:
                key = key_mapper(x)
            except Exception as ex:
                observer.on_error(ex)
                return

            comparison = 0

            if not has_value[0]:
                has_value[0] = True
                last_key[0] = key
            else:
                try:
                    comparison = comparer(key, last_key[0])
                except Exception as ex1:
                    observer.on_error(ex1)
                    return

            if comparison > 0:
                last_key[0] = key
                items[:] = []

            if comparison >= 0:
                items.append(x)

        def on_completed():
            observer.on_next(items)
            observer.on_completed()

        return source.subscribe_(on_next, observer.on_error, on_completed, scheduler)
    return Observable(subscribe)
Example #42
0
    def take_while(source: Observable) -> Observable:
        """Returns elements from an observable sequence as long as a
        specified condition is true.

        Example:
            >>> take_while(source)

        Args:
            source: The source observable to take from.

        Returns:
            An observable sequence that contains the elements from the
            input sequence that occur before the element at which the
            test no longer passes.
        """
        def subscribe(observer, scheduler=None):
            running = True

            def on_next(value):
                nonlocal running

                with source.lock:
                    if not running:
                        return

                    try:
                        running = predicate(value)
                    except Exception as exn:
                        observer.on_error(exn)
                        return

                if running:
                    observer.on_next(value)
                else:
                    if inclusive:
                        observer.on_next(value)
                    observer.on_completed()

            return source.subscribe_(on_next, observer.on_error,
                                     observer.on_completed, scheduler)

        return Observable(subscribe)
def delay_subscription(self, duetime, scheduler=None):
    """Time shifts the observable sequence by delaying the subscription.

    1 - res = source.delay_subscription(5000) # 5s
    2 - res = source.delay_subscription(5000, Scheduler.timeout) # 5 seconds

    duetime -- Absolute or relative time to perform the subscription at.
    scheduler [Optional] Scheduler to run the subscription delay timer on.
        If not specified, the timeout scheduler is used.

    Returns time-shifted sequence.
    """

    scheduler = scheduler or timeout_scheduler

    def selector(_):
        return Observable.empty()

    return self.delay_with_selector(Observable.timer(duetime, scheduler),
                                    selector)
Example #44
0
def last_or_default_async(source, has_default=False, default_value=None):
    def subscribe(observer, scheduler=None):
        value = [default_value]
        seen_value = [False]

        def on_next(x):
            value[0] = x
            seen_value[0] = True

        def on_completed():
            if not seen_value[0] and not has_default:
                observer.on_error(SequenceContainsNoElementsError())
            else:
                observer.on_next(value[0])
                observer.on_completed()

        return source.subscribe_(on_next, observer.on_error, on_completed,
                                 scheduler)

    return Observable(subscribe)
Example #45
0
def repeat_value(value: Any = None, repeat_count: int = None) -> ObservableBase:
    """Generates an observable sequence that repeats the given element
    the specified number of times.

    1 - res = repeat_value(42)
    2 - res = repeat_value(42, 4)

    Keyword arguments:
    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."""

    if repeat_count == -1:
        repeat_count = None

    xs = Observable.return_value(value)
    return xs.repeat(repeat_count)
Example #46
0
def _with_latest_from(parent: Observable, *sources: Observable) -> Observable:
    NO_VALUE = NotSet()

    def subscribe(observer, scheduler=None):
        def subscribe_all(parent, *children):

            values = [NO_VALUE for _ in children]

            def subscribe_child(i, child):
                subscription = SingleAssignmentDisposable()

                def on_next(value):
                    with parent.lock:
                        values[i] = value

                subscription.disposable = child.subscribe_(on_next,
                                                           observer.on_error,
                                                           scheduler=scheduler)
                return subscription

            parent_subscription = SingleAssignmentDisposable()

            def on_next(value):
                with parent.lock:
                    if NO_VALUE not in values:
                        result = (value, ) + tuple(values)
                        observer.on_next(result)

            disp = parent.subscribe_(on_next, observer.on_error,
                                     observer.on_completed, scheduler)
            parent_subscription.disposable = disp

            children_subscription = [
                subscribe_child(i, child) for i, child in enumerate(children)
            ]

            return [parent_subscription] + children_subscription

        return CompositeDisposable(subscribe_all(parent, *sources))

    return Observable(subscribe)
Example #47
0
    def to_dict(source: Observable) -> Observable:
        """Converts the observable sequence to a Map if it exists.

        Args:
            source: Source observable to convert.

        Returns:
            An observable sequence with a single value of a dictionary
            containing the values from the observable sequence.
        """
        def subscribe(
                observer: typing.Observer,
                scheduler: Optional[typing.Scheduler] = None
        ) -> typing.Disposable:
            m = dict()

            def on_next(x: Any) -> None:
                try:
                    key = key_mapper(x)
                except Exception as ex:  # pylint: disable=broad-except
                    observer.on_error(ex)
                    return

                element = x
                if element_mapper:
                    try:
                        element = element_mapper(x)
                    except Exception as ex:  # pylint: disable=broad-except
                        observer.on_error(ex)
                        return

                m[key] = element

            def on_completed() -> None:
                observer.on_next(m)
                observer.on_completed()

            return source.subscribe_(on_next, observer.on_error, on_completed,
                                     scheduler)

        return Observable(subscribe)
Example #48
0
def _generate(initial_state: Any,
              condition: Predicate,
              iterate: Mapper
              ) -> Observable:

    def subscribe(observer, scheduler=None):
        scheduler = scheduler or CurrentThreadScheduler.singleton()
        first = True
        state = initial_state
        mad = MultipleAssignmentDisposable()

        def action(scheduler, state1=None):
            nonlocal first
            nonlocal state

            has_result = False
            result = None

            try:
                if first:
                    first = False
                else:
                    state = iterate(state)

                has_result = condition(state)
                if has_result:
                    result = state

            except Exception as exception:  # pylint: disable=broad-except
                observer.on_error(exception)
                return

            if has_result:
                observer.on_next(result)
                mad.disposable = scheduler.schedule(action)
            else:
                observer.on_completed()

        mad.disposable = scheduler.schedule(action)
        return mad
    return Observable(subscribe)
Example #49
0
    def observe_on(source: Observable) -> Observable:
        """Wraps the source sequence in order to run its observer
        callbacks on the specified scheduler.

        This only invokes observer callbacks on a scheduler. In case
        the subscription and/or unsubscription actions have
        side-effects that require to be run on a scheduler, use
        subscribe_on.

        Args:
            source: Source observable.


        Returns:
            Returns the source sequence whose observations happen on
            the specified scheduler.
        """
        def subscribe(observer, _=None):
            return source.subscribe(ObserveOnObserver(scheduler, observer))

        return Observable(subscribe)
    def last_or_default(source: Observable) -> Observable:
        """Return last or default element.

        Examples:
            >>> res = _last_or_default(source)

        Args:
            source: Observable sequence to get the last item from.

        Returns:
            Observable sequence containing the last element in the
            observable sequence.
        """

        if predicate:
            return source.pipe(
                ops.filter(predicate),
                ops.last_or_default(None, default_value),
            )

        return last_or_default_async(source, True, default_value)
Example #51
0
    def test_map_throws(self):
        with self.assertRaises(RxException):
            Observable.return_value(1) \
                .map(mapper_indexed=lambda x, y: x) \
                .subscribe_(lambda x: _raise("ex"))

        with self.assertRaises(RxException):
            Observable.throw('ex') \
                .map(mapper_indexed=lambda x, y: x) \
                .subscribe_(on_error=lambda ex: _raise(ex))

        with self.assertRaises(RxException):
            Observable.empty() \
                .map(mapper_indexed=lambda x, y: x) \
                .subscribe_(lambda x: x, lambda ex: ex, lambda: _raise('ex'))

        def subscribe(observer, scheduler=None):
            _raise('ex')

        with self.assertRaises(RxException):
            Observable.create(subscribe) \
                .map(lambda x: x) \
                .subscribe()
Example #52
0
    def test_select_throws(self):
        with self.assertRaises(RxException):
            Observable.return_value(1) \
                .map(lambda x, y: x) \
                .subscribe(lambda x: _raise("ex"))

        with self.assertRaises(RxException):
            Observable.throw_exception('ex') \
                .map(lambda x, y: x) \
                .subscribe(on_error=lambda ex: _raise(ex))

        with self.assertRaises(RxException):
            Observable.empty() \
                .map(lambda x, y: x) \
                .subscribe(lambda x: x, lambda ex: ex, lambda: _raise('ex'))

        def subscribe(observer):
            _raise('ex')

        with self.assertRaises(RxException):
            Observable.create(subscribe) \
                .map(lambda x: x) \
                .subscribe()
Example #53
0
def many_select(self, selector, scheduler=None):
    """Comonadic bind operator. Internally projects a new observable for each
    value, and it pushes each observable into the user-defined selector function
    that projects/queries each observable into some result.

    Keyword arguments:
    selector -- {Function} A transform function to apply to each element.
    scheduler -- {Object} [Optional] Scheduler used to execute the
        operation. If not specified, defaults to the ImmediateScheduler.

    Returns {Observable} An observable sequence which results from the
    comonadic bind operation.
    """

    scheduler = scheduler or immediate_scheduler
    source = self

    def factory():
        chain = [None]

        def mapper(x):
            curr = ChainObservable(x)

            chain[0] and chain[0].on_next(x)
            chain[0] = curr

            return curr

        def on_error(e):
            if chain[0]:
                chain[0].on_error(e)

        def on_completed():
            if chain[0]:
                chain[0].on_completed()

        return source.map(mapper).tap(
            noop, on_error, on_completed).observe_on(scheduler).map(selector)

    return Observable.defer(factory)
Example #54
0
    def exclusive(source: Observable) -> Observable:
        def subscribe(observer, scheduler=None):
            has_current = [False]
            is_stopped = [False]
            m = SingleAssignmentDisposable()
            g = CompositeDisposable()

            g.add(m)

            def on_next(inner_source):
                if not has_current[0]:
                    has_current[0] = True

                    inner_source = rx.from_future(inner_source) if is_future(
                        inner_source) else inner_source

                    inner_subscription = SingleAssignmentDisposable()
                    g.add(inner_subscription)

                    def on_completed_inner():
                        g.remove(inner_subscription)
                        has_current[0] = False
                        if is_stopped[0] and len(g) == 1:
                            observer.on_completed()

                    inner_subscription.disposable = inner_source.subscribe_(
                        observer.on_next, observer.on_error,
                        on_completed_inner, scheduler)

            def on_completed():
                is_stopped[0] = True
                if not has_current[0] and len(g) == 1:
                    observer.on_completed()

            m.disposable = source.subscribe_(on_next, observer.on_error,
                                             on_completed, scheduler)
            return g

        return Observable(subscribe)
Example #55
0
    def test_ref_count_notconnected(self):
        disconnected = [False]
        count = [0]

        def factory(scheduler):
            count[0] += 1

            def create(obs):
                def func():
                    disconnected[0] = True

                return func

            return Observable.create(create)

        xs = Observable.defer(factory)

        subject = MySubject()
        conn = ConnectableObservable(xs, subject)
        refd = conn.ref_count()
        dis1 = refd.subscribe()
        self.assertEqual(1, count[0])
        self.assertEqual(1, subject.subscribe_count)
        assert (not disconnected[0])
        dis2 = refd.subscribe()
        self.assertEqual(1, count[0])
        self.assertEqual(2, subject.subscribe_count)
        assert (not disconnected[0])
        dis1.dispose()
        assert (not disconnected[0])
        dis2.dispose()
        assert (disconnected[0])
        disconnected[0] = False
        dis3 = refd.subscribe()
        self.assertEqual(2, count[0])
        self.assertEqual(3, subject.subscribe_count)
        assert (not disconnected[0])
        dis3.dispose()
        assert (disconnected[0])
Example #56
0
File: catch.py Project: vuchau/RxPY
def catch_exception(self, second=None, handler=None):
    """Continues an observable sequence that is terminated by an exception
    with the next observable sequence.

    1 - xs.catch_exception(ys)
    2 - xs.catch_exception(lambda ex: ys(ex))

    Keyword arguments:
    handler -- Exception handler function that returns an observable
        sequence  given the error that occurred in the first sequence.
    second -- Second observable sequence used to produce results when an
        error occurred in the first sequence.

    Returns an observable sequence containing the first sequence's
    elements, followed by the elements of the handler sequence in case an
    exception occurred.
    """

    if handler or not isinstance(second, Observable):
        return catch_handler(self, handler or second)

    return Observable.catch_exception([self, second])
Example #57
0
def with_latest_from(self, *args):
    """Merges the specified observable sequences into one observable sequence
    by using the selector function only when the source observable sequence
    (the instance) produces an element. The other observables can be passed
    either as seperate arguments or as a list.

    1 - obs = observable.with_latest_from(obs1, obs2, obs3,
                                        lambda o1, o2, o3: o1 + o2 + o3)
    2 - obs = observable.with_latest_from([obs1, obs2, obs3],
                                        lambda o1, o2, o3: o1 + o2 + o3)

    Returns an observable sequence containing the result of combining
    elements of the sources using the specified result selector function.
    """

    args = list(args)
    if args and isinstance(args[0], list):
        args = args[0]

    args.insert(0, self)

    return Observable.with_latest_from(*args)
Example #58
0
    def take_until(source: Observable) -> Observable:
        """Returns the values from the source observable sequence until
        the other observable sequence produces a value.

        Args:
            source: The source observable sequence.

        Returns:
            An observable sequence containing the elements of the source
            sequence up to the point the other sequence interrupted
            further propagation.
        """
        def subscribe(observer, scheduler=None):
            def on_completed(_):
                observer.on_completed()

            return CompositeDisposable(
                source.subscribe(observer),
                other.subscribe_(on_completed, observer.on_error, noop,
                                 scheduler))

        return Observable(subscribe)
Example #59
0
File: amb.py Project: xyicheng/RxPY
def amb(*args):
    """Propagates the observable sequence that reacts first.

    E.g. winner = Observable.amb(xs, ys, zs)

    Returns an observable sequence that surfaces any of the given
    sequences, whichever reacted first.
    """

    acc = Observable.never()
    if isinstance(args[0], list):
        items = args[0]
    else:
        items = list(args)

    def func(previous, current):
        return _amb(previous, current)

    for item in items:
        acc = func(acc, item)

    return acc
Example #60
0
File: do.py Project: wensincai/RxPY
def do_on_dispose(source: Observable, on_dispose):
    """Invokes an action on disposal.

     This can be helpful for debugging, logging, and other side effects
     on the disposal of an operation.

    Args:
        on_dispose: Action to invoke on disposal
    """
    class OnDispose(Disposable):
        def dispose(self):
            on_dispose()

    def subscribe(observer, scheduler=None):
        composite_disposable = CompositeDisposable()
        composite_disposable.add(OnDispose())
        subscription = source.subscribe_(observer.on_next, observer.on_error,
                                         observer.on_completed, scheduler)
        composite_disposable.add(subscription)
        return composite_disposable

    return Observable(subscribe)