diff --git a/CHANGES/1302.doc b/CHANGES/1302.doc.rst similarity index 68% rename from CHANGES/1302.doc rename to CHANGES/1302.doc.rst index 80cc5492..31220d96 100644 --- a/CHANGES/1302.doc +++ b/CHANGES/1302.doc.rst @@ -1 +1 @@ -Corrected grammatical errors, improved sentence structures, translation for migration 2.x-3.x \ No newline at end of file +Corrected grammatical errors, improved sentence structures, translation for migration 2.x-3.x diff --git a/CHANGES/1320.misc.rst b/CHANGES/1320.misc.rst new file mode 100644 index 00000000..f7e079ce --- /dev/null +++ b/CHANGES/1320.misc.rst @@ -0,0 +1 @@ +Fixed ResourceWarning in the tests, reworked :code:`RedisEventsIsolation` fixture to use Redis connection from :code:`RedisStorage` diff --git a/CHANGES/1331.misc b/CHANGES/1331.misc.rst similarity index 74% rename from CHANGES/1331.misc rename to CHANGES/1331.misc.rst index 375f975c..38d7efa4 100644 --- a/CHANGES/1331.misc +++ b/CHANGES/1331.misc.rst @@ -1 +1 @@ -Prevent update handling task pointers from being garbage collected, backport from 2.x \ No newline at end of file +Prevent update handling task pointers from being garbage collected, backport from 2.x diff --git a/CHANGES/1332.bugfix.rst b/CHANGES/1332.bugfix.rst index 004cfd1d..9cf7d48c 100644 --- a/CHANGES/1332.bugfix.rst +++ b/CHANGES/1332.bugfix.rst @@ -1 +1 @@ - Fixed ``parse_mode`` in ``send_copy`` helper. Disable by default. + Fixed :code:`parse_mode` argument in the in :code:`Message.send_copy` shortcut. Disable by default. diff --git a/CHANGES/1343.feature.rst b/CHANGES/1343.feature.rst index 6ae25cd3..80960dc7 100644 --- a/CHANGES/1343.feature.rst +++ b/CHANGES/1343.feature.rst @@ -1 +1 @@ -The new FSM strategy CHAT_TOPIC, which sets the state for the entire topic in the chat, also works in private messages and regular groups without topics. +Added the new FSM strategy :code:`CHAT_TOPIC`, which sets the state for the entire topic in the chat, also works in private messages and regular groups without topics. diff --git a/CHANGES/1353.doc.rst b/CHANGES/1353.doc.rst new file mode 100644 index 00000000..15f6d28e --- /dev/null +++ b/CHANGES/1353.doc.rst @@ -0,0 +1 @@ +Minor typo correction in middleware docs. diff --git a/CHANGES/1357.misc.rst b/CHANGES/1357.misc.rst new file mode 100644 index 00000000..96822c1f --- /dev/null +++ b/CHANGES/1357.misc.rst @@ -0,0 +1 @@ +Speeded up CallableMixin processing by caching references to nested objects and simplifying kwargs assembly. diff --git a/CHANGES/1360.bugfix.rst b/CHANGES/1360.bugfix.rst new file mode 100644 index 00000000..b2a272b1 --- /dev/null +++ b/CHANGES/1360.bugfix.rst @@ -0,0 +1 @@ +Added ability to get handler flags from filters. diff --git a/CHANGES/1361.misc.rst b/CHANGES/1361.misc.rst new file mode 100644 index 00000000..9b1fe953 --- /dev/null +++ b/CHANGES/1361.misc.rst @@ -0,0 +1 @@ +Added :code:`pydantic` v2.5 support. diff --git a/aiogram/dispatcher/event/handler.py b/aiogram/dispatcher/event/handler.py index 2b71eed5..1a353e1e 100644 --- a/aiogram/dispatcher/event/handler.py +++ b/aiogram/dispatcher/event/handler.py @@ -4,7 +4,7 @@ import inspect import warnings from dataclasses import dataclass, field from functools import partial -from typing import Any, Callable, Dict, List, Optional, Tuple +from typing import Any, Callable, Dict, List, Optional, Set, Tuple from magic_filter.magic import MagicFilter as OriginalMagicFilter @@ -21,20 +21,21 @@ CallbackType = Callable[..., Any] class CallableMixin: callback: CallbackType awaitable: bool = field(init=False) - spec: inspect.FullArgSpec = field(init=False) + params: Set[str] = field(init=False) + varkw: bool = field(init=False) def __post_init__(self) -> None: callback = inspect.unwrap(self.callback) self.awaitable = inspect.isawaitable(callback) or inspect.iscoroutinefunction(callback) - self.spec = inspect.getfullargspec(callback) + spec = inspect.getfullargspec(callback) + self.params = {*spec.args, *spec.kwonlyargs} + self.varkw = spec.varkw is not None def _prepare_kwargs(self, kwargs: Dict[str, Any]) -> Dict[str, Any]: - if self.spec.varkw: + if self.varkw: return kwargs - return { - k: v for k, v in kwargs.items() if k in self.spec.args or k in self.spec.kwonlyargs - } + return {k: kwargs[k] for k in self.params if k in kwargs} async def call(self, *args: Any, **kwargs: Any) -> Any: wrapped = partial(self.callback, *args, **self._prepare_kwargs(kwargs)) diff --git a/aiogram/dispatcher/event/telegram.py b/aiogram/dispatcher/event/telegram.py index 4a370074..afa8938e 100644 --- a/aiogram/dispatcher/event/telegram.py +++ b/aiogram/dispatcher/event/telegram.py @@ -109,9 +109,10 @@ class TelegramEventObserver: Handler will be called when all its filters are pass. """ for handler in self.handlers: + kwargs["handler"] = handler result, data = await handler.check(event, **kwargs) if result: - kwargs.update(data, handler=handler) + kwargs.update(data) try: wrapped_inner = self.outer_middleware.wrap_middlewares( self._resolve_middlewares(), diff --git a/aiogram/utils/chat_action.py b/aiogram/utils/chat_action.py index 6d7b7400..4d5fb567 100644 --- a/aiogram/utils/chat_action.py +++ b/aiogram/utils/chat_action.py @@ -43,7 +43,7 @@ class ChatActionSender: :param chat_id: target chat id :param action: chat action type :param interval: interval between iterations - :param initial_sleep: sleep before first iteration + :param initial_sleep: sleep before first sending of the action """ self.chat_id = chat_id self.message_thread_id = message_thread_id diff --git a/docs/api/session/middleware.rst b/docs/api/session/middleware.rst index fb06daca..5a312c3e 100644 --- a/docs/api/session/middleware.rst +++ b/docs/api/session/middleware.rst @@ -53,7 +53,7 @@ Class based session middleware .. note:: - this middlewware is already implemented inside aiogram, so, if you want to use it you can + this middleware is already implemented inside aiogram, so, if you want to use it you can just import it :code:`from aiogram.client.session.middlewares.request_logging import RequestLogging` diff --git a/docs/dispatcher/middlewares.rst b/docs/dispatcher/middlewares.rst index 56d07ef1..c63c6709 100644 --- a/docs/dispatcher/middlewares.rst +++ b/docs/dispatcher/middlewares.rst @@ -59,7 +59,8 @@ Examples .. danger:: - Middleware should always call :code:`await handler(event, data)` to propagate event for next middleware/handler + Middleware should always call :code:`await handler(event, data)` to propagate event for next middleware/handler. + If you want to stop processing event in middleware you should not call :code:`await handler(event, data)`. Class-based diff --git a/docs/locale/uk_UA/LC_MESSAGES/api/session/middleware.po b/docs/locale/uk_UA/LC_MESSAGES/api/session/middleware.po index 137d74ca..a0bc20b5 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/api/session/middleware.po +++ b/docs/locale/uk_UA/LC_MESSAGES/api/session/middleware.po @@ -8,14 +8,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-30 18:31+0300\n" +"POT-Creation-Date: 2023-11-16 02:34+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.12.1\n" +"Generated-By: Babel 2.13.1\n" #: ../../api/session/middleware.rst:3 msgid "Client session middlewares" @@ -77,11 +77,20 @@ msgstr "" #: ../../api/session/middleware.rst:56 msgid "" -"this middlewware is already implemented inside aiogram, so, if you want " -"to use it you can just import it :code:`from " +"this middleware is already implemented inside aiogram, so, if you want to" +" use it you can just import it :code:`from " "aiogram.client.session.middlewares.request_logging import RequestLogging`" msgstr "" #: ../../api/session/middleware.rst:61 msgid "Function based session middleware" msgstr "" + +#~ msgid "" +#~ "this middlewware is already implemented " +#~ "inside aiogram, so, if you want to" +#~ " use it you can just import it" +#~ " :code:`from " +#~ "aiogram.client.session.middlewares.request_logging import " +#~ "RequestLogging`" +#~ msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/changelog.po b/docs/locale/uk_UA/LC_MESSAGES/changelog.po index 2c32c200..936a2964 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/changelog.po +++ b/docs/locale/uk_UA/LC_MESSAGES/changelog.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: aiogram \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-29 02:16+0300\n" +"POT-Creation-Date: 2023-11-16 02:34+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -22,7 +22,7 @@ msgid "Changelog" msgstr "" #: ../../[towncrier-fragments]:2 -msgid "\\ |release| [UNRELEASED DRAFT] (2023-10-29)" +msgid "\\ |release| [UNRELEASED DRAFT] (2023-11-16)" msgstr "" #: ../../../CHANGES.rst:33 ../../../CHANGES.rst:122 ../../../CHANGES.rst:180 @@ -57,81 +57,113 @@ msgid "" "`_" msgstr "" +#: ../../[towncrier-fragments]:16 +msgid "" +"Added current handler to filters, so that flags can be retrieved from it." +" `#1360 `_" +msgstr "" + #: ../../../CHANGES.rst:89 ../../../CHANGES.rst:159 ../../../CHANGES.rst:204 #: ../../../CHANGES.rst:289 ../../../CHANGES.rst:522 ../../../CHANGES.rst:572 -#: ../../../CHANGES.rst:952 ../../[towncrier-fragments]:19 +#: ../../../CHANGES.rst:952 ../../[towncrier-fragments]:21 msgid "Improved Documentation" msgstr "" -#: ../../[towncrier-fragments]:21 +#: ../../[towncrier-fragments]:23 msgid "" "Corrected grammatical errors, improved sentence structures, translation " "for migration 2.x-3.x `#1302 " "`_" msgstr "" -#: ../../[towncrier-fragments]:23 +#: ../../[towncrier-fragments]:25 msgid "" "Minor typo correction, specifically in module naming + some grammar. " "`#1340 `_" msgstr "" -#: ../../[towncrier-fragments]:25 +#: ../../[towncrier-fragments]:27 msgid "" "Added `CITATION.cff` file for automatic academic citation generation. Now" " you can copy citation from the GitHub page and paste it into your paper." " `#1351 `_" msgstr "" +#: ../../[towncrier-fragments]:30 +msgid "" +"Minor typo correction in middleware docs. `#1353 " +"`_" +msgstr "" + #: ../../../CHANGES.rst:110 ../../../CHANGES.rst:166 ../../../CHANGES.rst:305 #: ../../../CHANGES.rst:456 ../../../CHANGES.rst:533 ../../../CHANGES.rst:586 #: ../../../CHANGES.rst:637 ../../../CHANGES.rst:691 ../../../CHANGES.rst:733 #: ../../../CHANGES.rst:779 ../../../CHANGES.rst:839 ../../../CHANGES.rst:860 #: ../../../CHANGES.rst:883 ../../../CHANGES.rst:920 ../../../CHANGES.rst:959 -#: ../../[towncrier-fragments]:31 +#: ../../[towncrier-fragments]:35 msgid "Misc" msgstr "" -#: ../../[towncrier-fragments]:33 +#: ../../[towncrier-fragments]:37 +msgid "" +"Fixed ResourceWarning in the tests, reworked :code:`RedisEventsIsolation`" +" fixture to use Redis connection from :code:`RedisStorage` `#1320 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:39 msgid "Updated dependencies, bumped minimum required version:" msgstr "" -#: ../../[towncrier-fragments]:35 +#: ../../[towncrier-fragments]:41 msgid ":code:`magic-filter` - fixed `.resolve` operation" msgstr "" -#: ../../[towncrier-fragments]:36 +#: ../../[towncrier-fragments]:42 msgid ":code:`pydantic` - fixed compatibility (broken in 2.4)" msgstr "" -#: ../../[towncrier-fragments]:37 +#: ../../[towncrier-fragments]:43 msgid "" ":code:`aiodns` - added new dependency to the :code:`fast` extras " "(:code:`pip install aiogram[fast]`)" msgstr "" -#: ../../[towncrier-fragments]:38 +#: ../../[towncrier-fragments]:44 msgid "*others...*" msgstr "" -#: ../../[towncrier-fragments]:39 +#: ../../[towncrier-fragments]:45 msgid "`#1327 `_" msgstr "" -#: ../../[towncrier-fragments]:40 +#: ../../[towncrier-fragments]:46 msgid "" "Prevent update handling task pointers from being garbage collected, " "backport from 2.x `#1331 " "`_" msgstr "" -#: ../../[towncrier-fragments]:42 +#: ../../[towncrier-fragments]:48 msgid "" "Updated :code:`typing-extensions` package version range in dependencies " "to fix compatibility with :code:`FastAPI` `#1347 " "`_" msgstr "" +#: ../../[towncrier-fragments]:50 +msgid "" +"Speeded up CallableMixin processing by caching references to nested " +"objects and simplifying kwargs assembly. `#1357 " +"`_" +msgstr "" + +#: ../../[towncrier-fragments]:52 +msgid "" +"Added pydantic v2.5 support. `#1361 " +"`_" +msgstr "" + #: ../../../CHANGES.rst:20 msgid "3.1.1 (2023-09-25)" msgstr "" @@ -3202,3 +3234,6 @@ msgstr "" #~ msgid "\\ |release| [UNRELEASED DRAFT] (2023-10-08)" #~ msgstr "" + +#~ msgid "\\ |release| [UNRELEASED DRAFT] (2023-10-29)" +#~ msgstr "" diff --git a/docs/locale/uk_UA/LC_MESSAGES/dispatcher/middlewares.po b/docs/locale/uk_UA/LC_MESSAGES/dispatcher/middlewares.po index acf64c07..862a7f31 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/dispatcher/middlewares.po +++ b/docs/locale/uk_UA/LC_MESSAGES/dispatcher/middlewares.po @@ -5,123 +5,125 @@ # msgid "" msgstr "" -"Project-Id-Version: aiogram\n" +"Project-Id-Version: aiogram\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-10-01 22:51+0300\n" +"POT-Creation-Date: 2023-11-16 02:34+0200\n" "PO-Revision-Date: 2022-10-20 20:56+0300\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" -"X-Generator: Poedit 3.1.1\n" +"Generated-By: Babel 2.13.1\n" -#: ../../dispatcher/middlewares.rst:3 +#: ../../dispatcher/middlewares.rst:5 msgid "Middlewares" msgstr "Проміжні програми" -#: ../../dispatcher/middlewares.rst:5 +#: ../../dispatcher/middlewares.rst:7 msgid "" -"**aiogram** provides powerful mechanism for customizing event handlers via " -"middlewares." +"**aiogram** provides powerful mechanism for customizing event handlers " +"via middlewares." msgstr "" "**aiogram** надає потужний механізм для налаштування обробників(handler) " "подій через проміжні програми." -#: ../../dispatcher/middlewares.rst:7 +#: ../../dispatcher/middlewares.rst:9 msgid "" "Middlewares in bot framework seems like Middlewares mechanism in web-" -"frameworks like `aiohttp `_, `fastapi `_, `Django `_ or etc.) with small difference - here is " -"implemented two layers of middlewares (before and after filters)." +"frameworks like `aiohttp " +"`_, `fastapi " +"`_, `Django " +"`_ or " +"etc.) with small difference - here is implemented two layers of " +"middlewares (before and after filters)." msgstr "" -"Проміжні програми у фреймворку для ботів виглядають як механізм проміжних " -"програм у веб-фреймворках, таких як `aiohttp `_, `fastapi `_, `Django `_ тощо) з невеликою " -"різницею – тут реалізовано два рівні проміжного програмних програм (до та " -"після фільтрів)." +"Проміжні програми у фреймворку для ботів виглядають як механізм проміжних" +" програм у веб-фреймворках, таких як `aiohttp " +"`_, `fastapi " +"`_, `Django " +"`_ тощо) " +"з невеликою різницею – тут реалізовано два рівні проміжного програмних " +"програм (до та після фільтрів)." -#: ../../dispatcher/middlewares.rst:15 +#: ../../dispatcher/middlewares.rst:17 msgid "" -"Middleware is function that triggered on every event received from Telegram " -"Bot API in many points on processing pipeline." +"Middleware is function that triggered on every event received from " +"Telegram Bot API in many points on processing pipeline." msgstr "" "Проміжна програма — це функція, яка запускається під час кожної події, " "отриманої від Telegram Bot API у багатьох точках процесу обробки." -#: ../../dispatcher/middlewares.rst:19 +#: ../../dispatcher/middlewares.rst:21 msgid "Base theory" msgstr "Основні поняття" -#: ../../dispatcher/middlewares.rst:21 +#: ../../dispatcher/middlewares.rst:23 msgid "As many books and other literature in internet says:" msgstr "Більшість книг та Інтернет-джерел стверджують:" -#: ../../dispatcher/middlewares.rst:23 +#: ../../dispatcher/middlewares.rst:25 msgid "" -"Middleware is reusable software that leverages patterns and frameworks to " -"bridge the gap between the functional requirements of applications and the " -"underlying operating systems, network protocol stacks, and databases." +"Middleware is reusable software that leverages patterns and frameworks to" +" bridge the gap between the functional requirements of applications and " +"the underlying operating systems, network protocol stacks, and databases." msgstr "" "Проміжна програма — це програма, багаторазового використання, що " "використовує шаблони та фреймворки для ліквідування розриву між " "функціональними вимогами додатків і основними операційними системами, " "стеками мережевих протоколів і базами даних." -#: ../../dispatcher/middlewares.rst:27 +#: ../../dispatcher/middlewares.rst:29 msgid "" -"Middleware can modify, extend or reject processing event in many places of " -"pipeline." +"Middleware can modify, extend or reject processing event in many places " +"of pipeline." msgstr "" -"Проміжна програма може змінювати, розширювати або відхиляти подію обробки у " -"багатьох точках процесу обробки." +"Проміжна програма може змінювати, розширювати або відхиляти подію обробки" +" у багатьох точках процесу обробки." -#: ../../dispatcher/middlewares.rst:30 +#: ../../dispatcher/middlewares.rst:32 msgid "Basics" msgstr "Основи" -#: ../../dispatcher/middlewares.rst:32 +#: ../../dispatcher/middlewares.rst:34 msgid "" -"Middleware instance can be applied for every type of Telegram Event (Update, " -"Message, etc.) in two places" +"Middleware instance can be applied for every type of Telegram Event " +"(Update, Message, etc.) in two places" msgstr "" "Екземпляр проміжної програми можна застосувати для кожного типу події " "Telegram (оновлення, повідомлення тощо) у двох місцях" -#: ../../dispatcher/middlewares.rst:34 +#: ../../dispatcher/middlewares.rst:36 msgid "" -"Outer scope - before processing filters (:code:`.." -"outer_middleware(...)`)" +"Outer scope - before processing filters " +"(:code:`..outer_middleware(...)`)" msgstr "" -"Зовнішня область - перед обробкою фільтрами (:code:`.." -"outer_middleware(...)`)" +"Зовнішня область - перед обробкою фільтрами " +"(:code:`..outer_middleware(...)`)" -#: ../../dispatcher/middlewares.rst:35 +#: ../../dispatcher/middlewares.rst:37 msgid "" -"Inner scope - after processing filters but before handler (:code:`." -".middleware(...)`)" -msgstr "" -"Внутрішня область – після обробки фільтрами, але перед обробником (handler) " +"Inner scope - after processing filters but before handler " "(:code:`..middleware(...)`)" +msgstr "" +"Внутрішня область – після обробки фільтрами, але перед обробником " +"(handler) (:code:`..middleware(...)`)" #: ../../dispatcher/middlewares.rst:-1 msgid "Middleware basics" msgstr "Основи проміжних програм" -#: ../../dispatcher/middlewares.rst:42 +#: ../../dispatcher/middlewares.rst:44 msgid "" -"Middleware should be subclass of :code:`BaseMiddleware` (:code:`from aiogram " -"import BaseMiddleware`) or any async callable" +"Middleware should be subclass of :code:`BaseMiddleware` (:code:`from " +"aiogram import BaseMiddleware`) or any async callable" msgstr "" "Проміжна програма має бути підкласом :code:`BaseMiddleware` (:code:`from " "aiogram import BaseMiddleware`) або будь-якою асинхронною функцією" -#: ../../dispatcher/middlewares.rst:45 +#: ../../dispatcher/middlewares.rst:47 msgid "Arguments specification" msgstr "Специфікація аргументів" @@ -161,53 +163,58 @@ msgstr "Повертає" msgid ":class:`Any`" msgstr ":class:`Any`" -#: ../../dispatcher/middlewares.rst:56 +#: ../../dispatcher/middlewares.rst:58 msgid "Examples" msgstr "Приклади" -#: ../../dispatcher/middlewares.rst:60 +#: ../../dispatcher/middlewares.rst:62 +#, fuzzy msgid "" "Middleware should always call :code:`await handler(event, data)` to " -"propagate event for next middleware/handler" +"propagate event for next middleware/handler. If you want to stop " +"processing event in middleware you should not call :code:`await " +"handler(event, data)`." msgstr "" "Проміжні програми мають завжди викликати :code:`await handler(event, " "data)` , щоб передавати подію для наступної проміжної програми/обробника " "(handler)" -#: ../../dispatcher/middlewares.rst:64 +#: ../../dispatcher/middlewares.rst:67 msgid "Class-based" msgstr "Класово орієнтований" -#: ../../dispatcher/middlewares.rst:85 +#: ../../dispatcher/middlewares.rst:88 msgid "and then" msgstr "і тоді" -#: ../../dispatcher/middlewares.rst:94 +#: ../../dispatcher/middlewares.rst:97 msgid "Function-based" msgstr "Функціонально-орієнтований" -#: ../../dispatcher/middlewares.rst:109 +#: ../../dispatcher/middlewares.rst:112 msgid "Facts" msgstr "Факти" -#: ../../dispatcher/middlewares.rst:111 +#: ../../dispatcher/middlewares.rst:114 msgid "Middlewares from outer scope will be called on every incoming event" msgstr "" "Проміжні програми із зовнішньої області викликатимуться під час кожної " "вхідної події" -#: ../../dispatcher/middlewares.rst:112 +#: ../../dispatcher/middlewares.rst:115 msgid "Middlewares from inner scope will be called only when filters pass" msgstr "" "Проміжні програми із внутрішньої області викликатимуться лише після " "проходження фільтрів" -#: ../../dispatcher/middlewares.rst:113 +#: ../../dispatcher/middlewares.rst:116 msgid "" -"Inner middlewares is always calls for :class:`aiogram.types.update.Update` " -"event type in due to all incoming updates going to specific event type " -"handler through built in update handler" +"Inner middlewares is always calls for " +":class:`aiogram.types.update.Update` event type in due to all incoming " +"updates going to specific event type handler through built in update " +"handler" msgstr "" -"Внутрішні проміжні програми викликають тип події :class:`aiogram.types." -"update.Update` , через те, що всі вхідні оновлення надходять до обробника " -"(handler) певного типу подій через вбудований обробник (handler) оновлень" +"Внутрішні проміжні програми викликають тип події " +":class:`aiogram.types.update.Update` , через те, що всі вхідні оновлення " +"надходять до обробника (handler) певного типу подій через вбудований " +"обробник (handler) оновлень" diff --git a/docs/locale/uk_UA/LC_MESSAGES/utils/chat_action.po b/docs/locale/uk_UA/LC_MESSAGES/utils/chat_action.po index 46ab594b..4140fc79 100644 --- a/docs/locale/uk_UA/LC_MESSAGES/utils/chat_action.po +++ b/docs/locale/uk_UA/LC_MESSAGES/utils/chat_action.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: aiogram\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-30 18:31+0300\n" +"POT-Creation-Date: 2023-11-16 02:34+0200\n" "PO-Revision-Date: 2022-10-13 21:22+0300\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.12.1\n" +"Generated-By: Babel 2.13.1\n" #: ../../utils/chat_action.rst:3 msgid "Chat action sender" @@ -69,7 +69,8 @@ msgid "interval between iterations" msgstr "інтервал між ітераціями" #: aiogram.utils.chat_action.ChatActionSender.__init__:5 of -msgid "sleep before first iteration" +#, fuzzy +msgid "sleep before first sending of the action" msgstr "затримка перед першою ітерацією" #: aiogram.utils.chat_action.ChatActionSender.choose_sticker:1 of diff --git a/pyproject.toml b/pyproject.toml index f1f86f77..2d17be3b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,8 +42,8 @@ classifiers = [ ] dependencies = [ "magic-filter>=1.0.12,<1.1", - "aiohttp~=3.9.0b0", - "pydantic>=2.4.1,<2.5", + "aiohttp~=3.9.0", + "pydantic>=2.4.1,<2.6", "aiofiles~=23.2.1", "certifi>=2023.7.22", "typing-extensions>=4.7.0,<=5.0", diff --git a/tests/conftest.py b/tests/conftest.py index 1c72f386..3e063ff1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -38,7 +38,7 @@ def pytest_collection_modifyitems(config, items): raise UsageError(f"Invalid redis URI {redis_uri!r}: {e}") -@pytest.fixture(scope="session") +@pytest.fixture() def redis_server(request): redis_uri = request.config.getoption("--redis") return redis_uri @@ -73,20 +73,9 @@ async def memory_storage(): @pytest.fixture() @pytest.mark.redis -async def redis_isolation(redis_server): - if not redis_server: - pytest.skip("Redis is not available here") - isolation = RedisEventIsolation.from_url(redis_server) - try: - await isolation.redis.info() - except ConnectionError as e: - pytest.skip(str(e)) - try: - yield isolation - finally: - conn = await isolation.redis - await conn.flushdb() - await isolation.close() +async def redis_isolation(redis_storage): + isolation = redis_storage.create_isolation() + return isolation @pytest.fixture() diff --git a/tests/test_api/test_client/test_session/test_aiohttp_session.py b/tests/test_api/test_client/test_session/test_aiohttp_session.py index bc7aff83..6740dcc1 100644 --- a/tests/test_api/test_client/test_session/test_aiohttp_session.py +++ b/tests/test_api/test_client/test_session/test_aiohttp_session.py @@ -96,6 +96,8 @@ class TestAiohttpSession: await session.close() mocked_close.assert_called_once() + await session.close() + def test_build_form_data_with_data_only(self, bot: MockedBot): class TestMethod(TelegramMethod[bool]): __api_method__ = "test" diff --git a/tests/test_api/test_types/test_message.py b/tests/test_api/test_types/test_message.py index 4e893d20..7efe6c89 100644 --- a/tests/test_api/test_types/test_message.py +++ b/tests/test_api/test_types/test_message.py @@ -36,6 +36,7 @@ from aiogram.methods import ( UnpinChatMessage, ) from aiogram.types import ( + UNSET_PARSE_MODE, Animation, Audio, Chat, @@ -75,7 +76,6 @@ from aiogram.types import ( VideoNote, Voice, WebAppData, - UNSET_PARSE_MODE, ) from aiogram.types.message import ContentType, Message diff --git a/tests/test_dispatcher/test_event/test_handler.py b/tests/test_dispatcher/test_event/test_handler.py index f7000d8e..b5492dce 100644 --- a/tests/test_dispatcher/test_event/test_handler.py +++ b/tests/test_dispatcher/test_event/test_handler.py @@ -1,5 +1,5 @@ import functools -from typing import Any, Dict, Union +from typing import Any, Callable, Dict, Set, Union import pytest from magic_filter import F as A @@ -61,9 +61,9 @@ class TestCallableMixin: pytest.param(SyncCallable(), {"self", "foo", "bar", "baz"}), ], ) - def test_init_args_spec(self, callback, args): + def test_init_args_spec(self, callback: Callable, args: Set[str]): obj = CallableMixin(callback) - assert set(obj.spec.args) == args + assert set(obj.params) == args def test_init_decorated(self): def decorator(func): @@ -85,9 +85,9 @@ class TestCallableMixin: obj1 = CallableMixin(callback1) obj2 = CallableMixin(callback2) - assert set(obj1.spec.args) == {"foo", "bar", "baz"} + assert set(obj1.params) == {"foo", "bar", "baz"} assert obj1.callback == callback1 - assert set(obj2.spec.args) == {"foo", "bar", "baz"} + assert set(obj2.params) == {"foo", "bar", "baz"} assert obj2.callback == callback2 @pytest.mark.parametrize( @@ -124,7 +124,9 @@ class TestCallableMixin: ), ], ) - def test_prepare_kwargs(self, callback, kwargs, result): + def test_prepare_kwargs( + self, callback: Callable, kwargs: Dict[str, Any], result: Dict[str, Any] + ): obj = CallableMixin(callback) assert obj._prepare_kwargs(kwargs) == result diff --git a/tests/test_fsm/storage/test_isolation.py b/tests/test_fsm/storage/test_isolation.py index 60e240ae..8be303c4 100644 --- a/tests/test_fsm/storage/test_isolation.py +++ b/tests/test_fsm/storage/test_isolation.py @@ -1,6 +1,10 @@ +from unittest import mock +from unittest.mock import AsyncMock, patch + import pytest from aiogram.fsm.storage.base import BaseEventIsolation, StorageKey +from aiogram.fsm.storage.redis import RedisEventIsolation from tests.mocked_bot import MockedBot @@ -18,7 +22,6 @@ def create_storage_key(bot: MockedBot): ], ) class TestIsolations: - @pytest.mark.filterwarnings("ignore::ResourceWarning") async def test_lock( self, isolation: BaseEventIsolation, @@ -26,3 +29,35 @@ class TestIsolations: ): async with isolation.lock(key=storage_key): assert True, "Are you kidding me?" + + +class TestRedisEventIsolation: + def test_init_without_key_builder(self): + redis = AsyncMock() + isolation = RedisEventIsolation(redis=redis) + assert isolation.redis is redis + + assert isolation.key_builder is not None + + def test_init_with_key_builder(self): + redis = AsyncMock() + key_builder = AsyncMock() + isolation = RedisEventIsolation(redis=redis, key_builder=key_builder) + assert isolation.redis is redis + assert isolation.key_builder is key_builder + + def test_create_from_url(self): + with patch("redis.asyncio.connection.ConnectionPool.from_url") as pool: + isolation = RedisEventIsolation.from_url("redis://localhost:6379/0") + assert isinstance(isolation, RedisEventIsolation) + assert isolation.redis is not None + assert isolation.key_builder is not None + + assert pool.called_once_with("redis://localhost:6379/0") + + async def test_close(self): + isolation = RedisEventIsolation(redis=AsyncMock()) + await isolation.close() + + # close is not called because connection should be closed from the storage + # assert isolation.redis.close.called_once()