예제 #1
0
파일: statistics.py 프로젝트: lizh06/RxPY
def variance(source: Observable) -> Observable:
    """
    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))
예제 #2
0
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'.

    Examples:
        >>> res = return(42)
        >>> res = return(42, rx.Scheduler.timeout)

    Args:
        value: Single element in the resulting observable sequence.

    Returns:
        An observable sequence containing the single specified
        element.
    """
    def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler_: Optional[abc.SchedulerBase] = None
    ) -> abc.DisposableBase:
        _scheduler = scheduler or scheduler_ or CurrentThreadScheduler.singleton(
        )

        def action(scheduler: abc.SchedulerBase, state: Any = None) -> None:
            observer.on_next(value)
            observer.on_completed()

        return _scheduler.schedule(action)

    return Observable(subscribe)
예제 #3
0
    def take_until_with_time(source: Observable[_T]) -> Observable[_T]:
        """Takes elements for the specified duration until the specified end
        time, using the specified scheduler to run timers.

        Examples:
            >>> res = take_until_with_time(source)

        Args:
            source: Source observale to take elements from.

        Returns:
            An observable sequence with the elements taken
            until the specified end time.
        """
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton(
            )

            def action(scheduler: abc.SchedulerBase, state: Any = None):
                observer.on_completed()

            if isinstance(end_time, datetime):
                task = _scheduler.schedule_absolute(end_time, action)
            else:
                task = _scheduler.schedule_relative(end_time, action)

            return CompositeDisposable(
                task, source.subscribe(observer, scheduler=scheduler_))

        return Observable(subscribe)
예제 #4
0
    def multicast(
        source: Observable[_TSource],
    ) -> Union[Observable[_TResult], ConnectableObservable[_TSource]]:
        if subject_factory:

            def subscribe(
                observer: abc.ObserverBase[_TResult],
                scheduler: Optional[abc.SchedulerBase] = None,
            ) -> abc.DisposableBase:
                assert subject_factory
                connectable = source.pipe(
                    ops.multicast(subject=subject_factory(scheduler)))
                assert mapper
                subscription = mapper(connectable).subscribe(
                    observer, scheduler=scheduler)

                return CompositeDisposable(subscription,
                                           connectable.connect(scheduler))

            return Observable(subscribe)

        if not subject:
            raise ValueError("multicast: Subject cannot be None")
        ret: ConnectableObservable[_TSource] = ConnectableObservable(
            source, subject)
        return ret
예제 #5
0
파일: _map.py 프로젝트: lizh06/RxPY
    def map(source: Observable[_T1]) -> Observable[_T2]:
        """Partially applied map operator.

        Project each element of an observable sequence into a new form
        by incorporating the element's index.

        Example:
            >>> map(source)

        Args:
            source: The observable source to transform.

        Returns:
            Returns an observable sequence whose elements are the
            result of invoking the transform function on each element
            of the source.
        """

        def subscribe(
            obv: abc.ObserverBase[_T2], scheduler: Optional[abc.SchedulerBase] = None
        ) -> abc.DisposableBase:
            def on_next(value: _T1) -> None:
                try:
                    result = _mapper(value)
                except Exception as err:  # pylint: disable=broad-except
                    obv.on_error(err)
                else:
                    obv.on_next(result)

            return source.subscribe(
                on_next, obv.on_error, obv.on_completed, scheduler=scheduler
            )

        return Observable(subscribe)
예제 #6
0
    def element_at_or_default(source: Observable[_T]) -> Observable[_T]:
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            index_ = index

            def on_next(x: _T) -> None:
                nonlocal index_
                found = False
                with source.lock:
                    if index_:
                        index_ -= 1
                    else:
                        found = True

                if found:
                    observer.on_next(x)
                    observer.on_completed()

            def on_completed():
                if not has_default:
                    observer.on_error(ArgumentOutOfRangeException())
                else:
                    observer.on_next(cast(_T, default_value))
                    observer.on_completed()

            return source.subscribe(on_next,
                                    observer.on_error,
                                    on_completed,
                                    scheduler=scheduler)

        return Observable(subscribe)
예제 #7
0
파일: timer.py 프로젝트: lizh06/RxPY
def observable_timer_timespan_and_period(
    duetime: typing.RelativeTime,
    period: typing.RelativeTime,
    scheduler: Optional[abc.SchedulerBase] = None,
) -> Observable[int]:
    if duetime == period:

        def subscribe(
            observer: abc.ObserverBase[int],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            _scheduler: abc.SchedulerBase = (scheduler or scheduler_
                                             or TimeoutScheduler.singleton())

            def action(count: Optional[int] = None) -> Optional[int]:
                if count is not None:
                    observer.on_next(count)
                    return count + 1
                return None

            if not isinstance(_scheduler, PeriodicScheduler):
                raise ValueError("Sceduler must be PeriodicScheduler")
            return _scheduler.schedule_periodic(period, action, state=0)

        return Observable(subscribe)
    return observable_timer_duetime_and_period(duetime, period, scheduler)
예제 #8
0
    def materialize(source: Observable[_T]) -> Observable[Notification[_T]]:
        """Partially applied materialize operator.

        Materializes the implicit notifications of an observable
        sequence as explicit notification values.

        Args:
            source: Source observable to materialize.

        Returns:
            An observable sequence containing the materialized
            notification values from the source sequence.
        """
        def subscribe(
            observer: abc.ObserverBase[Notification[_T]],
            scheduler: Optional[abc.SchedulerBase] = None,
        ):
            def on_next(value: _T) -> None:
                observer.on_next(OnNext(value))

            def on_error(error: Exception) -> None:
                observer.on_next(OnError(error))
                observer.on_completed()

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

            return source.subscribe(on_next,
                                    on_error,
                                    on_completed,
                                    scheduler=scheduler)

        return Observable(subscribe)
예제 #9
0
def last_or_default_async(
    source: Observable[_T],
    has_default: bool = False,
    default_value: Optional[_T] = None,
) -> Observable[Optional[_T]]:
    def subscribe(
        observer: abc.ObserverBase[Optional[_T]],
        scheduler: Optional[abc.SchedulerBase] = None,
    ):
        value = [default_value]
        seen_value = [False]

        def on_next(x: _T) -> None:
            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=scheduler)

    return Observable(subscribe)
예제 #10
0
파일: _takeuntil.py 프로젝트: lizh06/RxPY
    def take_until(source: Observable[_T]) -> Observable[_T]:
        """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: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            def on_completed(_: _T) -> None:
                observer.on_completed()

            return CompositeDisposable(
                source.subscribe(observer, scheduler=scheduler),
                obs.subscribe(
                    on_completed, observer.on_error, noop, scheduler=scheduler
                ),
            )

        return Observable(subscribe)
예제 #11
0
파일: _do.py 프로젝트: lizh06/RxPY
def do_after_terminate(source: Observable[Any],
                       after_terminate: typing.Action):
    """Invokes an action after an on_complete() or on_error() event.
     This can be helpful for debugging, logging, and other side effects
     when completion or an error terminates an operation


    on_terminate -- Action to invoke after on_complete or throw is called
    """
    def subscribe(
            observer: abc.ObserverBase[Any],
            scheduler: Optional[abc.SchedulerBase] = None
    ) -> abc.DisposableBase:
        def on_completed():
            observer.on_completed()
            try:
                after_terminate()
            except Exception as err:  # pylint: disable=broad-except
                observer.on_error(err)

        def on_error(exception: Exception) -> None:
            observer.on_error(exception)
            try:
                after_terminate()
            except Exception as err:  # pylint: disable=broad-except
                observer.on_error(err)

        return source.subscribe(observer.on_next,
                                on_error,
                                on_completed,
                                scheduler=scheduler)

    return Observable(subscribe)
예제 #12
0
파일: _do.py 프로젝트: lizh06/RxPY
def do_on_dispose(source: Observable[Any], on_dispose: typing.Action):
    """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(abc.DisposableBase):
        def dispose(self) -> None:
            on_dispose()

    def subscribe(
            observer: abc.ObserverBase[Any],
            scheduler: Optional[abc.SchedulerBase] = None
    ) -> abc.DisposableBase:
        composite_disposable = CompositeDisposable()
        composite_disposable.add(OnDispose())
        subscription = source.subscribe(
            observer.on_next,
            observer.on_error,
            observer.on_completed,
            scheduler=scheduler,
        )
        composite_disposable.add(subscription)
        return composite_disposable

    return Observable(subscribe)
