Merge branch 'dev-3.x' into python-3.12

This commit is contained in:
Alex Root Junior 2023-11-18 21:19:58 +02:00 committed by GitHub
commit 50b19956df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 219 additions and 131 deletions

View file

@ -1 +1 @@
Corrected grammatical errors, improved sentence structures, translation for migration 2.x-3.x
Corrected grammatical errors, improved sentence structures, translation for migration 2.x-3.x

1
CHANGES/1320.misc.rst Normal file
View file

@ -0,0 +1 @@
Fixed ResourceWarning in the tests, reworked :code:`RedisEventsIsolation` fixture to use Redis connection from :code:`RedisStorage`

View file

@ -1 +1 @@
Prevent update handling task pointers from being garbage collected, backport from 2.x
Prevent update handling task pointers from being garbage collected, backport from 2.x

View file

@ -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.

View file

@ -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.

1
CHANGES/1353.doc.rst Normal file
View file

@ -0,0 +1 @@
Minor typo correction in middleware docs.

1
CHANGES/1357.misc.rst Normal file
View file

@ -0,0 +1 @@
Speeded up CallableMixin processing by caching references to nested objects and simplifying kwargs assembly.

1
CHANGES/1360.bugfix.rst Normal file
View file

@ -0,0 +1 @@
Added ability to get handler flags from filters.

1
CHANGES/1361.misc.rst Normal file
View file

@ -0,0 +1 @@
Added :code:`pydantic` v2.5 support.

View file

@ -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))

View file

@ -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(),

View file

@ -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

View file

@ -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`

View file

@ -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

View file

@ -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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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 ""

View file

@ -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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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 ""
"<https://github.com/aiogram/aiogram/issues/1332>`_"
msgstr ""
#: ../../[towncrier-fragments]:16
msgid ""
"Added current handler to filters, so that flags can be retrieved from it."
" `#1360 <https://github.com/aiogram/aiogram/issues/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 "
"<https://github.com/aiogram/aiogram/issues/1302>`_"
msgstr ""
#: ../../[towncrier-fragments]:23
#: ../../[towncrier-fragments]:25
msgid ""
"Minor typo correction, specifically in module naming + some grammar. "
"`#1340 <https://github.com/aiogram/aiogram/issues/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 <https://github.com/aiogram/aiogram/issues/1351>`_"
msgstr ""
#: ../../[towncrier-fragments]:30
msgid ""
"Minor typo correction in middleware docs. `#1353 "
"<https://github.com/aiogram/aiogram/issues/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 "
"<https://github.com/aiogram/aiogram/issues/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 <https://github.com/aiogram/aiogram/issues/1327>`_"
msgstr ""
#: ../../[towncrier-fragments]:40
#: ../../[towncrier-fragments]:46
msgid ""
"Prevent update handling task pointers from being garbage collected, "
"backport from 2.x `#1331 "
"<https://github.com/aiogram/aiogram/issues/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 "
"<https://github.com/aiogram/aiogram/issues/1347>`_"
msgstr ""
#: ../../[towncrier-fragments]:50
msgid ""
"Speeded up CallableMixin processing by caching references to nested "
"objects and simplifying kwargs assembly. `#1357 "
"<https://github.com/aiogram/aiogram/issues/1357>`_"
msgstr ""
#: ../../[towncrier-fragments]:52
msgid ""
"Added pydantic v2.5 support. `#1361 "
"<https://github.com/aiogram/aiogram/issues/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 ""

View file

@ -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 <https://docs.aiohttp.org/en/stable/web_advanced."
"html#aiohttp-web-middlewares>`_, `fastapi <https://fastapi.tiangolo.com/"
"tutorial/middleware/>`_, `Django <https://docs.djangoproject.com/en/3.0/"
"topics/http/middleware/>`_ or etc.) with small difference - here is "
"implemented two layers of middlewares (before and after filters)."
"frameworks like `aiohttp "
"<https://docs.aiohttp.org/en/stable/web_advanced.html#aiohttp-web-"
"middlewares>`_, `fastapi "
"<https://fastapi.tiangolo.com/tutorial/middleware/>`_, `Django "
"<https://docs.djangoproject.com/en/3.0/topics/http/middleware/>`_ or "
"etc.) with small difference - here is implemented two layers of "
"middlewares (before and after filters)."
msgstr ""
"Проміжні програми у фреймворку для ботів виглядають як механізм проміжних "
"програм у веб-фреймворках, таких як `aiohttp <https://docs.aiohttp.org/en/"
"stable/web_advanced.html#aiohttp-web-middlewares>`_, `fastapi <https://"
"fastapi.tiangolo.com/tutorial/middleware/>`_, `Django <https://docs."
"djangoproject.com/en/3.0/topics/http/middleware/>`_ тощо) з невеликою "
"різницею тут реалізовано два рівні проміжного програмних програм (до та "
"після фільтрів)."
"Проміжні програми у фреймворку для ботів виглядають як механізм проміжних"
" програм у веб-фреймворках, таких як `aiohttp "
"<https://docs.aiohttp.org/en/stable/web_advanced.html#aiohttp-web-"
"middlewares>`_, `fastapi "
"<https://fastapi.tiangolo.com/tutorial/middleware/>`_, `Django "
"<https://docs.djangoproject.com/en/3.0/topics/http/middleware/>`_ тощо) "
"з невеликою різницею тут реалізовано два рівні проміжного програмних "
"програм (до та після фільтрів)."
#: ../../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:`<router>.<event>."
"outer_middleware(...)`)"
"Outer scope - before processing filters "
"(:code:`<router>.<event>.outer_middleware(...)`)"
msgstr ""
"Зовнішня область - перед обробкою фільтрами (:code:`<router>.<event>."
"outer_middleware(...)`)"
"Зовнішня область - перед обробкою фільтрами "
"(:code:`<router>.<event>.outer_middleware(...)`)"
#: ../../dispatcher/middlewares.rst:35
#: ../../dispatcher/middlewares.rst:37
msgid ""
"Inner scope - after processing filters but before handler (:code:`<router>."
"<event>.middleware(...)`)"
msgstr ""
"Внутрішня область після обробки фільтрами, але перед обробником (handler) "
"Inner scope - after processing filters but before handler "
"(:code:`<router>.<event>.middleware(...)`)"
msgstr ""
"Внутрішня область після обробки фільтрами, але перед обробником "
"(handler) (:code:`<router>.<event>.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) оновлень"

View file

@ -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

View file

@ -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",

View file

@ -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()

View file

@ -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"

View file

@ -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

View file

@ -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

View file

@ -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()