Esempio n. 1
0
def test_groupdisposable_clear():
    disp1 = [False]
    disp2 = [False]

    def action1():
        disp1[0] = True

    d1 = Disposable(action1)

    def action2():
        disp2[0] = True

    d2 = Disposable(action2)

    g = CompositeDisposable(d1, d2)
    assert g.length == 2

    g.clear()
    assert disp1[0]
    assert disp2[0]
    assert not g.length

    disp3 = [False]

    def action3():
        disp3[0] = True

    d3 = Disposable(action3)
    g.add(d3)
    assert not disp3[0]
    assert g.length == 1
Esempio n. 2
0
def test_groupdisposable_contains():
    d1 = Disposable()
    d2 = Disposable()

    g = CompositeDisposable(d1, d2)

    assert g.length == 2
    assert g.contains(d1)
    assert g.contains(d2)
Esempio n. 3
0
def test_Disposable_dispose():
    disposed = [False]

    def action():
        disposed[0] = True

    d = Disposable(action)
    assert not disposed[0]
    d.dispose()
    assert disposed[0]
Esempio n. 4
0
 def action_dispose(
     scheduler: abc.SchedulerBase, state: Any = None
 ) -> abc.DisposableBase:
     """Called at dispose time. Defaults to 1000"""
     if subscription:
         subscription.dispose()
     return Disposable()
Esempio n. 5
0
    def schedule_relative(
        self,
        duetime: typing.RelativeTime,
        action: typing.ScheduledAction[_TState],
        state: Optional[_TState] = None,
    ) -> abc.DisposableBase:
        """Schedules an action to be executed after duetime.

        Args:
            duetime: Relative time after which to execute the action.
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        seconds = self.to_seconds(duetime)
        if seconds <= 0.0:
            return self.schedule(action, state=state)

        sad = SingleAssignmentDisposable()

        def interval() -> None:
            sad.disposable = self.invoke_action(action, state=state)

        log.debug("timeout: %s", seconds)
        timer = self._loop.call_later(seconds, interval)

        def dispose() -> None:
            self._loop.remove_timeout(timer)
            self._loop.remove_timeout(timer)

        return CompositeDisposable(sad, Disposable(dispose))
Esempio n. 6
0
    def schedule(self,
                 action: typing.ScheduledAction[_TState],
                 state: Optional[_TState] = None) -> abc.DisposableBase:
        """Schedules an action to be executed.

        Args:
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        sad = SingleAssignmentDisposable()

        def interval() -> None:
            sad.disposable = self.invoke_action(action, state=state)

        timer = self._eventlet.spawn(interval)

        def dispose() -> None:
            timer.kill()

        return CompositeDisposable(sad, Disposable(dispose))
Esempio n. 7
0
    def schedule_relative(
        self,
        duetime: typing.RelativeTime,
        action: typing.ScheduledAction[_TState],
        state: Optional[_TState] = None,
    ) -> abc.DisposableBase:
        """Schedules an action to be executed after duetime.

        Args:
            duetime: Relative time after which to execute the action.
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        sad = SingleAssignmentDisposable()

        def invoke_action() -> None:
            sad.disposable = self.invoke_action(action, state=state)

        msecs = max(0, int(self.to_seconds(duetime) * 1000.0))
        timer = self._root.after(msecs, invoke_action)

        def dispose() -> None:
            self._root.after_cancel(timer)

        return CompositeDisposable(sad, Disposable(dispose))
Esempio n. 8
0
    def schedule_relative(
        self,
        duetime: typing.RelativeTime,
        action: typing.ScheduledAction[_TState],
        state: Optional[_TState] = None,
    ) -> abc.DisposableBase:
        """Schedules an action to be executed after duetime.

        Args:
            duetime: Relative time after which to execute the action.
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """
        msecs = max(0, int(self.to_seconds(duetime) * 1000.0))
        sad = SingleAssignmentDisposable()
        is_disposed = False

        def invoke_action() -> None:
            if not is_disposed:
                sad.disposable = action(self, state)

        log.debug("relative timeout: %sms", msecs)

        # Use static method, let Qt C++ handle QTimer lifetime
        self._qtcore.QTimer.singleShot(msecs, invoke_action)

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

        return CompositeDisposable(sad, Disposable(dispose))
Esempio n. 9
0
    def _subscribe_core(
        self,
        observer: Optional[abc.ObserverBase[_T]] = None,
        scheduler: Optional[abc.SchedulerBase] = None,
    ) -> abc.DisposableBase:
        self.subscriptions.append(Subscription(self.scheduler.clock))
        index = len(self.subscriptions) - 1
        disp = CompositeDisposable()

        def get_action(
                notification: Notification[_T]) -> abc.ScheduledAction[_T]:
            def action(scheduler: abc.SchedulerBase,
                       state: Any = None) -> abc.DisposableBase:
                if observer:
                    notification.accept(observer)
                return Disposable()

            return action

        for message in self.messages:
            notification = message.value
            if not isinstance(notification, Notification):
                raise ValueError("Must be notification")

            # Don't make closures within a loop
            action = get_action(notification)
            disp.add(self.scheduler.schedule_relative(message.time, action))

        def dispose() -> None:
            start = self.subscriptions[index].subscribe
            end = self.scheduler.to_seconds(self.scheduler.now)
            self.subscriptions[index] = Subscription(start, int(end))
            disp.dispose()

        return Disposable(dispose)
Esempio n. 10
0
    def schedule_relative(
        self,
        duetime: typing.RelativeTime,
        action: typing.ScheduledAction[_TState],
        state: Optional[_TState] = None,
    ) -> abc.DisposableBase:
        """Schedules an action to be executed after duetime.

        Args:
            duetime: Relative time after which to execute the action.
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        seconds = max(0.0, self.to_seconds(duetime))

        sad = SingleAssignmentDisposable()

        def interval() -> None:
            sad.disposable = action(self, state)

        log.debug("timeout: %s", seconds)
        timer = self._reactor.callLater(seconds, interval)

        def dispose() -> None:
            if not timer.called:
                timer.cancel()

        return CompositeDisposable(sad, Disposable(dispose))