예제 #13
0
    def skip_last_with_time(source: Observable[_T]) -> Observable[_T]:
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            nonlocal duration

            _scheduler: abc.SchedulerBase = (scheduler or scheduler_
                                             or TimeoutScheduler.singleton())
            duration = _scheduler.to_timedelta(duration)
            q: List[Dict[str, Any]] = []

            def on_next(x: _T) -> None:
                now = _scheduler.now
                q.append({"interval": now, "value": x})
                while q and now - q[0]["interval"] >= duration:
                    observer.on_next(q.pop(0)["value"])

            def on_completed() -> None:
                now = _scheduler.now
                while q and now - q[0]["interval"] >= duration:
                    observer.on_next(q.pop(0)["value"])

                observer.on_completed()

            return source.subscribe(on_next,
                                    observer.on_error,
                                    on_completed,
                                    scheduler=_scheduler)

        return Observable(subscribe)
    def _buffer_by_bytes_count(source: Observable) -> Observable:
        def subscribe(observer, scheduler=None):
            observer.buffer = []

            def on_next(current):
                observer.buffer.append(current)
                # Emit new batch if the buffer size is greater then boundary
                if (_buffer_bytes_size(observer.buffer) +
                        len(current)) >= bytes_count:
                    # emit batch
                    observer.on_next(observer.buffer)
                    observer.buffer = []

            def on_error(exception):
                observer.buffer = []
                observer.on_error(exception)

            def on_completed():
                if len(observer.buffer) >= 0:
                    # flush rest of buffer
                    observer.on_next(observer.buffer)
                    observer.buffer = []
                observer.on_completed()

            return source.subscribe(on_next,
                                    on_error,
                                    on_completed,
                                    scheduler=scheduler)

        return Observable(subscribe)
