diff --git a/CHANGES/682.misc b/CHANGES/682.misc new file mode 100644 index 00000000..a1a18c67 --- /dev/null +++ b/CHANGES/682.misc @@ -0,0 +1 @@ +Reworked **handlers_in_use** util. Function moved to Router as method **.resolve_used_update_types()** diff --git a/aiogram/dispatcher/router.py b/aiogram/dispatcher/router.py index b776bcdf..8f2df80b 100644 --- a/aiogram/dispatcher/router.py +++ b/aiogram/dispatcher/router.py @@ -1,7 +1,7 @@ from __future__ import annotations import warnings -from typing import Any, Dict, Generator, List, Optional, Union +from typing import Any, Dict, Generator, List, Optional, Set, Union from ..types import TelegramObject from ..utils.imports import import_module @@ -11,6 +11,8 @@ from .event.event import EventObserver from .event.telegram import TelegramEventObserver from .filters import BUILTIN_FILTERS +INTERNAL_UPDATE_TYPES = frozenset({"update", "error"}) + class Router: """ @@ -91,6 +93,27 @@ class Router: def __repr__(self) -> str: return f"<{self}>" + def resolve_used_update_types(self, skip_events: Optional[Set[str]] = None) -> List[str]: + """ + Resolve registered event names + + Is useful for getting updates only for registered event types. + + :param skip_events: skip specified event names + :return: set of registered names + """ + handlers_in_use: Set[str] = set() + if skip_events is None: + skip_events = set() + skip_events = {*skip_events, *INTERNAL_UPDATE_TYPES} + + for router in self.chain_tail: + for update_name, observer in router.observers.items(): + if observer.handlers and update_name not in skip_events: + handlers_in_use.add(update_name) + + return list(sorted(handlers_in_use)) + async def propagate_event(self, update_type: str, event: TelegramObject, **kwargs: Any) -> Any: kwargs.update(event_router=self) observer = self.observers[update_type] diff --git a/aiogram/utils/handlers_in_use.py b/aiogram/utils/handlers_in_use.py deleted file mode 100644 index c1816476..00000000 --- a/aiogram/utils/handlers_in_use.py +++ /dev/null @@ -1,28 +0,0 @@ -from itertools import chain -from typing import List, cast - -from aiogram.dispatcher.dispatcher import Dispatcher -from aiogram.dispatcher.router import Router - -INTERNAL_HANDLERS = [ - "update", - "error", -] - - -def get_handlers_in_use( - dispatcher: Dispatcher, handlers_to_skip: List[str] = INTERNAL_HANDLERS -) -> List[str]: - handlers_in_use: List[str] = [] - - for router in [dispatcher.sub_routers, dispatcher]: - if isinstance(router, list): - if router: - handlers_in_use.extend(chain(*list(map(get_handlers_in_use, router)))) - else: - router = cast(Router, router) - for update_name, observer in router.observers.items(): - if observer.handlers and update_name not in [*handlers_to_skip, *handlers_in_use]: - handlers_in_use.append(update_name) - - return handlers_in_use diff --git a/examples/specify_updates.py b/examples/specify_updates.py index 5877a33c..1ad3cd0f 100644 --- a/examples/specify_updates.py +++ b/examples/specify_updates.py @@ -5,7 +5,6 @@ from aiogram.dispatcher.router import Router from aiogram.types import CallbackQuery, ChatMemberUpdated, Message from aiogram.types.inline_keyboard_button import InlineKeyboardButton from aiogram.types.inline_keyboard_markup import InlineKeyboardMarkup -from aiogram.utils.handlers_in_use import get_handlers_in_use TOKEN = "6wo" dp = Dispatcher() @@ -33,7 +32,7 @@ async def chat_member_update(chat_member: ChatMemberUpdated, bot: Bot) -> None: await bot.send_message( chat_member.chat.id, "Member {chat_member.from_user.id} was changed " - + f"from {chat_member.old_chat_member.is_chat_member} to {chat_member.new_chat_member.is_chat_member}", + + f"from {chat_member.old_chat_member.status} to {chat_member.new_chat_member.status}", ) @@ -64,7 +63,7 @@ async def my_chat_member_change(chat_member: ChatMemberUpdated, bot: Bot) -> Non await bot.send_message( chat_member.chat.id, "Member was changed from " - + f"{chat_member.old_chat_member.is_chat_member} to {chat_member.new_chat_member.is_chat_member}", + + f"{chat_member.old_chat_member.status} to {chat_member.new_chat_member.status}", ) @@ -77,7 +76,7 @@ def main() -> None: dp.include_router(sub_router) dp.include_router(sub_sub_router) - useful_updates = get_handlers_in_use(dp) + useful_updates = dp.resolve_used_update_types() # And the run events dispatching dp.run_polling(bot, allowed_updates=useful_updates) diff --git a/tests/test_dispatcher/test_dispatcher.py b/tests/test_dispatcher/test_dispatcher.py index 520b190c..30f10970 100644 --- a/tests/test_dispatcher/test_dispatcher.py +++ b/tests/test_dispatcher/test_dispatcher.py @@ -29,7 +29,6 @@ from aiogram.types import ( Update, User, ) -from aiogram.utils.handlers_in_use import get_handlers_in_use from tests.mocked_bot import MockedBot try: @@ -737,30 +736,30 @@ class TestDispatcher: router21 = Router() router21.edited_message.register(simple_edited_msg_handler) - useful_updates1 = get_handlers_in_use(dispatcher) + useful_updates1 = dispatcher.resolve_used_update_types() assert sorted(useful_updates1) == sorted(["message"]) dispatcher.include_router(router1) - useful_updates2 = get_handlers_in_use(dispatcher) + useful_updates2 = dispatcher.resolve_used_update_types() assert sorted(useful_updates2) == sorted(["message", "callback_query"]) dispatcher.include_router(router2) - useful_updates3 = get_handlers_in_use(dispatcher) + useful_updates3 = dispatcher.resolve_used_update_types() assert sorted(useful_updates3) == sorted(["message", "callback_query", "poll"]) router2.include_router(router21) - useful_updates4 = get_handlers_in_use(dispatcher) + useful_updates4 = dispatcher.resolve_used_update_types() assert sorted(useful_updates4) == sorted( ["message", "callback_query", "poll", "edited_message"] ) - useful_updates5 = get_handlers_in_use(router2) + useful_updates5 = router2.resolve_used_update_types() assert sorted(useful_updates5) == sorted(["poll", "edited_message"])