mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
Precalculate StateGroup values (#1507)
* Precalculate StateGroup values * Changelog added * Remove redundant overrides * Refactor children preparing * Refactor mcs fn visibility * Refactor mcs fn visibility (fix)
This commit is contained in:
parent
2215df7a0f
commit
9b0b6a68ed
2 changed files with 32 additions and 9 deletions
1
CHANGES/1507.misc.rst
Normal file
1
CHANGES/1507.misc.rst
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Improved performance of StatesGroup
|
||||||
|
|
@ -70,10 +70,13 @@ class StatesGroupMeta(type):
|
||||||
__childs__: "Tuple[Type[StatesGroup], ...]"
|
__childs__: "Tuple[Type[StatesGroup], ...]"
|
||||||
__states__: Tuple[State, ...]
|
__states__: Tuple[State, ...]
|
||||||
__state_names__: Tuple[str, ...]
|
__state_names__: Tuple[str, ...]
|
||||||
|
__all_childs__: Tuple[Type["StatesGroup"], ...]
|
||||||
|
__all_states__: Tuple[State, ...]
|
||||||
|
__all_states_names__: Tuple[str, ...]
|
||||||
|
|
||||||
@no_type_check
|
@no_type_check
|
||||||
def __new__(mcs, name, bases, namespace, **kwargs):
|
def __new__(mcs, name, bases, namespace, **kwargs):
|
||||||
cls = super(StatesGroupMeta, mcs).__new__(mcs, name, bases, namespace)
|
cls = super().__new__(mcs, name, bases, namespace)
|
||||||
|
|
||||||
states = []
|
states = []
|
||||||
childs = []
|
childs = []
|
||||||
|
|
@ -82,14 +85,22 @@ class StatesGroupMeta(type):
|
||||||
if isinstance(arg, State):
|
if isinstance(arg, State):
|
||||||
states.append(arg)
|
states.append(arg)
|
||||||
elif inspect.isclass(arg) and issubclass(arg, StatesGroup):
|
elif inspect.isclass(arg) and issubclass(arg, StatesGroup):
|
||||||
childs.append(arg)
|
child = cls._prepare_child(arg)
|
||||||
arg.__parent__ = cls
|
childs.append(child)
|
||||||
|
|
||||||
cls.__parent__ = None
|
cls.__parent__ = None
|
||||||
cls.__childs__ = tuple(childs)
|
cls.__childs__ = tuple(childs)
|
||||||
cls.__states__ = tuple(states)
|
cls.__states__ = tuple(states)
|
||||||
cls.__state_names__ = tuple(state.state for state in states)
|
cls.__state_names__ = tuple(state.state for state in states)
|
||||||
|
|
||||||
|
cls.__all_childs__ = cls._get_all_childs()
|
||||||
|
cls.__all_states__ = cls._get_all_states()
|
||||||
|
|
||||||
|
# In order to ensure performance, we calculate this parameter
|
||||||
|
# in advance already during the production of the class.
|
||||||
|
# Depending on the relationship, it should be recalculated
|
||||||
|
cls.__all_states_names__ = cls._get_all_states_names()
|
||||||
|
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
@ -98,22 +109,33 @@ class StatesGroupMeta(type):
|
||||||
return ".".join((cls.__parent__.__full_group_name__, cls.__name__))
|
return ".".join((cls.__parent__.__full_group_name__, cls.__name__))
|
||||||
return cls.__name__
|
return cls.__name__
|
||||||
|
|
||||||
@property
|
def _prepare_child(cls, child: Type["StatesGroup"]) -> Type["StatesGroup"]:
|
||||||
def __all_childs__(cls) -> Tuple[Type["StatesGroup"], ...]:
|
"""Prepare child.
|
||||||
|
|
||||||
|
While adding `cls` for its children, we also need to recalculate
|
||||||
|
the parameter `__all_states_names__` for each child
|
||||||
|
`StatesGroup`. Since the child class appears before the
|
||||||
|
parent, at the time of adding the parent, the child's
|
||||||
|
`__all_states_names__` is already recorded without taking into
|
||||||
|
account the name of current parent.
|
||||||
|
"""
|
||||||
|
child.__parent__ = cls # type: ignore[assignment]
|
||||||
|
child.__all_states_names__ = child._get_all_states_names()
|
||||||
|
return child
|
||||||
|
|
||||||
|
def _get_all_childs(cls) -> Tuple[Type["StatesGroup"], ...]:
|
||||||
result = cls.__childs__
|
result = cls.__childs__
|
||||||
for child in cls.__childs__:
|
for child in cls.__childs__:
|
||||||
result += child.__childs__
|
result += child.__childs__
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@property
|
def _get_all_states(cls) -> Tuple[State, ...]:
|
||||||
def __all_states__(cls) -> Tuple[State, ...]:
|
|
||||||
result = cls.__states__
|
result = cls.__states__
|
||||||
for group in cls.__childs__:
|
for group in cls.__childs__:
|
||||||
result += group.__all_states__
|
result += group.__all_states__
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@property
|
def _get_all_states_names(cls) -> Tuple[str, ...]:
|
||||||
def __all_states_names__(cls) -> Tuple[str, ...]:
|
|
||||||
return tuple(state.state for state in cls.__all_states__ if state.state)
|
return tuple(state.state for state in cls.__all_states__ if state.state)
|
||||||
|
|
||||||
def __contains__(cls, item: Any) -> bool:
|
def __contains__(cls, item: Any) -> bool:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue