Ejemplo n.º 1
0
    def assert_not_registered(self,
                              cmd_or_alias: str,
                              context: VerediContext) -> None:
        '''
        Raises a CommandRegisterError if `cmd_or_alias` is already registered
        as a command or an alias.
        '''
        existing, _ = self.get(cmd_or_alias)
        if not existing:
            return

        kwargs = log.incr_stack_level(None)
        msg = ("A command named '{}' already registered '{}'; cannot "
               "register another. command: {}").format(existing.name,
                                                       cmd_or_alias,
                                                       existing)
        error = CommandRegisterError(msg, None,
                                     context=context,
                                     data={
                                         'existing': existing,
                                         'existing.name': existing.name,
                                         'cmd_or_alias': cmd_or_alias,
                                     })
        raise self._log_exception(error,
                                  msg,
                                  context=context,
                                  **kwargs)
Ejemplo n.º 2
0
    def exception(klass:      Type['config'],
                  context:    Optional['VerediContext'],
                  msg:        Optional[str],
                  *args:      Any,
                  error_data: Optional[Mapping[Any, Any]] = None,
                  **kwargs:   Any) -> None:
        '''
        Calls log.exception() to raise a ConfigError with message built from
        msg, args, kwargs and with supplied context.

        NOTE: If no context is supplied, WILL NOT LOG ANY! Provide
        config.make_config_context() if you are using it as your default!

        Sets stack level one more than usual so that caller of this should be
        the stacktrace of the exception.

        If optional `error_data` is not None, it will be supplied to the
        created ConfigError as the `data` parameter in the constructor.
        '''
        kwargs = log.incr_stack_level(kwargs)
        # If we raised instead of returned, we could add an extra stacklevel to
        # get the log back to whoever called us...
        #                             amount=2)

        # Let a generic ConfigError be made.
        return log.exception(
            ConfigError,
            msg, *args, **kwargs,
            error_data=error_data,
            context=context)
Ejemplo n.º 3
0
 def debug(self, msg: str, *args: Any, **kwargs: Any) -> None:
     '''
     Debug logs go through our callback if we have it. Otherwise just use
     log.debug.
     '''
     kwargs = log.incr_stack_level(kwargs)
     call = self._debug_fn if self._debug_fn else log.debug
     call(msg, *args, **kwargs)
Ejemplo n.º 4
0
 def next(self, value: CurrNextT) -> None:
     '''
     Sets next value.
     '''
     if self._freeze_next:
         kwargs = log.incr_stack_level(None)
         log.info(
             f"Currently next is frozen at {self._next}; "
             f"cannot set next value to {value}.", **kwargs)
         return
     self._next = value
Ejemplo n.º 5
0
 def debug(self, msg: str, *args: Any, **kwargs: Any) -> None:
     '''
     Debug logs if our DebugFlag has the proper bits set for Mediator
     debugging.
     '''
     if (self._debug and self._debug.any(DebugFlag.MEDIATOR_BASE,
                                         DebugFlag.MEDIATOR_CLIENT)):
         msg = f"{self.name}: " + msg
         kwargs = log.incr_stack_level(kwargs)
         self._log_data_processing(self.dotted,
                                   msg,
                                   *args,
                                   **kwargs,
                                   log_minimum=log.Level.DEBUG)
Ejemplo n.º 6
0
    def _log(self,
             context:      InputContext,
             level:        log.Level,
             entity:       Entity,
             command_name: str,
             command_safe: str,
             message:      str,
             *args:        Any,
             **kwargs:     Any) -> None:
        '''
        Format command info from context into standard command log message,
        then append message and call log.at_level().

        Log's stack level (for method/class auto-print by logger) should be at
        level of caller of this function.
        '''
        ident = entity.get(IdentityComponent)
        ent_name = ident.log_name
        cmd_info = {
            'source': {
                'name': ent_name,
                'group': ident.group,
                'controller': ident.controller,
                # todo: controller entity id, user id
            },
            'name': command_name,
            'input': command_safe,
        }

        fmt_pre = "- command: '{}' invoked by '{}' - "
        msg_pre = fmt_pre.format(command_name, ent_name)
        msg_post = '\n' + pretty.indented(cmd_info)

        log_fmt = msg_pre + message + '{msg_post}'
        kwargs['msg_post'] = msg_post
        log.incr_stack_level(kwargs)
        self._log_at_level(level, log_fmt, *args, **kwargs)
