Ejemplo n.º 1
0
    def register(self, key):
        """
        Decorator that registers a class with the registry.

        Example::

           registry = ClassRegistry(attr_name='widget_type')

           @registry.register
           class CustomWidget(BaseWidget):
             widget_type = 'custom'
             ...

           # Override the registry key:
           @registry.register('premium')
           class AdvancedWidget(BaseWidget):
             ...

        :param key:
            The registry key to use for the registered class.
            Optional if the registry's :py:attr:`attr_name` is set.
        """
        if is_class(key):
            if self.attr_name:
                # Note that ``getattr`` will raise an AttributeError if
                # the class doesn't have the required attribute.
                self._register(getattr(key, self.attr_name), key)
                return key
            else:
                raise ValueError('Registry key is required.')

        def _decorator(cls):
            self._register(key, cls)
            return cls
        return _decorator
Ejemplo n.º 2
0
def iter_filters_in(target):
    # type: (Any) -> Generator[Tuple[Text, Type[BaseFilter]]]
    """
    Iterates over all filters in the specified module/class.
    """
    global legacy_warned
    if not legacy_warned:
        # Set the global flag to ``True`` first, in case the user has
        # ``simplefilter('error')`` set.
        legacy_warned = True

        warn(
            'Legacy extension loader is deprecated and will be removed in '
            'Filters v1.4.  '
            'See http://filters.readthedocs.io/en/latest/extensions.html#legacy-extensions-loader '
            'for more information.',
            DeprecationWarning,
        )

    ift_result = is_filter_type(target)

    if ift_result is True:
        logger.debug(
            'Registering extension filter '
            '{cls.__module__}.{cls.__name__}.'.format(cls=target, ), )

        yield target.__name__, target
    elif is_module(target):
        for member_name, member in get_members(target):
            member_ift_result = is_filter_type(member)

            if member_ift_result is True:
                logger.debug(
                    'Registering extension filter '
                    '{cls.__module__}.{cls.__name__}.'.format(cls=member, ), )

                yield member.__name__, member
            else:
                logger.debug(
                    'Ignoring {module}.{name} ({reason})'.format(
                        module=target.__name__,
                        name=member_name,
                        reason=member_ift_result,
                    ), )
    elif is_class(target):
        logger.debug(
            'Ignoring {cls.__module__}.{cls.__name__} ({reason}).'.format(
                cls=target,
                reason=ift_result,
            ), )
    else:
        logger.debug(
            'Ignoring {target!r} ({reason}).'.format(
                reason=ift_result,
                target=target,
            ), )
Ejemplo n.º 3
0
    def register(self, key):

        if is_class(key):
            if self.attr_name:
                self._register(getattr(key, self.attr_name), key)
                return key
            else:
                raise ValueError('Registry key is required.')

        def _decorator(cls):
            self._register(key, cls)
            return cls

        return _decorator
Ejemplo n.º 4
0
def is_filter_type(target: typing.Any) -> typing.Union[bool, str]:
    """
    Returns whether the specified object can be registered as a filter.

    :return:
        Returns ``True`` if the object is a filter.
        Otherwise, returns a string indicating why it is not valid.
    """
    if not is_class(target):
        return 'not a class'

    if not issubclass(target, BaseFilter):
        return 'does not extend BaseFilter'

    if is_abstract(target):
        return 'abstract class'

    return True
Ejemplo n.º 5
0
    def register(self, key):
        if is_class(key):
            if not key.tag_name:
                raise ValueError("Unable to register tag: unable to determine "
                                 "name neither from @tag(name=...) decorator "
                                 "nor from tag_name = '...' class attribute")
            return self._register(key.tag_name, key)

        def _decorator(cls):
            if cls.tag_name:
                raise ValueError(
                    "Names conflict: @tag(name='{}') overrides class "
                    "tag_name = '{}' attribute".format(key, cls.tag_name))
            cls.tag_name = key

            return self._register(key, cls)

        return _decorator