예제 #15
0
    def time_interval(source: Observable[_T]) -> Observable[TimeInterval[_T]]:
        """Records the time interval between consecutive values in an
        observable sequence.

            >>> res = time_interval(source)

        Return:
            An observable sequence with time interval information on
            values.
        """
        def subscribe(
            observer: abc.ObserverBase[TimeInterval[_T]],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton(
            )
            last = _scheduler.now

            def mapper(value: _T) -> TimeInterval[_T]:
                nonlocal last

                now = _scheduler.now
                span = now - last
                last = now
                return TimeInterval(value=value, interval=span)

            return source.pipe(ops.map(mapper)).subscribe(observer,
                                                          scheduler=_scheduler)

        return Observable(subscribe)
예제 #16
0
    def finally_action(source: Observable[_T]) -> Observable[_T]:
        """Invokes a specified action after the source observable
        sequence terminates gracefully or exceptionally.

        Example:
            res = finally(source)

        Args:
            source: Observable sequence.

        Returns:
            An observable sequence with the action-invoking termination
            behavior applied.
        """
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            try:
                subscription = source.subscribe(observer, scheduler=scheduler)
            except Exception:
                action()
                raise

            def dispose():
                try:
                    subscription.dispose()
                finally:
                    action()

            return Disposable(dispose)

        return Observable(subscribe)
예제 #17
0
    def filter(source: Observable[_T]) -> Observable[_T]:
        """Partially applied filter operator.

        Filters the elements of an observable sequence based on a
        predicate.

        Example:
            >>> filter(source)

        Args:
            source: Source observable to filter.

        Returns:
            A filtered observable sequence.
        """
        def subscribe(
                observer: abc.ObserverBase[_T],
                scheduler: Optional[abc.SchedulerBase]) -> abc.DisposableBase:
            def on_next(value: _T):
                try:
                    should_run = predicate(value)
                except Exception as ex:  # pylint: disable=broad-except
                    observer.on_error(ex)
                    return

                if should_run:
                    observer.on_next(value)

            return source.subscribe(on_next,
                                    observer.on_error,
                                    observer.on_completed,
                                    scheduler=scheduler)

        return Observable(subscribe)
예제 #18
0
파일: _find.py 프로젝트: lizh06/RxPY
    def find_value(source: Observable[_T]) -> Observable[Union[_T, int, None]]:
        def subscribe(
            observer: abc.ObserverBase[Union[_T, int, None]],
            scheduler: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            index = 0

            def on_next(x: _T) -> None:
                nonlocal index
                should_run = False
                try:
                    should_run = predicate(x, index, source)
                except Exception as ex:  # pylint: disable=broad-except
                    observer.on_error(ex)
                    return

                if should_run:
                    observer.on_next(index if yield_index else x)
                    observer.on_completed()
                else:
                    index += 1

            def on_completed():
                observer.on_next(-1 if yield_index else None)
                observer.on_completed()

            return source.subscribe(on_next,
                                    observer.on_error,
                                    on_completed,
                                    scheduler=scheduler)

        return Observable(subscribe)
예제 #19
0
    def skip(source: Observable[_T]) -> Observable[_T]:
        """The skip operator.

        Bypasses a specified number of elements in an observable sequence
        and then returns the remaining elements.

        Args:
            source: The source observable.

        Returns:
            An observable sequence that contains the elements that occur
            after the specified index in the input sequence.
        """
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None,
        ):
            remaining = count

            def on_next(value: _T) -> None:
                nonlocal remaining

                if remaining <= 0:
                    observer.on_next(value)
                else:
                    remaining -= 1

            return source.subscribe(on_next,
                                    observer.on_error,
                                    observer.on_completed,
                                    scheduler=scheduler)

        return Observable(subscribe)
예제 #20
0
파일: _toiterable.py 프로젝트: lizh06/RxPY
    def to_iterable(source: Observable[_T]) -> Observable[List[_T]]:
        """Creates an iterable from an observable sequence.

        Returns:
            An observable sequence containing a single element with an
            iterable containing all the elements of the source
            sequence.
        """
        def subscribe(
            observer: abc.ObserverBase[List[_T]],
            scheduler: Optional[abc.SchedulerBase] = None,
        ):
            nonlocal source

            queue: List[_T] = []

            def on_next(item: _T):
                queue.append(item)

            def on_completed():
                nonlocal queue
                observer.on_next(queue)
                queue = []
                observer.on_completed()

            return source.subscribe(on_next,
                                    observer.on_error,
                                    on_completed,
                                    scheduler=scheduler)

        return Observable(subscribe)
예제 #21
0
파일: _catch.py 프로젝트: lizh06/RxPY
def catch_handler(
    source: Observable[_T],
    handler: Callable[[Exception, Observable[_T]], Union[Observable[_T],
                                                         "Future[_T]"]],
) -> Observable[_T]:
    def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None
    ) -> abc.DisposableBase:
        d1 = SingleAssignmentDisposable()
        subscription = SerialDisposable()

        subscription.disposable = d1

        def on_error(exception: Exception) -> None:
            try:
                result = handler(exception, source)
            except Exception as ex:  # By design. pylint: disable=W0703
                observer.on_error(ex)
                return

            result = (reactivex.from_future(result) if isinstance(
                result, Future) else result)
            d = SingleAssignmentDisposable()
            subscription.disposable = d
            d.disposable = result.subscribe(observer, scheduler=scheduler)

        d1.disposable = source.subscribe(observer.on_next,
                                         on_error,
                                         observer.on_completed,
                                         scheduler=scheduler)
        return subscription

    return Observable(subscribe)