Ejemplo n.º 7
0
    def add(self, cls_or_func: 'RegisterType',
            *dotted_label: label.LabelInput) -> None:
        '''
        This function does the actual registration.
        '''
        # Ignored?
        if self.ignored(cls_or_func):
            msg = (f"{cls_or_func} is in our set of ignored "
                   "classes/functions that should not be registered.")
            error = RegistryError(msg,
                                  data={
                                      'registree': cls_or_func,
                                      'dotted': label.normalize(dotted_label),
                                      'ignored': self._ignore,
                                  })
            raise log.exception(error, msg)

        # Do any initial steps.
        dotted_list = label.regularize(*dotted_label)
        if not self._init_register(cls_or_func, dotted_list):
            # Totally ignore if not successful. _init_register() should do
            # all the erroring itself.
            return

        # Pull final key off of list so we don't make too many
        # dictionaries.
        name = str(cls_or_func)
        try:
            # Final key where the registration will actually be stored.
            leaf_key = dotted_list[-1]
        except IndexError as error:
            kwargs = log.incr_stack_level(None)
            raise log.exception(
                RegistryError, "Need to know what to register this ({}) as. "
                "E.g. @register('jeff', 'geoff'). Got no dotted_list: {}",
                name, dotted_list, **kwargs) from error

        # Our register - full info saved here.
        registry_our = self._registry

        # Background register - just names saved here.
        registry_bg = background.registry.registry(self.dotted)

        # ------------------------------
        # Get reg dicts to the leaf.
        # ------------------------------

        length = len(dotted_list)
        # -1 as we've got our config name already from that final
        # dotted_list entry.
        for i in range(length - 1):
            # Walk down into both dicts, making new empty sub-entries as
            # necessary.
            registry_our = registry_our.setdefault(dotted_list[i], {})
            registry_bg = registry_bg.setdefault(dotted_list[i], {})

        # ------------------------------
        # Register (warn if occupied).
        # ------------------------------

        # Helpful messages - but registering either way.
        try:
            if leaf_key in registry_our:
                if background.testing.get_unit_testing():
                    msg = ("Something was already registered under this "
                           f"registry_our key... keys: {dotted_list}, "
                           f"replacing {str(registry_our[leaf_key])}' with "
                           f"this '{name}'.")
                    error = KeyError(leaf_key, msg, cls_or_func)
                    log.exception(error, None, msg, stacklevel=3)
                else:
                    log.warning(
                        "Something was already registered under this "
                        "registry_our key... keys: {}, replacing "
                        "'{}' with this '{}'",
                        dotted_list,
                        str(registry_our[leaf_key]),
                        name,
                        stacklevel=3)
            else:
                log.debug("Registered: keys: {}, value '{}'",
                          dotted_list,
                          name,
                          stacklevel=3)
        except TypeError as error:
            msg = (f"{self.klass}.add(): Our "
                   "'registry_our' dict is the incorrect type? Expected "
                   "something that can deal with 'in' operator. Have: "
                   f"{type(registry_our)} -> {registry_our}. Trying to "
                   f"register {cls_or_func} at "
                   f"'{label.normalize(dotted_list)}'. "
                   "Registry: \n{}")
            from veredi.base.strings import pretty
            log.exception(error, msg, pretty.indented(self._registry))
            # Reraise it. Just want more info.
            raise

        # Register cls/func to our registry, save some info to our
        # background registry.
        self._register(cls_or_func, dotted_list, leaf_key, registry_our,
                       registry_bg)

        # ------------------------------
        # Finalize (if desired).
        # ------------------------------
        self._finalize_register(cls_or_func, dotted_list, registry_our,
                                registry_bg)