This repository has been archived on 2021-03-28. You can view files and clone it, but cannot push or open issues/pull-requests.
frank/frank/module/meta.py

55 lines
1.5 KiB
Python

# =====IMPORTS=====
# Future imports
from __future__ import annotations
# Built-in imports
from functools import cached_property
# Own imports
from .decorators import SimpleCommand, Daemon, Default, RegexCommand
# Typing imports
from typing import TYPE_CHECKING
if TYPE_CHECKING:
# Built-in imports
from typing import List, Any
class ModuleMeta:
def _filter_attrs(self, condition: callable[[Any], bool]) -> List[Any]:
# This prevents an infinite loop of getting the attribute
illegal_names = ["commands", "daemons", "default"]
output = []
for attr in filter(lambda x: x not in illegal_names, dir(self)):
value = getattr(self, attr)
if condition(value):
output.append(value)
return output
@cached_property
def commands(self) -> List[SimpleCommand]:
# This also matches RegexCommand objects
# The sort puts all the RegexCommand objects at the back,making
# them be matched last
return sorted(
self._filter_attrs(lambda val: isinstance(val, SimpleCommand)),
key=lambda x: isinstance(x, RegexCommand),
)
@cached_property
def daemons(self) -> List[Daemon]:
return self._filter_attrs(lambda val: isinstance(val, Daemon))
@cached_property
def default(self) -> Default:
return next(
iter(self._filter_attrs(lambda val: isinstance(val, Default))),
None,
)