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

54 lines
1.4 KiB
Python
Raw Normal View History

2020-08-25 17:07:27 +02:00
# =====IMPORTS=====
# Future imports
from __future__ import annotations
# Built-in imports
from functools import cached_property
# Own imports
2020-08-26 13:05:56 +02:00
from .decorators import Command, Daemon, Default, RegexCommand
2020-08-25 17:07:27 +02:00
# Typing imports
from typing import TYPE_CHECKING
2020-08-25 17:07:27 +02:00
if TYPE_CHECKING:
# Built-in imports
from typing import List, Any
class ModuleMeta:
def _filter_attrs(self, condition: callable[[Any], bool]) -> List[Any]:
2020-08-26 12:22:18 +02:00
# This prevents an infinite loop of getting the attribute
illegal_names = ["commands", "daemons", "default"]
2020-08-25 17:07:27 +02:00
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[Command]:
# This also matches RegexCommand objects
2020-08-26 13:05:56 +02:00
# The sort puts all the RegexCommand objects at the back, making them
# be matched last
return sorted(
self._filter_attrs(lambda val: isinstance(val, Command)),
key=lambda x: isinstance(x, RegexCommand),
)
2020-08-25 17:07:27 +02:00
@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
)