Пример #1
0
    def _inner(fun: PushFunction) -> PushFunction:
        validator.is_function(fun=fun)

        def _call(self: 'Push',
                  envelope: Optional[Envelope] = None,
                  payload: Payload = None,
                  **kwargs: Any) -> Payload:
            validator.is_instance(Push, self=self)
            parsed = self._parse_envelope_value(value, envelope=envelope)

            new_kwargs = {value: parsed, 'payload': payload}
            if envelope is not None:
                new_kwargs['envelope'] = envelope

            return fun(self, **{**new_kwargs, **kwargs})

        if asyncio.iscoroutinefunction(fun):

            @functools.wraps(fun)
            async def _wrapper(self: 'Push',
                               envelope: Optional[Envelope] = None,
                               payload: Payload = None,
                               **kwargs: Any) -> Payload:
                return await _call(self, envelope, payload, **kwargs)

            return _wrapper

        return functools.wraps(fun)(_call)
Пример #2
0
    def _parse_envelope_value(
        self,
        name: str,
        envelope: Optional[Envelope] = None,
        parse_fun: Optional[Callable[[Any], Any]] = None,
        instance_lookup_fun: Optional[Callable[...,
                                               Optional[Any]]] = None) -> Any:
        """
        Parse the envelope for the given `name`. If present in the envelope the extracted value will
        be tested / parsed by the given `parse_fun`. If no `parse_fun` is explicitly given, it will
        be determined if this instance provides a `parse_<name>`, `_parse_<name>` or a
        `__parse_<name>`. If yes the function is called; otherwise the value is returned as is.

        If the value is not present in the envelope the current instance will be probed for
        `<name>`, `_<name>` or `__<name>`. If an instance variable is present it will be returned
        unvalidated / unparsed (we assume that happened previously). If no variable is present
        simply `None` will be returned.

        Args:
            name: Name of the attribute to lookup in the envelope / instance.
            envelope: Envelope of the payload.
            parse_fun: Custom function to validate / parse. If not given it will be determined
                automagically.
            instance_lookup_fun: Custom function to perform instance variable lookups.
                If not given a reasonably default will be used.
        """
        validator.is_instance(str, name=name)
        validator.is_instance(dict, allow_none=True, envelope=envelope)
        if parse_fun:
            validator.is_function(parse_fun=parse_fun)
        if instance_lookup_fun:
            validator.is_function(instance_lookup_fun=instance_lookup_fun)

        lookups = cast(
            Dict[str, str],
            utils.make_public_protected_private_attr_lookup(name,
                                                            as_dict=True))

        if envelope is None or name not in envelope:
            return (instance_lookup_fun(name) if instance_lookup_fun
                    is not None else _lookup(self, list(lookups.values()))  # pylint: disable=no-member
                    )

        val = envelope[name]
        try:
            if parse_fun is None:
                public_attr_name = lookups['public']  # pylint: disable=invalid-sequence-index
                fun_base = 'parse_' + public_attr_name
                parse_fun_names = utils.make_public_protected_private_attr_lookup(
                    fun_base)
                parse_fun = _lookup(self, parse_fun_names)
                if parse_fun is None:
                    return val
            return parse_fun(val)
        except (ValueError, TypeError):
            self.logger.exception("Cannot parse value for '%s' from envelope",
                                  name)
            return (instance_lookup_fun(name) if instance_lookup_fun
                    is not None else _lookup(self, list(lookups.values()))  # pylint: disable=no-member
                    )
Пример #3
0
 def __init__(self,
              fun: Callable[..., Any],
              cool_down: float = 0.5,
              cool_down_callback: Optional[Callable[[], None]] = None,
              renew_cooldown: bool = True):
     super().__init__(fun, cool_down)
     if cool_down_callback:
         validator.is_function(cool_down_callback=cool_down_callback)
     self.cool_down_callback = cool_down_callback
     self.renew_cooldown = bool(renew_cooldown)
Пример #4
0
async def async_sleep_until_interrupt(sleep_time: float,
                                      interrupt_fun: SleepInterruptPredicate,
                                      interval: float = 0.1) -> None:
    """Call this method to sleep an interruptable sleep until the interrupt co-routine returns
    True."""
    validator.is_function(interrupt_fun=interrupt_fun)

    async def callback() -> None:
        if await interrupt_fun():
            raise StopCycleError()

    await async_interruptible_sleep(sleep_time, callback, interval=interval)
Пример #5
0
def sleep_until_interrupt(sleep_time: float,
                          interrupt_fun: Callable[[], bool],
                          interval: float = 0.5) -> None:
    """Call this method to sleep an interruptable sleep until the interrupt function returns
    True."""
    validator.is_function(interrupt_fun=interrupt_fun)

    def callback() -> None:
        if interrupt_fun():
            raise StopCycleError()

    interruptable_sleep(sleep_time, callback, interval=interval)
Пример #6
0
def enveloped(fun: PushFunction) -> Callable[['Push', Payload], Payload]:
    """Decorator to split the envelope and the actual payload. This is an but a convenience
    decorator for `envelope_payload` of the `PushBase` class."""

    validator.is_function(fun=fun)

    def _call(self: 'Push', payload: Payload) -> Payload:
        validator.is_instance(Push, self=self)
        envelope, real_payload = self.envelope_payload(payload)
        return fun(self, envelope=envelope, payload=real_payload)

    if asyncio.iscoroutinefunction(fun):

        @functools.wraps(fun)
        async def _wrapper(self: 'Push', payload: Payload) -> Payload:
            return await _call(self, payload)

        return _wrapper

    return functools.wraps(fun)(_call)
Пример #7
0
 def __init__(self, fun: Callable[..., Any], wait: float = 0.5):
     validator.is_function(fun=fun)
     self.fun = fun
     self.wait = float(wait)
     self.timer = None  # type: Optional[Timer]
Пример #8
0
 def __init__(self, scheduled_callable, **kwargs):
     super().__init__(**kwargs)
     self.scheduled_callable = scheduled_callable
     validator.is_function(scheduled_callable=self.scheduled_callable)