Ejemplo n.º 6
0
def iter_filters_in(
    target: typing.Any,
) -> typing.Generator[typing.Tuple[str, typing.Type[BaseFilter]], None, None]:
    """
    Iterates over all filters in the specified module/class.
    """
    ift_result = is_filter_type(target)

    if ift_result is True:
        logger.debug(
            'Registering extension filter '
            '{cls.__module__}.{cls.__name__}.'.format(cls=target, ), )

        yield target.__name__, target
    elif is_module(target):
        for member_name, member in get_members(target):
            member_ift_result = is_filter_type(member)

            if member_ift_result is True:
                logger.debug(
                    'Registering extension filter '
                    '{cls.__module__}.{cls.__name__}.'.format(cls=member, ), )

                yield member.__name__, member
            else:
                logger.debug(
                    'Ignoring {module}.{name} ({reason})'.format(
                        module=target.__name__,
                        name=member_name,
                        reason=member_ift_result,
                    ), )
    elif is_class(target):
        logger.debug(
            'Ignoring {cls.__module__}.{cls.__name__} ({reason}).'.format(
                cls=target,
                reason=ift_result,
            ), )
    else:
        logger.debug(
            'Ignoring {target!r} ({reason}).'.format(
                reason=ift_result,
                target=target,
            ), )
Ejemplo n.º 7
0
def discover_commands(package, recursively=True):
    # type: (Union[ModuleType, Text], bool) -> Dict[Text, 'CommandMeta']
    """
  Automatically discover commands in the specified package.

  :param package:
    Package path or reference.

  :param recursively:
    If True, will descend recursively into sub-packages.

  :return:
    All commands discovered in the specified package, indexed by
    command name (note: not class name).
  """
    # http://stackoverflow.com/a/25562415/
    if isinstance(package, string_types):
        package = import_module(package)  # type: ModuleType

    commands = {}

    for _, name, is_package in walk_packages(package.__path__,
                                             package.__name__ + '.'):
        # Loading the module is good enough; the CommandMeta metaclass will
        # ensure that any commands in the module get registered.

        # Prefix in name module move to function "walk_packages" for fix
        # conflict with names importing packages
        # Bug https://github.com/iotaledger/iota.lib.py/issues/63
        sub_package = import_module(name)

        # Index any command classes that we find.
        for (_, obj) in get_members(sub_package):
            if is_class(obj) and isinstance(obj, CommandMeta):
                command_name = getattr(obj, 'command')
                if command_name:
                    commands[command_name] = obj

        if recursively and is_package:
            commands.update(discover_commands(sub_package))

    return commands
Ejemplo n.º 8
0
def discover_commands(package, recursively=True):
  # type: (Union[ModuleType, Text], bool) -> Dict[Text, 'CommandMeta']
  """
  Automatically discover commands in the specified package.

  :param package:
    Package path or reference.

  :param recursively:
    If True, will descend recursively into sub-packages.

  :return:
    All commands discovered in the specified package, indexed by
    command name (note: not class name).
  """
  # http://stackoverflow.com/a/25562415/
  if isinstance(package, string_types):
    package = import_module(package) # type: ModuleType

  commands = {}

  for _, name, is_package in walk_packages(package.__path__, package.__name__ + '.'):
    # Loading the module is good enough; the CommandMeta metaclass will
    # ensure that any commands in the module get registered.

    # Prefix in name module move to function "walk_packages" for fix
    # conflict with names importing packages
    # Bug https://github.com/iotaledger/iota.lib.py/issues/63
    sub_package = import_module(name)

    # Index any command classes that we find.
    for (_, obj) in get_members(sub_package):
      if is_class(obj) and isinstance(obj, CommandMeta):
        command_name = getattr(obj, 'command')
        if command_name:
          commands[command_name] = obj

    if recursively and is_package:
      commands.update(discover_commands(sub_package))

  return commands