Esempio n. 11
0
 def action_create(
     scheduler: abc.SchedulerBase, state: Any = None
 ) -> abc.DisposableBase:
     """Called at create time. Defaults to 100"""
     nonlocal source
     source = create() if create is not None else reactivex.never()
     return Disposable()
Esempio n. 12
0
    def schedule(self,
                 action: typing.ScheduledAction[_TState],
                 state: Optional[_TState] = None) -> abc.DisposableBase:
        """Schedules an action to be executed.

        Args:
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """
        sad = SingleAssignmentDisposable()
        is_disposed = False

        def invoke_action() -> None:
            if not is_disposed:
                sad.disposable = action(self, state)

        self._wx.CallAfter(invoke_action)

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

        return CompositeDisposable(sad, Disposable(dispose))
Esempio n. 13
0
    def schedule(self,
                 action: typing.ScheduledAction[_TState],
                 state: Optional[_TState] = None) -> abc.DisposableBase:
        """Schedules an action to be executed.

        Args:
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """
        sad = SingleAssignmentDisposable()

        def interval() -> None:
            sad.disposable = self.invoke_action(action, state=state)

        handle = self._loop.call_soon_threadsafe(interval)

        def dispose() -> None:
            if self._on_self_loop_or_not_running():
                handle.cancel()
                return

            future: "Future[int]" = Future()

            def cancel_handle() -> None:
                handle.cancel()
                future.set_result(0)

            self._loop.call_soon_threadsafe(cancel_handle)
            future.result()

        return CompositeDisposable(sad, Disposable(dispose))
Esempio n. 14
0
 def _subscribe_core(
     self,
     observer: abc.ObserverBase[_T],
     scheduler: Optional[abc.SchedulerBase] = None,
 ) -> abc.DisposableBase:
     return self._subscribe(observer,
                            scheduler) if self._subscribe else Disposable()
Esempio n. 15
0
        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()
Esempio n. 16
0
    def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler_: Optional[abc.SchedulerBase] = None
    ) -> abc.DisposableBase:
        _scheduler = scheduler or scheduler_ or CurrentThreadScheduler.singleton(
        )
        iterator = iter(iterable)
        disposed = False

        def action(_: abc.SchedulerBase, __: 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)
Esempio n. 17
0
 def action_subscribe(
     scheduler: abc.SchedulerBase, state: Any = None
 ) -> abc.DisposableBase:
     """Called at subscribe time. Defaults to 200"""
     nonlocal subscription
     if source:
         subscription = source.subscribe(observer, scheduler=scheduler)
     return Disposable()
Esempio n. 18
0
 def wrapped_action(
         self: abc.SchedulerBase,
         state: Optional[_TState]) -> Optional[abc.DisposableBase]:
     try:
         return action(parent._get_recursive_wrapper(self), state)
     except Exception as ex:
         if not parent._handler(ex):
             raise
         return Disposable()
Esempio n. 19
0
 def subscribe(
     observer: abc.ObserverBase[_T],
     scheduler: Optional[abc.SchedulerBase] = None,
 ) -> abc.DisposableBase:
     return CompositeDisposable(
         merged_disposable.disposable
         if merged_disposable else Disposable(),
         underlying_observable.subscribe(observer, scheduler=scheduler),
     )
Esempio n. 20
0
    def schedule_relative(
        self,
        duetime: typing.RelativeTime,
        action: typing.ScheduledAction[_TState],
        state: Optional[_TState] = None,
    ) -> abc.DisposableBase:
        """Schedules an action to be executed after duetime.

        Args:
            duetime: Relative time after which to execute the action.
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """
        seconds = self.to_seconds(duetime)
        if seconds <= 0:
            return self.schedule(action, state=state)

        sad = SingleAssignmentDisposable()

        def interval() -> None:
            sad.disposable = self.invoke_action(action, state=state)

        # the operations on the list used here are atomic, so there is no
        # need to protect its access with a lock
        handle: List[asyncio.Handle] = []

        def stage2() -> None:
            handle.append(self._loop.call_later(seconds, interval))

        handle.append(self._loop.call_soon_threadsafe(stage2))

        def dispose() -> None:
            def do_cancel_handles() -> None:
                try:
                    handle.pop().cancel()
                    handle.pop().cancel()
                except Exception:
                    pass

            if self._on_self_loop_or_not_running():
                do_cancel_handles()
                return

            future: "Future[int]" = Future()

            def cancel_handle() -> None:
                do_cancel_handles()
                future.set_result(0)

            self._loop.call_soon_threadsafe(cancel_handle)
            future.result()

        return CompositeDisposable(sad, Disposable(dispose))
Esempio n. 21
0
    def schedule_absolute(self,
                          due: AbsoluteTime,
                          action: ScheduledAction,
                          state: Optional[TState] = None) -> Disposable:
        item = ScheduledItem(self, state, action, self.to_datetime(due))

        self._queue.put(item)

        return Disposable(item.cancel)
Esempio n. 22
0
        def fix_subscriber(
            subscriber: Union[abc.DisposableBase, Callable[[], None]]
        ) -> abc.DisposableBase:
            """Fixes subscriber to make sure it returns a Disposable instead
            of None or a dispose function"""

            if isinstance(subscriber, abc.DisposableBase) or hasattr(
                    subscriber, "dispose"):
                # Note: cast can be avoided using Protocols (Python 3.9)
                return cast(abc.DisposableBase, subscriber)

            return Disposable(subscriber)
Esempio n. 23
0
def test_groupdisposable_addafterdispose():
    disp1 = [False]
    disp2 = [False]

    def action1():
        disp1[0] = True

    d1 = Disposable(action1)

    def action2():
        disp2[0] = True

    d2 = Disposable(action2)

    g = CompositeDisposable(d1)
    assert g.length == 1
    g.dispose()
    assert disp1[0]
    assert g.length == 0
    g.add(d2)
    assert disp2[0]
    assert g.length == 0
Esempio n. 24
0
def test_mutabledisposable_replacebeforedispose():
    disp1 = [False]
    disp2 = [False]
    m = SerialDisposable()

    def action1():
        disp1[0] = True

    d1 = Disposable(action1)
    m.disposable = d1

    assert d1 == m.disposable
    assert not disp1[0]

    def action2():
        disp2[0] = True

    d2 = Disposable(action2)
    m.disposable = d2

    assert d2 == m.disposable
    assert disp1[0]
    assert not disp2[0]
Esempio n. 25
0
def test_mutabledisposable_replaceafterdispose():
    disp1 = [False]
    disp2 = [False]
    m = SerialDisposable()
    m.dispose()

    def action1():
        disp1[0] = True

    d1 = Disposable(action1)
    m.disposable = d1

    assert m.disposable == None
    assert disp1[0]

    def action2():
        disp2[0] = True

    d2 = Disposable(action2)
    m.disposable = d2

    assert m.disposable == None
    assert disp2[0]
Esempio n. 26
0
def test_groupdisposable_remove():
    disp1 = [False]
    disp2 = [False]

    def action1():
        disp1[0] = True

    d1 = Disposable(action1)

    def action2():
        disp2[0] = True

    d2 = Disposable(action2)

    g = CompositeDisposable(d1, d2)

    assert g.length == 2
    assert g.contains(d1)
    assert g.contains(d2)
    assert g.remove(d1)
    assert g.length == 1
    assert not g.contains(d1)
    assert g.contains(d2)
    assert disp1[0]
    assert g.remove(d2)
    assert not g.contains(d1)
    assert not g.contains(d2)
    assert disp2[0]

    disp3 = [False]

    def action3():
        disp3[0] = True

    d3 = Disposable(action3)
    assert not g.remove(d3)
    assert not disp3[0]
Esempio n. 27
0
def test_mutabledisposable_dispose():
    disp = [False]
    m = SerialDisposable()

    def action():
        disp[0] = True

    d = Disposable(action)
    m.disposable = d

    assert d == m.disposable
    assert not disp[0]
    m.dispose()
    assert disp[0]
    assert m.disposable == None
Esempio n. 28
0
def test_futuredisposable_disposeafterset():
    d = SingleAssignmentDisposable()
    disposed = [False]

    def action():
        disposed[0] = True

    dd = Disposable(action)
    d.disposable = dd
    assert dd == d.disposable
    assert not disposed[0]

    d.dispose()
    assert disposed[0]
    d.dispose()
    assert disposed[0]
Esempio n. 29
0
        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)
Esempio n. 30
0
def test_futuredisposable_disposebeforeset():
    disposed = [False]

    def dispose():
        disposed[0] = True

    d = SingleAssignmentDisposable()
    dd = Disposable(dispose)

    assert not disposed[0]
    d.dispose()
    assert not disposed[0]
    d.disposable = dd
    assert d.disposable == None
    assert disposed[0]
    d.dispose()
    assert disposed[0]