diff --git a/.github/workflows/pypi-release.yml b/.github/workflows/pypi-release.yml index 3dcee3e..2e6169c 100644 --- a/.github/workflows/pypi-release.yml +++ b/.github/workflows/pypi-release.yml @@ -54,7 +54,7 @@ jobs: id-token: write steps: - name: Download artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4.1.7 with: name: dist path: dist diff --git a/aliceio/client/session/aiohttp.py b/aliceio/client/session/aiohttp.py index 95ddefb..a13c08e 100644 --- a/aliceio/client/session/aiohttp.py +++ b/aliceio/client/session/aiohttp.py @@ -85,13 +85,26 @@ def _prepare_connector( class AiohttpSession(BaseSession): - def __init__(self, proxy: Optional[_ProxyType] = None, **kwargs: Any) -> None: + def __init__( + self, + proxy: Optional[_ProxyType] = None, + limit: int = 100, + **kwargs: Any, + ) -> None: + """ + Client session based on aiohttp. + :param proxy: The proxy to be used for requests. Default is None. + :param limit: The total number of simultaneous connections. Default is 100. + :param kwargs: Additional keyword arguments. + """ super().__init__(**kwargs) self._session: Optional[ClientSession] = None self._connector_type: Type[TCPConnector] = TCPConnector self._connector_init: Dict[str, Any] = { "ssl": ssl.create_default_context(cafile=certifi.where()), + "limit": limit, + "ttl_dns_cache": 3600, # https://github.com/aiogram/aiogram/issues/1500 } self._should_reset_connector = True # флаг определяет состояние коннектора self._proxy: Optional[_ProxyType] = None diff --git a/aliceio/fsm/state.py b/aliceio/fsm/state.py index 8e6c579..88c5956 100644 --- a/aliceio/fsm/state.py +++ b/aliceio/fsm/state.py @@ -72,15 +72,13 @@ class StatesGroupMeta(type): __childs__: "Tuple[Type[StatesGroup], ...]" __states__: Tuple[State, ...] __state_names__: Tuple[str, ...] + __all_childs__: Tuple[Type["StatesGroup"], ...] + __all_states__: Tuple[State, ...] + __all_states_names__: Tuple[str, ...] @no_type_check def __new__(mcs, name, bases, namespace, **kwargs): # noqa: ANN204, ANN001, ANN003 - cls = super(StatesGroupMeta, mcs).__new__( # noqa: UP008 - mcs, - name, - bases, - namespace, - ) + cls = super().__new__(mcs, name, bases, namespace) states = [] childs = [] @@ -89,14 +87,22 @@ def __new__(mcs, name, bases, namespace, **kwargs): # noqa: ANN204, ANN001, ANN if isinstance(arg, State): states.append(arg) elif inspect.isclass(arg) and issubclass(arg, StatesGroup): - childs.append(arg) - arg.__parent__ = cls + child = cls._prepare_child(arg) + childs.append(child) cls.__parent__ = None cls.__childs__ = tuple(childs) cls.__states__ = tuple(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 @property @@ -105,22 +111,33 @@ def __full_group_name__(cls) -> str: return f"{cls.__parent__.__full_group_name__}.{cls.__name__}" return cls.__name__ - @property - def __all_childs__(cls) -> Tuple[Type["StatesGroup"], ...]: + def _prepare_child(cls, child: Type["StatesGroup"]) -> 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() # noqa: SLF001 + return child + + def _get_all_childs(cls) -> Tuple[Type["StatesGroup"], ...]: result = cls.__childs__ for child in cls.__childs__: result += child.__childs__ return result - @property - def __all_states__(cls) -> Tuple[State, ...]: + def _get_all_states(cls) -> Tuple[State, ...]: result = cls.__states__ for group in cls.__childs__: result += group.__all_states__ return result - @property - def __all_states_names__(cls) -> Tuple[str, ...]: + def _get_all_states_names(cls) -> Tuple[str, ...]: return tuple(state.state for state in cls.__all_states__ if state.state) def __contains__(cls, item: Any) -> bool: diff --git a/pyproject.toml b/pyproject.toml index 1dd6c85e..0351b5b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,7 +40,7 @@ classifiers = [ ] dependencies = [ "aiofiles~=23.2.1", - "aiohttp~=3.9.0", + "aiohttp>=3.9.0,<3.11", "certifi>=2023.7.22", "magic-filter>=1.0.12,<1.1", "pydantic>=2.4.1,<2.9",