예제 #22
0
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.

    Example:
        >>> res = defer(lambda scheduler: of(1, 2, 3))

    Args:
        observable_factory: Observable factory function to invoke for
        each observer that subscribes to the resulting sequence. The
        factory takes a single argument, the scheduler used.

    Returns:
        An observable sequence whose observers trigger an invocation
        of the given observable factory function.
    """
    def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None
    ) -> abc.DisposableBase:
        try:
            result = factory(scheduler or ImmediateScheduler.singleton())
        except Exception as ex:  # By design. pylint: disable=W0703
            return throw(ex).subscribe(observer)

        result = from_future(result) if isinstance(result, Future) else result
        return result.subscribe(observer, scheduler=scheduler)

    return Observable(subscribe)
예제 #23
0
파일: fromcallback.py 프로젝트: lizh06/RxPY
    def function(*args: Any) -> Observable[Any]:
        arguments = list(args)

        def subscribe(
            observer: abc.ObserverBase[Any],
            scheduler: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            def handler(*args: Any) -> None:
                results = list(args)
                if mapper:
                    try:
                        results = mapper(args)
                    except Exception as err:  # pylint: disable=broad-except
                        observer.on_error(err)
                        return

                    observer.on_next(results)
                else:
                    if len(results) <= 1:
                        observer.on_next(*results)
                    else:
                        observer.on_next(results)

                    observer.on_completed()

            arguments.append(handler)
            func(*arguments)
            return Disposable()

        return Observable(subscribe)
예제 #24
0
    def single_or_default_async(source: Observable[_T]) -> Observable[_T]:
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None,
        ):
            value = cast(_T, default_value)
            seen_value = False

            def on_next(x: _T):
                nonlocal value, seen_value

                if seen_value:
                    observer.on_error(
                        Exception("Sequence contains more than one element")
                    )
                else:
                    value = x
                    seen_value = True

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

            return source.subscribe(
                on_next, observer.on_error, on_completed, scheduler=scheduler
            )

        return Observable(subscribe)
예제 #25
0
파일: _observeon.py 프로젝트: lizh06/RxPY
    def observe_on(source: Observable[_T]) -> Observable[_T]:
        """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: abc.ObserverBase[_T],
            subscribe_scheduler: Optional[abc.SchedulerBase] = None,
        ):
            return source.subscribe(ObserveOnObserver(scheduler, observer),
                                    scheduler=subscribe_scheduler)

        return Observable(subscribe)
예제 #26
0
파일: range.py 프로젝트: lizh06/RxPY
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.

    Examples:
        >>> res = range(10)
        >>> res = range(0, 10)
        >>> res = 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: The scheduler to schedule the values on.

    Returns:
        An observable sequence that contains a range of sequential
        integral numbers.
    """

    _stop: int = maxsize if stop is None else stop
    _step: int = 1 if step is None else step

    if step is None and stop is None:
        range_t = range(start)
    elif step is None:
        range_t = range(start, _stop)
    else:
        range_t = range(start, _stop, _step)

    def subscribe(
        observer: abc.ObserverBase[int], scheduler_: Optional[abc.SchedulerBase] = None
    ) -> abc.DisposableBase:
        nonlocal range_t

        _scheduler = scheduler or scheduler_ or CurrentThreadScheduler.singleton()
        sd = MultipleAssignmentDisposable()

        def action(
            scheduler: abc.SchedulerBase, iterator: Optional[Iterator[int]]
        ) -> None:
            try:
                assert iterator
                observer.on_next(next(iterator))
                sd.disposable = _scheduler.schedule(action, state=iterator)
            except StopIteration:
                observer.on_completed()

        sd.disposable = _scheduler.schedule(action, iter(range_t))
        return sd

    return Observable(subscribe)
예제 #27
0
파일: statistics.py 프로젝트: lizh06/RxPY
def mode(source: Observable[Any]) -> Observable[Any]:
    """
    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]))
예제 #28
0
    def distinct_until_changed(source: Observable[_T]) -> Observable[_T]:
        """Returns an observable sequence that contains only distinct
        contiguous elements according to the key_mapper and the
        comparer.

        Examples:
            >>> op = distinct_until_changed();
            >>> op = distinct_until_changed(lambda x: x.id)
            >>> op = distinct_until_changed(lambda x: x.id, lambda x, y: x == y)

        Args:
            key_mapper: [Optional] A function to compute the comparison
                key for each element. If not provided, it projects the
                value.
            comparer: [Optional] Equality comparer for computed key
                values. If not provided, defaults to an equality
                comparer function.

        Returns:
            An observable sequence only containing the distinct
            contiguous elements, based on a computed key value, from
            the source sequence.
        """
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            has_current_key = False
            current_key: _TKey = cast(_TKey, None)

            def on_next(value: _T) -> None:
                nonlocal has_current_key, current_key
                comparer_equals = False
                try:
                    key = key_mapper_(value)
                except Exception as exception:  # pylint: disable=broad-except
                    observer.on_error(exception)
                    return

                if has_current_key:
                    try:
                        comparer_equals = comparer_(current_key, key)
                    except Exception as exception:  # pylint: disable=broad-except
                        observer.on_error(exception)
                        return

                if not has_current_key or not comparer_equals:
                    has_current_key = True
                    current_key = key
                    observer.on_next(value)

            return source.subscribe(on_next,
                                    observer.on_error,
                                    observer.on_completed,
                                    scheduler=scheduler)

        return Observable(subscribe)
예제 #29
0
파일: _merge.py 프로젝트: lizh06/RxPY
    def merge_all(source: Observable[Observable[_T]]) -> Observable[_T]:
        """Partially applied merge_all operator.

        Merges an observable sequence of observable sequences into an
        observable sequence.

        Args:
            source: Source observable to merge.

        Returns:
            The observable sequence that merges the elements of the inner
            sequences.
        """
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None,
        ):
            group = CompositeDisposable()
            is_stopped = [False]
            m = SingleAssignmentDisposable()
            group.add(m)

            def on_next(inner_source: Union[Observable[_T], "Future[_T]"]):
                inner_subscription = SingleAssignmentDisposable()
                group.add(inner_subscription)

                inner_source = (from_future(inner_source) if isinstance(
                    inner_source, Future) else inner_source)

                @synchronized(source.lock)
                def on_completed():
                    group.remove(inner_subscription)
                    if is_stopped[0] and len(group) == 1:
                        observer.on_completed()

                on_next: typing.OnNext[_T] = synchronized(source.lock)(
                    observer.on_next)
                on_error = synchronized(source.lock)(observer.on_error)
                subscription = inner_source.subscribe(on_next,
                                                      on_error,
                                                      on_completed,
                                                      scheduler=scheduler)
                inner_subscription.disposable = subscription

            def on_completed():
                is_stopped[0] = True
                if len(group) == 1:
                    observer.on_completed()

            m.disposable = source.subscribe(on_next,
                                            observer.on_error,
                                            on_completed,
                                            scheduler=scheduler)
            return group

        return Observable(subscribe)
예제 #30
0
파일: utils.py 프로젝트: lizh06/RxPY
def add_ref(xs: "Observable[_T]", r: RefCountDisposable) -> "Observable[_T]":
    from reactivex import Observable

    def subscribe(
            observer: abc.ObserverBase[Any],
            scheduler: Optional[abc.SchedulerBase] = None
    ) -> abc.DisposableBase:
        return CompositeDisposable(r.disposable, xs.subscribe(observer))

    return Observable(subscribe)