Migrate from Black to Ruff (#1750)

* Migrate from Black to Ruff and reformat code with enabling additional linter checks

* Add changelog for migration to Ruff as formatter and linter

* Add type ignores for specific attributes and replace tuple with set for chat type check

* Remove file from another changes
This commit is contained in:
Alex Root Junior 2026-01-04 21:34:08 +02:00 committed by GitHub
parent a4a3f42c71
commit ec7da0f678
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
214 changed files with 886 additions and 964 deletions

View file

@ -72,7 +72,7 @@ jobs:
run: | run: |
uv run ruff check --output-format=github aiogram examples uv run ruff check --output-format=github aiogram examples
uv run mypy aiogram uv run mypy aiogram
uv run black --check --diff aiogram tests uv run ruff format --check --diff aiogram tests scripts examples
- name: Setup redis - name: Setup redis
if: ${{ env.IS_WINDOWS == 'false' }} if: ${{ env.IS_WINDOWS == 'false' }}

View file

@ -13,13 +13,10 @@ repos:
- id: "check-toml" - id: "check-toml"
- id: "check-json" - id: "check-json"
- repo: https://github.com/psf/black
rev: 25.9.0
hooks:
- id: black
files: &files '^(aiogram|tests|examples)'
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
rev: 'v0.14.0' rev: 'v0.14.0'
hooks: hooks:
- id: ruff - id: ruff
files: &files '^(aiogram|tests|examples)'
- id: ruff-format
files: *files

24
CHANGES/1750.misc.rst Normal file
View file

@ -0,0 +1,24 @@
Migrated from Black and isort to Ruff for code formatting and linting, a modern, blazingly fast formatter and linter written in Rust.
Enabled additional ruff rule sets.
**For end users:**
No changes required. This is purely a development tooling change that doesn't affect the library API or behavior.
**For contributors:**
- Use ``make reformat`` or ``uv run ruff format`` to format code (replaces ``black`` and ``isort``)
- Use ``make lint`` to check code quality (now includes formatting, linting, and type checking)
- Pre-commit hooks automatically updated to use ``ruff`` and ``ruff-format``
- CI/CD pipelines updated to use ruff in GitHub Actions workflows
**Benefits:**
- 10-100x faster formatting and linting compared to Black + isort + flake8
- Single tool for formatting, import sorting, and linting
- More comprehensive code quality checks out of the box
- Auto-fixes for many common issues (33 issues auto-fixed during migration)
- Better integration with modern Python development workflows
This change improves the developer experience and code quality while maintaining the same code style standards.

View file

@ -37,15 +37,14 @@ install: clean
.PHONY: lint .PHONY: lint
lint: lint:
uv run isort --check-only $(code_dir) uv run ruff format --check --diff $(code_dir)
uv run black --check --diff $(code_dir)
uv run ruff check --show-fixes --preview $(package_dir) $(examples_dir) uv run ruff check --show-fixes --preview $(package_dir) $(examples_dir)
uv run mypy $(package_dir) uv run mypy $(package_dir)
.PHONY: reformat .PHONY: reformat
reformat: reformat:
uv run black $(code_dir) uv run ruff format $(code_dir)
uv run isort $(code_dir) uv run ruff check --fix $(code_dir)
# ================================================================================================= # =================================================================================================
# Tests # Tests

View file

@ -2,12 +2,11 @@ from __future__ import annotations
import io import io
import pathlib import pathlib
from collections.abc import AsyncGenerator, AsyncIterator
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from types import TracebackType from types import TracebackType
from typing import ( from typing import (
Any, Any,
AsyncGenerator,
AsyncIterator,
BinaryIO, BinaryIO,
TypeVar, TypeVar,
cast, cast,
@ -283,9 +282,9 @@ class Bot:
# Few arguments are completely removed in 3.7.0 version # Few arguments are completely removed in 3.7.0 version
# Temporary solution to raise an error if user passed these arguments # Temporary solution to raise an error if user passed these arguments
# with explanation how to fix it # with explanation how to fix it
parse_mode = kwargs.get("parse_mode", None) parse_mode = kwargs.get("parse_mode")
link_preview_is_disabled = kwargs.get("disable_web_page_preview", None) link_preview_is_disabled = kwargs.get("disable_web_page_preview")
protect_content = kwargs.get("protect_content", None) protect_content = kwargs.get("protect_content")
if ( if (
parse_mode is not None parse_mode is not None
or link_preview_is_disabled is not None or link_preview_is_disabled is not None
@ -310,7 +309,7 @@ class Bot:
self.__token = token self.__token = token
self._me: User | None = None self._me: User | None = None
async def __aenter__(self) -> "Bot": async def __aenter__(self) -> Bot:
return self return self
async def __aexit__( async def __aexit__(

View file

@ -58,7 +58,7 @@ def _prepare_connector(chain_or_plain: _ProxyType) -> tuple[type[TCPConnector],
# since tuple is Iterable(compatible with _ProxyChain) object, we assume that # since tuple is Iterable(compatible with _ProxyChain) object, we assume that
# user wants chained proxies if tuple is a pair of string(url) and BasicAuth # user wants chained proxies if tuple is a pair of string(url) and BasicAuth
if isinstance(chain_or_plain, str) or ( if isinstance(chain_or_plain, str) or (
isinstance(chain_or_plain, tuple) and len(chain_or_plain) == 2 isinstance(chain_or_plain, tuple) and len(chain_or_plain) == 2 # noqa: PLR2004
): ):
chain_or_plain = cast(_ProxyBasic, chain_or_plain) chain_or_plain = cast(_ProxyBasic, chain_or_plain)
return ProxyConnector, _retrieve_basic(chain_or_plain) return ProxyConnector, _retrieve_basic(chain_or_plain)
@ -170,10 +170,10 @@ class AiohttpSession(BaseSession):
timeout=self.timeout if timeout is None else timeout, timeout=self.timeout if timeout is None else timeout,
) as resp: ) as resp:
raw_result = await resp.text() raw_result = await resp.text()
except asyncio.TimeoutError: except asyncio.TimeoutError as e:
raise TelegramNetworkError(method=method, message="Request timeout error") raise TelegramNetworkError(method=method, message="Request timeout error") from e
except ClientError as e: except ClientError as e:
raise TelegramNetworkError(method=method, message=f"{type(e).__name__}: {e}") raise TelegramNetworkError(method=method, message=f"{type(e).__name__}: {e}") from e
response = self.check_response( response = self.check_response(
bot=bot, bot=bot,
method=method, method=method,

View file

@ -90,14 +90,14 @@ class BaseSession(abc.ABC):
# in due to decoder can be customized and raise any exception # in due to decoder can be customized and raise any exception
msg = "Failed to decode object" msg = "Failed to decode object"
raise ClientDecodeError(msg, e, content) raise ClientDecodeError(msg, e, content) from e
try: try:
response_type = Response[method.__returning__] # type: ignore response_type = Response[method.__returning__] # type: ignore
response = response_type.model_validate(json_data, context={"bot": bot}) response = response_type.model_validate(json_data, context={"bot": bot})
except ValidationError as e: except ValidationError as e:
msg = "Failed to deserialize object" msg = "Failed to deserialize object"
raise ClientDecodeError(msg, e, json_data) raise ClientDecodeError(msg, e, json_data) from e
if HTTPStatus.OK <= status_code <= HTTPStatus.IM_USED and response.ok: if HTTPStatus.OK <= status_code <= HTTPStatus.IM_USED and response.ok:
return response return response

View file

@ -21,10 +21,10 @@ class FlagDecorator:
flag: Flag flag: Flag
@classmethod @classmethod
def _with_flag(cls, flag: Flag) -> "FlagDecorator": def _with_flag(cls, flag: Flag) -> FlagDecorator:
return cls(flag) return cls(flag)
def _with_value(self, value: Any) -> "FlagDecorator": def _with_value(self, value: Any) -> FlagDecorator:
new_flag = Flag(self.flag.name, value) new_flag = Flag(self.flag.name, value)
return self._with_flag(new_flag) return self._with_flag(new_flag)
@ -33,11 +33,11 @@ class FlagDecorator:
pass pass
@overload @overload
def __call__(self, value: Any, /) -> "FlagDecorator": def __call__(self, value: Any, /) -> FlagDecorator:
pass pass
@overload @overload
def __call__(self, **kwargs: Any) -> "FlagDecorator": def __call__(self, **kwargs: Any) -> FlagDecorator:
pass pass
def __call__( def __call__(

View file

@ -37,7 +37,7 @@ class _MemberStatusMarker:
def __or__( def __or__(
self, self,
other: _MemberStatusMarker | _MemberStatusGroupMarker, other: _MemberStatusMarker | _MemberStatusGroupMarker,
) -> "_MemberStatusGroupMarker": ) -> _MemberStatusGroupMarker:
if isinstance(other, _MemberStatusMarker): if isinstance(other, _MemberStatusMarker):
return _MemberStatusGroupMarker(self, other) return _MemberStatusGroupMarker(self, other)
if isinstance(other, _MemberStatusGroupMarker): if isinstance(other, _MemberStatusGroupMarker):
@ -53,7 +53,7 @@ class _MemberStatusMarker:
def __rshift__( def __rshift__(
self, self,
other: _MemberStatusMarker | _MemberStatusGroupMarker, other: _MemberStatusMarker | _MemberStatusGroupMarker,
) -> "_MemberStatusTransition": ) -> _MemberStatusTransition:
old = _MemberStatusGroupMarker(self) old = _MemberStatusGroupMarker(self)
if isinstance(other, _MemberStatusMarker): if isinstance(other, _MemberStatusMarker):
return _MemberStatusTransition(old=old, new=_MemberStatusGroupMarker(other)) return _MemberStatusTransition(old=old, new=_MemberStatusGroupMarker(other))
@ -68,7 +68,7 @@ class _MemberStatusMarker:
def __lshift__( def __lshift__(
self, self,
other: _MemberStatusMarker | _MemberStatusGroupMarker, other: _MemberStatusMarker | _MemberStatusGroupMarker,
) -> "_MemberStatusTransition": ) -> _MemberStatusTransition:
new = _MemberStatusGroupMarker(self) new = _MemberStatusGroupMarker(self)
if isinstance(other, _MemberStatusMarker): if isinstance(other, _MemberStatusMarker):
return _MemberStatusTransition(old=_MemberStatusGroupMarker(other), new=new) return _MemberStatusTransition(old=_MemberStatusGroupMarker(other), new=new)
@ -118,7 +118,7 @@ class _MemberStatusGroupMarker:
def __rshift__( def __rshift__(
self, self,
other: _MemberStatusMarker | _MemberStatusGroupMarker, other: _MemberStatusMarker | _MemberStatusGroupMarker,
) -> "_MemberStatusTransition": ) -> _MemberStatusTransition:
if isinstance(other, _MemberStatusMarker): if isinstance(other, _MemberStatusMarker):
return _MemberStatusTransition(old=self, new=_MemberStatusGroupMarker(other)) return _MemberStatusTransition(old=self, new=_MemberStatusGroupMarker(other))
if isinstance(other, _MemberStatusGroupMarker): if isinstance(other, _MemberStatusGroupMarker):
@ -132,7 +132,7 @@ class _MemberStatusGroupMarker:
def __lshift__( def __lshift__(
self, self,
other: _MemberStatusMarker | _MemberStatusGroupMarker, other: _MemberStatusMarker | _MemberStatusGroupMarker,
) -> "_MemberStatusTransition": ) -> _MemberStatusTransition:
if isinstance(other, _MemberStatusMarker): if isinstance(other, _MemberStatusMarker):
return _MemberStatusTransition(old=_MemberStatusGroupMarker(other), new=self) return _MemberStatusTransition(old=_MemberStatusGroupMarker(other), new=self)
if isinstance(other, _MemberStatusGroupMarker): if isinstance(other, _MemberStatusGroupMarker):

View file

@ -123,14 +123,15 @@ class Command(Filter):
result.update(command.magic_result) result.update(command.magic_result)
return result return result
def extract_command(self, text: str) -> CommandObject: @classmethod
def extract_command(cls, text: str) -> CommandObject:
# First step: separate command with arguments # First step: separate command with arguments
# "/command@mention arg1 arg2" -> "/command@mention", ["arg1 arg2"] # "/command@mention arg1 arg2" -> "/command@mention", ["arg1 arg2"]
try: try:
full_command, *args = text.split(maxsplit=1) full_command, *args = text.split(maxsplit=1)
except ValueError: except ValueError as e:
msg = "not enough values to unpack" msg = "not enough values to unpack"
raise CommandException(msg) raise CommandException(msg) from e
# Separate command into valuable parts # Separate command into valuable parts
# "/command@mention" -> "/", ("command", "@", "mention") # "/command@mention" -> "/", ("command", "@", "mention")
@ -292,6 +293,6 @@ class CommandStart(Command):
args = decode_payload(args) args = decode_payload(args)
except UnicodeDecodeError as e: except UnicodeDecodeError as e:
msg = f"Failed to decode Base64: {e}" msg = f"Failed to decode Base64: {e}"
raise CommandException(msg) raise CommandException(msg) from e
return replace(command, args=args) return replace(command, args=args)
return command return command

View file

@ -120,7 +120,7 @@ class ObserverDecorator:
handlers = getattr(target, "__aiogram_handler__", None) handlers = getattr(target, "__aiogram_handler__", None)
if not handlers: if not handlers:
handlers = [] handlers = []
setattr(target, "__aiogram_handler__", handlers) target.__aiogram_handler__ = handlers # type: ignore[union-attr]
handlers.append( handlers.append(
HandlerContainer( HandlerContainer(
@ -137,7 +137,7 @@ class ObserverDecorator:
action = getattr(target, "__aiogram_action__", None) action = getattr(target, "__aiogram_action__", None)
if action is None: if action is None:
action = defaultdict(dict) action = defaultdict(dict)
setattr(target, "__aiogram_action__", action) target.__aiogram_action__ = action # type: ignore[attr-defined]
action[self.action][self.name] = CallableObject(target) action[self.action][self.name] = CallableObject(target)
def __call__(self, target: CallbackType) -> CallbackType: def __call__(self, target: CallbackType) -> CallbackType:
@ -865,7 +865,7 @@ class SceneRegistry:
return self._scenes[scene] return self._scenes[scene]
except KeyError: except KeyError:
msg = f"Scene {scene!r} is not registered" msg = f"Scene {scene!r} is not registered"
raise SceneException(msg) raise SceneException(msg) from None
@dataclass @dataclass

View file

@ -1,11 +1,11 @@
from __future__ import annotations from __future__ import annotations
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from collections.abc import Generator
from typing import ( from typing import (
TYPE_CHECKING, TYPE_CHECKING,
Any, Any,
ClassVar, ClassVar,
Generator,
Generic, Generic,
TypeVar, TypeVar,
) )

View file

@ -1,4 +1,4 @@
from typing import List, Literal, Optional, Union from typing import Literal, Optional, Union
from .accepted_gift_types import AcceptedGiftTypes from .accepted_gift_types import AcceptedGiftTypes
from .affiliate_info import AffiliateInfo from .affiliate_info import AffiliateInfo
@ -654,7 +654,7 @@ for _entity_name in __all__:
continue continue
_entity.model_rebuild( _entity.model_rebuild(
_types_namespace={ _types_namespace={
"List": List, "List": list,
"Optional": Optional, "Optional": Optional,
"Union": Union, "Union": Union,
"Literal": Literal, "Literal": Literal,

View file

@ -1,8 +1,8 @@
import sys import sys
from datetime import datetime, timezone from datetime import datetime, timezone
from typing import Annotated
from pydantic import PlainSerializer from pydantic import PlainSerializer
from typing_extensions import Annotated
if sys.platform == "win32": # pragma: no cover if sys.platform == "win32": # pragma: no cover

View file

@ -130,9 +130,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendMessage from aiogram.methods import SendMessage
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendMessage( return SendMessage(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -208,9 +208,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendMessage from aiogram.methods import SendMessage
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendMessage( return SendMessage(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -298,9 +298,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendAnimation from aiogram.methods import SendAnimation
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendAnimation( return SendAnimation(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -391,9 +391,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendAnimation from aiogram.methods import SendAnimation
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendAnimation( return SendAnimation(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -483,9 +483,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendAudio from aiogram.methods import SendAudio
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendAudio( return SendAudio(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -571,9 +571,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendAudio from aiogram.methods import SendAudio
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendAudio( return SendAudio(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -652,9 +652,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendContact from aiogram.methods import SendContact
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendContact( return SendContact(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -727,9 +727,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendContact from aiogram.methods import SendContact
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendContact( return SendContact(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -808,9 +808,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendDocument from aiogram.methods import SendDocument
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendDocument( return SendDocument(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -889,9 +889,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendDocument from aiogram.methods import SendDocument
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendDocument( return SendDocument(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -958,9 +958,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendGame from aiogram.methods import SendGame
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendGame( return SendGame(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1018,9 +1018,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendGame from aiogram.methods import SendGame
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendGame( return SendGame(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1122,9 +1122,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendInvoice from aiogram.methods import SendInvoice
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendInvoice( return SendInvoice(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1245,9 +1245,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendInvoice from aiogram.methods import SendInvoice
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendInvoice( return SendInvoice(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1342,9 +1342,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendLocation from aiogram.methods import SendLocation
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendLocation( return SendLocation(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1423,9 +1423,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendLocation from aiogram.methods import SendLocation
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendLocation( return SendLocation(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1492,9 +1492,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendMediaGroup from aiogram.methods import SendMediaGroup
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendMediaGroup( return SendMediaGroup(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1552,9 +1552,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendMediaGroup from aiogram.methods import SendMediaGroup
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendMediaGroup( return SendMediaGroup(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1628,9 +1628,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendPhoto from aiogram.methods import SendPhoto
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendPhoto( return SendPhoto(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1709,9 +1709,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendPhoto from aiogram.methods import SendPhoto
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendPhoto( return SendPhoto(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1804,9 +1804,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendPoll from aiogram.methods import SendPoll
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendPoll( return SendPoll(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1903,9 +1903,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendPoll from aiogram.methods import SendPoll
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendPoll( return SendPoll(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1982,9 +1982,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendDice from aiogram.methods import SendDice
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendDice( return SendDice(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2048,9 +2048,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendDice from aiogram.methods import SendDice
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendDice( return SendDice(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2118,9 +2118,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendSticker from aiogram.methods import SendSticker
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendSticker( return SendSticker(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2187,9 +2187,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendSticker from aiogram.methods import SendSticker
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendSticker( return SendSticker(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2270,9 +2270,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendVenue from aiogram.methods import SendVenue
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendVenue( return SendVenue(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2357,9 +2357,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendVenue from aiogram.methods import SendVenue
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendVenue( return SendVenue(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2456,9 +2456,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendVideo from aiogram.methods import SendVideo
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendVideo( return SendVideo(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2558,9 +2558,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendVideo from aiogram.methods import SendVideo
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendVideo( return SendVideo(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2644,9 +2644,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendVideoNote from aiogram.methods import SendVideoNote
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendVideoNote( return SendVideoNote(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2719,9 +2719,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendVideoNote from aiogram.methods import SendVideoNote
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendVideoNote( return SendVideoNote(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2798,9 +2798,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendVoice from aiogram.methods import SendVoice
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendVoice( return SendVoice(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2876,9 +2876,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendVoice from aiogram.methods import SendVoice
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendVoice( return SendVoice(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2954,9 +2954,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendPaidMedia from aiogram.methods import SendPaidMedia
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendPaidMedia( return SendPaidMedia(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -3031,9 +3031,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
from aiogram.methods import SendPaidMedia from aiogram.methods import SendPaidMedia
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendPaidMedia( return SendPaidMedia(
chat_id=self.chat.id, chat_id=self.chat.id,

View file

@ -3,8 +3,9 @@ from __future__ import annotations
import io import io
import os import os
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from collections.abc import AsyncGenerator
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, Any, AsyncGenerator from typing import TYPE_CHECKING, Any
import aiofiles import aiofiles
@ -33,7 +34,7 @@ class InputFile(ABC):
self.chunk_size = chunk_size self.chunk_size = chunk_size
@abstractmethod @abstractmethod
async def read(self, bot: "Bot") -> AsyncGenerator[bytes, None]: # pragma: no cover async def read(self, bot: Bot) -> AsyncGenerator[bytes, None]: # pragma: no cover
yield b"" yield b""
@ -72,7 +73,7 @@ class BufferedInputFile(InputFile):
data = f.read() data = f.read()
return cls(data, filename=filename, chunk_size=chunk_size) return cls(data, filename=filename, chunk_size=chunk_size)
async def read(self, bot: "Bot") -> AsyncGenerator[bytes, None]: async def read(self, bot: Bot) -> AsyncGenerator[bytes, None]:
buffer = io.BytesIO(self.data) buffer = io.BytesIO(self.data)
while chunk := buffer.read(self.chunk_size): while chunk := buffer.read(self.chunk_size):
yield chunk yield chunk
@ -99,7 +100,7 @@ class FSInputFile(InputFile):
self.path = path self.path = path
async def read(self, bot: "Bot") -> AsyncGenerator[bytes, None]: async def read(self, bot: Bot) -> AsyncGenerator[bytes, None]:
async with aiofiles.open(self.path, "rb") as f: async with aiofiles.open(self.path, "rb") as f:
while chunk := await f.read(self.chunk_size): while chunk := await f.read(self.chunk_size):
yield chunk yield chunk
@ -135,7 +136,7 @@ class URLInputFile(InputFile):
self.timeout = timeout self.timeout = timeout
self.bot = bot self.bot = bot
async def read(self, bot: "Bot") -> AsyncGenerator[bytes, None]: async def read(self, bot: Bot) -> AsyncGenerator[bytes, None]:
bot = self.bot or bot bot = self.bot or bot
stream = bot.session.stream_content( stream = bot.session.stream_content(
url=self.url, url=self.url,

View file

@ -851,9 +851,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendAnimation from aiogram.methods import SendAnimation
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendAnimation( return SendAnimation(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -944,9 +944,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendAnimation from aiogram.methods import SendAnimation
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendAnimation( return SendAnimation(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1032,9 +1032,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendAudio from aiogram.methods import SendAudio
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendAudio( return SendAudio(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1120,9 +1120,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendAudio from aiogram.methods import SendAudio
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendAudio( return SendAudio(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1197,9 +1197,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendContact from aiogram.methods import SendContact
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendContact( return SendContact(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1272,9 +1272,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendContact from aiogram.methods import SendContact
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendContact( return SendContact(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1349,9 +1349,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendDocument from aiogram.methods import SendDocument
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendDocument( return SendDocument(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1430,9 +1430,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendDocument from aiogram.methods import SendDocument
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendDocument( return SendDocument(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1495,9 +1495,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendGame from aiogram.methods import SendGame
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendGame( return SendGame(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1555,9 +1555,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendGame from aiogram.methods import SendGame
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendGame( return SendGame(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1657,9 +1657,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendInvoice from aiogram.methods import SendInvoice
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendInvoice( return SendInvoice(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1783,9 +1783,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendInvoice from aiogram.methods import SendInvoice
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendInvoice( return SendInvoice(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1877,9 +1877,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendLocation from aiogram.methods import SendLocation
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendLocation( return SendLocation(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -1958,9 +1958,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendLocation from aiogram.methods import SendLocation
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendLocation( return SendLocation(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2023,9 +2023,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendMediaGroup from aiogram.methods import SendMediaGroup
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendMediaGroup( return SendMediaGroup(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2083,9 +2083,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendMediaGroup from aiogram.methods import SendMediaGroup
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendMediaGroup( return SendMediaGroup(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2153,9 +2153,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendMessage from aiogram.methods import SendMessage
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendMessage( return SendMessage(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2231,9 +2231,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendMessage from aiogram.methods import SendMessage
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendMessage( return SendMessage(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2309,9 +2309,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendPhoto from aiogram.methods import SendPhoto
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendPhoto( return SendPhoto(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2390,9 +2390,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendPhoto from aiogram.methods import SendPhoto
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendPhoto( return SendPhoto(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2481,9 +2481,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendPoll from aiogram.methods import SendPoll
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendPoll( return SendPoll(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2580,9 +2580,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendPoll from aiogram.methods import SendPoll
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendPoll( return SendPoll(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2655,9 +2655,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendDice from aiogram.methods import SendDice
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendDice( return SendDice(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2721,9 +2721,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendDice from aiogram.methods import SendDice
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendDice( return SendDice(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2787,9 +2787,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendSticker from aiogram.methods import SendSticker
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendSticker( return SendSticker(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2856,9 +2856,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendSticker from aiogram.methods import SendSticker
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendSticker( return SendSticker(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -2935,9 +2935,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendVenue from aiogram.methods import SendVenue
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendVenue( return SendVenue(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -3022,9 +3022,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendVenue from aiogram.methods import SendVenue
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendVenue( return SendVenue(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -3117,9 +3117,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendVideo from aiogram.methods import SendVideo
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendVideo( return SendVideo(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -3219,9 +3219,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendVideo from aiogram.methods import SendVideo
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendVideo( return SendVideo(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -3301,9 +3301,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendVideoNote from aiogram.methods import SendVideoNote
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendVideoNote( return SendVideoNote(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -3376,9 +3376,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendVideoNote from aiogram.methods import SendVideoNote
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendVideoNote( return SendVideoNote(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -3451,9 +3451,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendVoice from aiogram.methods import SendVoice
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendVoice( return SendVoice(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -3529,9 +3529,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendVoice from aiogram.methods import SendVoice
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendVoice( return SendVoice(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -3808,9 +3808,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import CopyMessage from aiogram.methods import CopyMessage
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return CopyMessage( return CopyMessage(
from_chat_id=self.chat.id, from_chat_id=self.chat.id,
@ -3872,9 +3872,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import EditMessageText from aiogram.methods import EditMessageText
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return EditMessageText( return EditMessageText(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -3928,9 +3928,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import ForwardMessage from aiogram.methods import ForwardMessage
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return ForwardMessage( return ForwardMessage(
from_chat_id=self.chat.id, from_chat_id=self.chat.id,
@ -3975,9 +3975,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import EditMessageMedia from aiogram.methods import EditMessageMedia
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return EditMessageMedia( return EditMessageMedia(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -4016,9 +4016,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import EditMessageReplyMarkup from aiogram.methods import EditMessageReplyMarkup
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return EditMessageReplyMarkup( return EditMessageReplyMarkup(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -4055,9 +4055,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import EditMessageReplyMarkup from aiogram.methods import EditMessageReplyMarkup
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return EditMessageReplyMarkup( return EditMessageReplyMarkup(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -4107,9 +4107,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import EditMessageLiveLocation from aiogram.methods import EditMessageLiveLocation
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return EditMessageLiveLocation( return EditMessageLiveLocation(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -4153,9 +4153,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import StopMessageLiveLocation from aiogram.methods import StopMessageLiveLocation
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return StopMessageLiveLocation( return StopMessageLiveLocation(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -4201,9 +4201,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import EditMessageCaption from aiogram.methods import EditMessageCaption
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return EditMessageCaption( return EditMessageCaption(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -4261,9 +4261,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import DeleteMessage from aiogram.methods import DeleteMessage
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return DeleteMessage( return DeleteMessage(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -4297,9 +4297,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import PinChatMessage from aiogram.methods import PinChatMessage
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return PinChatMessage( return PinChatMessage(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -4332,9 +4332,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import UnpinChatMessage from aiogram.methods import UnpinChatMessage
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return UnpinChatMessage( return UnpinChatMessage(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -4353,7 +4353,7 @@ class Message(MaybeInaccessibleMessage):
:param include_thread_id: if set, adds chat thread id to URL and returns like https://t.me/username/thread_id/message_id :param include_thread_id: if set, adds chat thread id to URL and returns like https://t.me/username/thread_id/message_id
:return: string with full message URL :return: string with full message URL
""" """
if self.chat.type in ("private", "group"): if self.chat.type in {"private", "group"}:
return None return None
chat_value = ( chat_value = (
@ -4397,9 +4397,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SetMessageReaction from aiogram.methods import SetMessageReaction
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SetMessageReaction( return SetMessageReaction(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -4461,9 +4461,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendPaidMedia from aiogram.methods import SendPaidMedia
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendPaidMedia( return SendPaidMedia(
chat_id=self.chat.id, chat_id=self.chat.id,
@ -4536,9 +4536,9 @@ class Message(MaybeInaccessibleMessage):
from aiogram.methods import SendPaidMedia from aiogram.methods import SendPaidMedia
assert ( assert self.chat is not None, (
self.chat is not None "This method can be used only if chat is present in the message."
), "This method can be used only if chat is present in the message." )
return SendPaidMedia( return SendPaidMedia(
chat_id=self.chat.id, chat_id=self.chat.id,

View file

@ -22,6 +22,7 @@ if TYPE_CHECKING:
from aiogram import Bot from aiogram import Bot
BAD_PATTERN = re.compile(r"[^a-zA-Z0-9-_]") BAD_PATTERN = re.compile(r"[^a-zA-Z0-9-_]")
DEEPLINK_PAYLOAD_LENGTH = 64
async def create_start_link( async def create_start_link(
@ -145,8 +146,8 @@ def create_deep_link(
) )
raise ValueError(msg) raise ValueError(msg)
if len(payload) > 64: if len(payload) > DEEPLINK_PAYLOAD_LENGTH:
msg = "Payload must be up to 64 characters long." msg = f"Payload must be up to {DEEPLINK_PAYLOAD_LENGTH} characters long."
raise ValueError(msg) raise ValueError(msg)
if not app_name: if not app_name:

View file

@ -15,7 +15,7 @@ class DataMixin:
data: dict[str, Any] | None = getattr(self, "_data", None) data: dict[str, Any] | None = getattr(self, "_data", None)
if data is None: if data is None:
data = {} data = {}
setattr(self, "_data", data) self._data = data
return data return data
def __getitem__(self, key: str) -> Any: def __getitem__(self, key: str) -> Any:

View file

@ -148,8 +148,8 @@ When using :code:`uv`, prefix commands with :code:`uv run` to execute them in th
.. code-block:: bash .. code-block:: bash
# Format code # Format code
uv run black aiogram tests examples uv run ruff format aiogram tests scripts examples
uv run isort aiogram tests examples uv run ruff check --fix aiogram tests scripts examples
# Run tests # Run tests
uv run pytest tests uv run pytest tests
@ -180,22 +180,22 @@ implementing new features or experimenting.
Format the code (code-style) Format the code (code-style)
---------------------------- ----------------------------
Note that this project is Black-formatted, so you should follow that code-style, Note that this project uses Ruff for formatting and linting, so you should follow that code-style.
too be sure You're correctly doing this let's reformat the code automatically: To be sure you're correctly doing this, let's reformat the code automatically:
Using traditional approach: Using traditional approach:
.. code-block:: bash .. code-block:: bash
black aiogram tests examples ruff format aiogram tests scripts examples
isort aiogram tests examples ruff check --fix aiogram tests scripts examples
Or with uv: Or with uv:
.. code-block:: bash .. code-block:: bash
uv run black aiogram tests examples uv run ruff format aiogram tests scripts examples
uv run isort aiogram tests examples uv run ruff check --fix aiogram tests scripts examples
Or simply use Makefile: Or simply use Makefile:

View file

@ -2,12 +2,11 @@ import asyncio
import logging import logging
from os import getenv from os import getenv
from handlers.echo import echo_router
from handlers.start import start_router
from aiogram import Bot, Dispatcher from aiogram import Bot, Dispatcher
from aiogram.client.default import DefaultBotProperties from aiogram.client.default import DefaultBotProperties
from aiogram.enums import ParseMode from aiogram.enums import ParseMode
from handlers.echo import echo_router
from handlers.start import start_router
# Bot token can be obtained via https://t.me/BotFather # Bot token can be obtained via https://t.me/BotFather
TOKEN = getenv("BOT_TOKEN") TOKEN = getenv("BOT_TOKEN")

View file

@ -4,7 +4,6 @@ from os import getenv
from typing import Any from typing import Any
from aiohttp import web from aiohttp import web
from finite_state_machine import form_router
from aiogram import Bot, Dispatcher, F, Router from aiogram import Bot, Dispatcher, F, Router
from aiogram.client.session.aiohttp import AiohttpSession from aiogram.client.session.aiohttp import AiohttpSession
@ -19,6 +18,7 @@ from aiogram.webhook.aiohttp_server import (
TokenBasedRequestHandler, TokenBasedRequestHandler,
setup_application, setup_application,
) )
from finite_state_machine import form_router
main_router = Router() main_router = Router()

View file

@ -4,14 +4,14 @@ from os import getenv
from aiohttp.web import run_app from aiohttp.web import run_app
from aiohttp.web_app import Application from aiohttp.web_app import Application
from handlers import my_router
from routes import check_data_handler, demo_handler, send_message_handler
from aiogram import Bot, Dispatcher from aiogram import Bot, Dispatcher
from aiogram.client.default import DefaultBotProperties from aiogram.client.default import DefaultBotProperties
from aiogram.enums.parse_mode import ParseMode from aiogram.enums.parse_mode import ParseMode
from aiogram.types import MenuButtonWebApp, WebAppInfo from aiogram.types import MenuButtonWebApp, WebAppInfo
from aiogram.webhook.aiohttp_server import SimpleRequestHandler, setup_application from aiogram.webhook.aiohttp_server import SimpleRequestHandler, setup_application
from handlers import my_router
from routes import check_data_handler, demo_handler, send_message_handler
TOKEN = getenv("BOT_TOKEN") TOKEN = getenv("BOT_TOKEN")

View file

@ -94,8 +94,6 @@ docs = [
[dependency-groups] [dependency-groups]
dev = [ dev = [
"black~=25.9",
"isort~=7.0",
"ruff~=0.14", "ruff~=0.14",
"mypy==1.10.1", "mypy==1.10.1",
"toml~=0.10.2", "toml~=0.10.2",
@ -139,16 +137,38 @@ exclude = [
[tool.ruff.lint] [tool.ruff.lint]
select = [ select = [
# "C", # TODO: mccabe - code complecity # "C", # TODO: mccabe - code complecity
"C4", "A", # flake8-annotations
"E", "B", # flake8-bugbear
"F", "C4", # flake8-comprehensions
"Q", "DTZ", # flake8-datetimez
"RET", "E", # pycodestyle errors
"T10", "F", # pyflakes
"T20", "I", # isort
"PERF", # perflint
"PL", # pylint
"Q", # flake8-quotes
"RET", # flake8-return
"SIM", # flake8-simplify
"T10", # flake8-debugger
"T20", # flake8-print
"UP", # pyupgrade
] ]
ignore = [ ignore = [
"F401", "F401", # unused-import (handled by other tools)
"A002", # builtin-argument-shadowing (common in API: type, id, format, etc.)
"A005", # stdlib-module-shadowing (Module `types` shadows a Python standard-library module)
"B008", # function-call-in-default-argument (Pydantic Field() defaults)
"PLC0415", # import-outside-top-level (needed for circular imports)
"PLC1901", # compare-to-empty-string (sometimes more explicit is better)
"PLR0904", # too-many-public-methods (Bot class has many API methods)
"PLR0911", # too-many-return-statements
"PLR0912", # too-many-branches
"PLR0913", # too-many-arguments (Telegram API methods have many params)
"PLR0915", # too-many-statements
"PLR0917", # too-many-positional-arguments (Telegram API design)
"PLR6301", # no-self-use (sometimes methods are intentionally not static)
"PLW2901", # redefined-loop-name (intentional pattern in this codebase)
"PLW3201", # bad-dunder-method-name (custom dunders for framework design)
] ]
[tool.ruff.lint.isort] [tool.ruff.lint.isort]
@ -164,6 +184,20 @@ known-first-party = [
"aiogram/types/*" = ["E501"] "aiogram/types/*" = ["E501"]
"aiogram/methods/*" = ["E501"] "aiogram/methods/*" = ["E501"]
"aiogram/enums/*" = ["E501"] "aiogram/enums/*" = ["E501"]
"tests/**" = [
"PLR0124",
"PLR2004",
"DTZ005",
"DTZ006",
"A001",
"A004",
"B018",
"B020",
"B904",
"E501",
"F821",
"UP",
]
[tool.pytest.ini_options] [tool.pytest.ini_options]
@ -174,7 +208,6 @@ testpaths = [
filterwarnings = [ filterwarnings = [
"error", "error",
"ignore::pytest.PytestUnraisableExceptionWarning", "ignore::pytest.PytestUnraisableExceptionWarning",
# Remove when uvloop fixes the issue # Remove when uvloop fixes the issue
# https://github.com/MagicStack/uvloop/issues/703 # https://github.com/MagicStack/uvloop/issues/703
# https://github.com/MagicStack/uvloop/pull/705 # https://github.com/MagicStack/uvloop/pull/705
@ -235,23 +268,10 @@ module = [
ignore_missing_imports = true ignore_missing_imports = true
disallow_untyped_defs = true disallow_untyped_defs = true
[tool.black] [tool.ruff.format]
line-length = 99 quote-style = "double"
target-version = ['py310', 'py311', 'py312', 'py313'] indent-style = "space"
exclude = ''' line-ending = "auto"
(
\.eggs
| \.git
| \.tox
| build
| dist
| venv
| docs
)
'''
[tool.isort]
profile = "black"
[tool.towncrier] [tool.towncrier]
package = "aiogram" package = "aiogram"

View file

@ -1,5 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Version bumping script for aiogram (replaces hatch version).""" """Version bumping script for aiogram (replaces hatch version)."""
import re import re
import sys import sys
from pathlib import Path from pathlib import Path

View file

@ -144,8 +144,7 @@ async def memory_storage():
@pytest.fixture() @pytest.fixture()
async def redis_isolation(redis_storage): async def redis_isolation(redis_storage):
isolation = redis_storage.create_isolation() return redis_storage.create_isolation()
return isolation
@pytest.fixture() @pytest.fixture()

View file

@ -1,5 +1,4 @@
from contextlib import contextmanager from contextlib import contextmanager
from typing import Type
import pytest import pytest
from packaging import version from packaging import version
@ -10,8 +9,8 @@ import aiogram
@contextmanager @contextmanager
def check_deprecated( def check_deprecated(
max_version: str, max_version: str,
exception: Type[Exception], exception: type[Exception],
warning: Type[Warning] = DeprecationWarning, warning: type[Warning] = DeprecationWarning,
) -> None: ) -> None:
""" """
Should be used for modules that are being deprecated or already removed from aiogram Should be used for modules that are being deprecated or already removed from aiogram

View file

@ -1,5 +1,6 @@
from collections import deque from collections import deque
from typing import TYPE_CHECKING, Any, AsyncGenerator, Deque, Dict, Optional, Type from collections.abc import AsyncGenerator
from typing import TYPE_CHECKING, Any
from aiogram import Bot from aiogram import Bot
from aiogram.client.session.base import BaseSession from aiogram.client.session.base import BaseSession
@ -10,9 +11,9 @@ from aiogram.types import UNSET_PARSE_MODE, ResponseParameters, User
class MockedSession(BaseSession): class MockedSession(BaseSession):
def __init__(self): def __init__(self):
super(MockedSession, self).__init__() super().__init__()
self.responses: Deque[Response[TelegramType]] = deque() self.responses: deque[Response[TelegramType]] = deque()
self.requests: Deque[TelegramMethod[TelegramType]] = deque() self.requests: deque[TelegramMethod[TelegramType]] = deque()
self.closed = True self.closed = True
def add_result(self, response: Response[TelegramType]) -> Response[TelegramType]: def add_result(self, response: Response[TelegramType]) -> Response[TelegramType]:
@ -29,7 +30,7 @@ class MockedSession(BaseSession):
self, self,
bot: Bot, bot: Bot,
method: TelegramMethod[TelegramType], method: TelegramMethod[TelegramType],
timeout: Optional[int] = UNSET_PARSE_MODE, timeout: int | None = UNSET_PARSE_MODE,
) -> TelegramType: ) -> TelegramType:
self.closed = False self.closed = False
self.requests.append(method) self.requests.append(method)
@ -45,7 +46,7 @@ class MockedSession(BaseSession):
async def stream_content( async def stream_content(
self, self,
url: str, url: str,
headers: Optional[Dict[str, Any]] = None, headers: dict[str, Any] | None = None,
timeout: int = 30, timeout: int = 30,
chunk_size: int = 65536, chunk_size: int = 65536,
raise_for_status: bool = True, raise_for_status: bool = True,
@ -58,9 +59,7 @@ class MockedBot(Bot):
session: MockedSession session: MockedSession
def __init__(self, **kwargs): def __init__(self, **kwargs):
super(MockedBot, self).__init__( super().__init__(kwargs.pop("token", "42:TEST"), session=MockedSession(), **kwargs)
kwargs.pop("token", "42:TEST"), session=MockedSession(), **kwargs
)
self._me = User( self._me = User(
id=self.id, id=self.id,
is_bot=True, is_bot=True,
@ -72,13 +71,13 @@ class MockedBot(Bot):
def add_result_for( def add_result_for(
self, self,
method: Type[TelegramMethod[TelegramType]], method: type[TelegramMethod[TelegramType]],
ok: bool, ok: bool,
result: TelegramType = None, result: TelegramType = None,
description: Optional[str] = None, description: str | None = None,
error_code: int = 200, error_code: int = 200,
migrate_to_chat_id: Optional[int] = None, migrate_to_chat_id: int | None = None,
retry_after: Optional[int] = None, retry_after: int | None = None,
) -> Response[TelegramType]: ) -> Response[TelegramType]:
response = Response[method.__returning__]( # type: ignore response = Response[method.__returning__]( # type: ignore
ok=ok, ok=ok,

View file

@ -1,12 +1,8 @@
import asyncio import asyncio
from collections.abc import AsyncGenerator, AsyncIterable
from typing import ( from typing import (
Any, Any,
AsyncContextManager, AsyncContextManager,
AsyncGenerator,
AsyncIterable,
Dict,
List,
Union,
) )
from unittest.mock import AsyncMock, patch from unittest.mock import AsyncMock, patch
@ -115,10 +111,10 @@ class TestAiohttpSession:
str_: str str_: str
int_: int int_: int
bool_: bool bool_: bool
unset_: Union[str, Default] = Default("parse_mode") unset_: str | Default = Default("parse_mode")
null_: None null_: None
list_: List[str] list_: list[str]
dict_: Dict[str, Any] dict_: dict[str, Any]
session = AiohttpSession() session = AiohttpSession()
form = session.build_form_data( form = session.build_form_data(

View file

@ -1,6 +1,7 @@
import datetime import datetime
import json import json
from typing import Any, AsyncContextManager, AsyncGenerator, Dict, Optional from collections.abc import AsyncGenerator
from typing import Any, AsyncContextManager
from unittest.mock import AsyncMock, patch from unittest.mock import AsyncMock, patch
import pytest import pytest
@ -39,7 +40,7 @@ class CustomSession(BaseSession):
self, self,
token: str, token: str,
method: TelegramMethod[TelegramType], method: TelegramMethod[TelegramType],
timeout: Optional[int] = UNSET_PARSE_MODE, timeout: int | None = UNSET_PARSE_MODE,
) -> None: # type: ignore ) -> None: # type: ignore
assert isinstance(token, str) assert isinstance(token, str)
assert isinstance(method, TelegramMethod) assert isinstance(method, TelegramMethod)
@ -47,7 +48,7 @@ class CustomSession(BaseSession):
async def stream_content( async def stream_content(
self, self,
url: str, url: str,
headers: Optional[Dict[str, Any]] = None, headers: dict[str, Any] | None = None,
timeout: int = 30, timeout: int = 30,
chunk_size: int = 65536, chunk_size: int = 65536,
raise_for_status: bool = True, raise_for_status: bool = True,

View file

@ -15,5 +15,5 @@ class TestAddStickerToSet:
sticker="file id", format=StickerFormat.STATIC, emoji_list=[":)"] sticker="file id", format=StickerFormat.STATIC, emoji_list=[":)"]
), ),
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -7,5 +7,5 @@ class TestAnswerCallbackQuery:
prepare_result = bot.add_result_for(AnswerCallbackQuery, ok=True, result=True) prepare_result = bot.add_result_for(AnswerCallbackQuery, ok=True, result=True)
response: bool = await bot.answer_callback_query(callback_query_id="cq id", text="OK") response: bool = await bot.answer_callback_query(callback_query_id="cq id", text="OK")
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -17,5 +17,5 @@ class TestAnswerInlineQuery:
) )
], ],
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -9,5 +9,5 @@ class TestAnswerPreCheckoutQuery:
response: bool = await bot.answer_pre_checkout_query( response: bool = await bot.answer_pre_checkout_query(
pre_checkout_query_id="query id", ok=True pre_checkout_query_id="query id", ok=True
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -7,5 +7,5 @@ class TestAnswerShippingQuery:
prepare_result = bot.add_result_for(AnswerShippingQuery, ok=True, result=True) prepare_result = bot.add_result_for(AnswerShippingQuery, ok=True, result=True)
response: bool = await bot.answer_shipping_query(shipping_query_id="query id", ok=True) response: bool = await bot.answer_shipping_query(shipping_query_id="query id", ok=True)
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -15,5 +15,5 @@ class TestAnswerWebAppQuery:
thumbnail_url="test", thumbnail_url="test",
), ),
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -10,5 +10,5 @@ class TestApproveChatJoinRequest:
chat_id=-42, chat_id=-42,
user_id=42, user_id=42,
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -10,5 +10,5 @@ class TestApproveSuggestedPost:
chat_id=-42, chat_id=-42,
message_id=42, message_id=42,
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -7,5 +7,5 @@ class TestKickChatMember:
prepare_result = bot.add_result_for(BanChatMember, ok=True, result=True) prepare_result = bot.add_result_for(BanChatMember, ok=True, result=True)
response: bool = await bot.ban_chat_member(chat_id=-42, user_id=42) response: bool = await bot.ban_chat_member(chat_id=-42, user_id=42)
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -10,5 +10,5 @@ class TestBanChatSenderChat:
chat_id=-42, chat_id=-42,
sender_chat_id=-1337, sender_chat_id=-1337,
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -7,5 +7,5 @@ class TestClose:
prepare_result = bot.add_result_for(Close, ok=True, result=True) prepare_result = bot.add_result_for(Close, ok=True, result=True)
response: bool = await bot.close() response: bool = await bot.close()
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -10,5 +10,5 @@ class TestCloseForumTopic:
chat_id=42, chat_id=42,
message_thread_id=42, message_thread_id=42,
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -7,5 +7,5 @@ class TestCloseGeneralForumTopic:
prepare_result = bot.add_result_for(CloseGeneralForumTopic, ok=True, result=True) prepare_result = bot.add_result_for(CloseGeneralForumTopic, ok=True, result=True)
response: bool = await bot.close_general_forum_topic(chat_id=42) response: bool = await bot.close_general_forum_topic(chat_id=42)
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -9,5 +9,5 @@ class TestConvertGiftToStars:
response: bool = await bot.convert_gift_to_stars( response: bool = await bot.convert_gift_to_stars(
business_connection_id="test_connection_id", owned_gift_id="test_gift_id" business_connection_id="test_connection_id", owned_gift_id="test_gift_id"
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -12,5 +12,5 @@ class TestCopyMessage:
from_chat_id=42, from_chat_id=42,
message_id=42, message_id=42,
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -20,5 +20,5 @@ class TestCreateChatInviteLink:
response: ChatInviteLink = await bot.create_chat_invite_link( response: ChatInviteLink = await bot.create_chat_invite_link(
chat_id=-42, chat_id=-42,
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -24,5 +24,5 @@ class TestCreateChatSubscriptionInviteLink:
subscription_period=timedelta(days=30), subscription_period=timedelta(days=30),
subscription_price=42, subscription_price=42,
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -15,5 +15,5 @@ class TestCreateForumTopic:
chat_id=42, chat_id=42,
name="test", name="test",
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -17,5 +17,5 @@ class TestCreateInvoiceLink:
currency="BTC", currency="BTC",
prices=[LabeledPrice(label="Test", amount=1)], prices=[LabeledPrice(label="Test", amount=1)],
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -20,5 +20,5 @@ class TestCreateNewStickerSet:
], ],
sticker_format=StickerFormat.STATIC, sticker_format=StickerFormat.STATIC,
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -10,5 +10,5 @@ class TestDeclineChatJoinRequest:
chat_id=-42, chat_id=-42,
user_id=42, user_id=42,
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -10,5 +10,5 @@ class TestDeclineSuggestedPost:
chat_id=-42, chat_id=-42,
message_id=42, message_id=42,
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -9,5 +9,5 @@ class TestDeleteBusinessMessages:
response: bool = await bot.delete_business_messages( response: bool = await bot.delete_business_messages(
business_connection_id="test_connection_id", message_ids=[1, 2, 3] business_connection_id="test_connection_id", message_ids=[1, 2, 3]
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -7,5 +7,5 @@ class TestDeleteChatPhoto:
prepare_result = bot.add_result_for(DeleteChatPhoto, ok=True, result=True) prepare_result = bot.add_result_for(DeleteChatPhoto, ok=True, result=True)
response: bool = await bot.delete_chat_photo(chat_id=42) response: bool = await bot.delete_chat_photo(chat_id=42)
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -7,5 +7,5 @@ class TestDeleteChatStickerSet:
prepare_result = bot.add_result_for(DeleteChatStickerSet, ok=True, result=True) prepare_result = bot.add_result_for(DeleteChatStickerSet, ok=True, result=True)
response: bool = await bot.delete_chat_sticker_set(chat_id=42) response: bool = await bot.delete_chat_sticker_set(chat_id=42)
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -10,5 +10,5 @@ class TestDeleteForumTopic:
chat_id=42, chat_id=42,
message_thread_id=42, message_thread_id=42,
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -7,5 +7,5 @@ class TestDeleteMessage:
prepare_result = bot.add_result_for(DeleteMessage, ok=True, result=True) prepare_result = bot.add_result_for(DeleteMessage, ok=True, result=True)
response: bool = await bot.delete_message(chat_id=42, message_id=42) response: bool = await bot.delete_message(chat_id=42, message_id=42)
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -7,5 +7,5 @@ class TestKickChatMember:
prepare_result = bot.add_result_for(DeleteMyCommands, ok=True, result=True) prepare_result = bot.add_result_for(DeleteMyCommands, ok=True, result=True)
response: bool = await bot.delete_my_commands() response: bool = await bot.delete_my_commands()
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -7,5 +7,5 @@ class TestDeleteStickerFromSet:
prepare_result = bot.add_result_for(DeleteStickerFromSet, ok=True, result=True) prepare_result = bot.add_result_for(DeleteStickerFromSet, ok=True, result=True)
response: bool = await bot.delete_sticker_from_set(sticker="sticker id") response: bool = await bot.delete_sticker_from_set(sticker="sticker id")
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -7,5 +7,5 @@ class TestDeleteStickerSet:
prepare_result = bot.add_result_for(DeleteStickerSet, ok=True, result=True) prepare_result = bot.add_result_for(DeleteStickerSet, ok=True, result=True)
response: bool = await bot.delete_sticker_set(name="test") response: bool = await bot.delete_sticker_set(name="test")
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -9,5 +9,5 @@ class TestDeleteStory:
response: bool = await bot.delete_story( response: bool = await bot.delete_story(
business_connection_id="test_connection_id", story_id=42 business_connection_id="test_connection_id", story_id=42
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -7,5 +7,5 @@ class TestDeleteWebhook:
prepare_result = bot.add_result_for(DeleteWebhook, ok=True, result=True) prepare_result = bot.add_result_for(DeleteWebhook, ok=True, result=True)
response: bool = await bot.delete_webhook() response: bool = await bot.delete_webhook()
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -20,5 +20,5 @@ class TestEditChatInviteLink:
response: ChatInviteLink = await bot.edit_chat_invite_link( response: ChatInviteLink = await bot.edit_chat_invite_link(
chat_id=-42, invite_link="https://t.me/username", member_limit=1 chat_id=-42, invite_link="https://t.me/username", member_limit=1
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -22,5 +22,5 @@ class TestEditChatSubscriptionInviteLink:
invite_link="https://t.me/username/test", invite_link="https://t.me/username/test",
name="test", name="test",
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -12,5 +12,5 @@ class TestEditForumTopic:
name="test", name="test",
icon_custom_emoji_id="0", icon_custom_emoji_id="0",
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -7,5 +7,5 @@ class TestCloseGeneralForumTopic:
prepare_result = bot.add_result_for(EditGeneralForumTopic, ok=True, result=True) prepare_result = bot.add_result_for(EditGeneralForumTopic, ok=True, result=True)
response: bool = await bot.edit_general_forum_topic(chat_id=42, name="Test") response: bool = await bot.edit_general_forum_topic(chat_id=42, name="Test")
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -1,5 +1,4 @@
import datetime import datetime
from typing import Union
from aiogram.methods import EditMessageCaption from aiogram.methods import EditMessageCaption
from aiogram.types import Chat, Message from aiogram.types import Chat, Message
@ -19,6 +18,6 @@ class TestEditMessageCaption:
), ),
) )
response: Union[Message, bool] = await bot.edit_message_caption() response: Message | bool = await bot.edit_message_caption()
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -31,5 +31,5 @@ class TestEditMessageChecklist:
message_id=42, message_id=42,
checklist=checklist, checklist=checklist,
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -1,5 +1,3 @@
from typing import Union
from aiogram.methods import EditMessageLiveLocation from aiogram.methods import EditMessageLiveLocation
from aiogram.types import Message from aiogram.types import Message
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
@ -9,8 +7,8 @@ class TestEditMessageLiveLocation:
async def test_bot_method(self, bot: MockedBot): async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(EditMessageLiveLocation, ok=True, result=True) prepare_result = bot.add_result_for(EditMessageLiveLocation, ok=True, result=True)
response: Union[Message, bool] = await bot.edit_message_live_location( response: Message | bool = await bot.edit_message_live_location(
latitude=3.141592, longitude=3.141592 latitude=3.141592, longitude=3.141592
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -1,5 +1,3 @@
from typing import Union
from aiogram.methods import EditMessageMedia from aiogram.methods import EditMessageMedia
from aiogram.types import BufferedInputFile, InputMediaPhoto, Message from aiogram.types import BufferedInputFile, InputMediaPhoto, Message
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
@ -9,8 +7,8 @@ class TestEditMessageMedia:
async def test_bot_method(self, bot: MockedBot): async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(EditMessageMedia, ok=True, result=True) prepare_result = bot.add_result_for(EditMessageMedia, ok=True, result=True)
response: Union[Message, bool] = await bot.edit_message_media( response: Message | bool = await bot.edit_message_media(
media=InputMediaPhoto(media=BufferedInputFile(b"", "photo.png")) media=InputMediaPhoto(media=BufferedInputFile(b"", "photo.png"))
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -1,5 +1,3 @@
from typing import Union
from aiogram.methods import EditMessageReplyMarkup from aiogram.methods import EditMessageReplyMarkup
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
@ -9,7 +7,7 @@ class TestEditMessageReplyMarkup:
async def test_bot_method(self, bot: MockedBot): async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(EditMessageReplyMarkup, ok=True, result=True) prepare_result = bot.add_result_for(EditMessageReplyMarkup, ok=True, result=True)
response: Union[Message, bool] = await bot.edit_message_reply_markup( response: Message | bool = await bot.edit_message_reply_markup(
chat_id=42, chat_id=42,
inline_message_id="inline message id", inline_message_id="inline message id",
reply_markup=InlineKeyboardMarkup( reply_markup=InlineKeyboardMarkup(
@ -18,5 +16,5 @@ class TestEditMessageReplyMarkup:
] ]
), ),
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -1,5 +1,3 @@
from typing import Union
from aiogram.methods import EditMessageText from aiogram.methods import EditMessageText
from aiogram.types import Message from aiogram.types import Message
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
@ -9,8 +7,8 @@ class TestEditMessageText:
async def test_bot_method(self, bot: MockedBot): async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(EditMessageText, ok=True, result=True) prepare_result = bot.add_result_for(EditMessageText, ok=True, result=True)
response: Union[Message, bool] = await bot.edit_message_text( response: Message | bool = await bot.edit_message_text(
chat_id=42, inline_message_id="inline message id", text="text" chat_id=42, inline_message_id="inline message id", text="text"
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -1,5 +1,3 @@
import datetime
from aiogram.methods import EditStory from aiogram.methods import EditStory
from aiogram.types import Chat, InputStoryContentPhoto, Story from aiogram.types import Chat, InputStoryContentPhoto, Story
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
@ -22,5 +20,5 @@ class TestEditStory:
content=InputStoryContentPhoto(type="photo", photo="test_photo"), content=InputStoryContentPhoto(type="photo", photo="test_photo"),
caption="Test caption", caption="Test caption",
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -11,5 +11,5 @@ class TestEditUserStarSubscription:
telegram_payment_charge_id="telegram_payment_charge_id", telegram_payment_charge_id="telegram_payment_charge_id",
is_canceled=False, is_canceled=False,
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -9,5 +9,5 @@ class TestExportChatInviteLink:
) )
response: str = await bot.export_chat_invite_link(chat_id=42) response: str = await bot.export_chat_invite_link(chat_id=42)
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -28,5 +28,5 @@ class TestGetAvailableGifts:
) )
response: Gifts = await bot.get_available_gifts() response: Gifts = await bot.get_available_gifts()
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -37,5 +37,5 @@ class TestGetBusinessAccountGifts:
business_connection_id="test_connection_id", business_connection_id="test_connection_id",
limit=10, limit=10,
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -17,5 +17,5 @@ class TestGetBusinessAccountStarBalance:
response: StarAmount = await bot.get_business_account_star_balance( response: StarAmount = await bot.get_business_account_star_balance(
business_connection_id="test_connection_id", business_connection_id="test_connection_id",
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -20,5 +20,5 @@ class TestGetBusinessConnection:
response: BusinessConnection = await bot.get_business_connection( response: BusinessConnection = await bot.get_business_connection(
business_connection_id="test" business_connection_id="test"
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -25,5 +25,5 @@ class TestGetChat:
) )
response: ChatFullInfo = await bot.get_chat(chat_id=-42) response: ChatFullInfo = await bot.get_chat(chat_id=-42)
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -1,5 +1,3 @@
from typing import List
from aiogram.methods import GetChatAdministrators from aiogram.methods import GetChatAdministrators
from aiogram.types import ChatMember, ChatMemberOwner, User from aiogram.types import ChatMember, ChatMemberOwner, User
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
@ -16,6 +14,6 @@ class TestGetChatAdministrators:
) )
], ],
) )
response: List[ChatMember] = await bot.get_chat_administrators(chat_id=-42) response: list[ChatMember] = await bot.get_chat_administrators(chat_id=-42)
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -37,5 +37,5 @@ class TestGetChatGifts:
chat_id=42, chat_id=42,
limit=10, limit=10,
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -13,5 +13,5 @@ class TestGetChatMember:
), ),
) )
response = await bot.get_chat_member(chat_id=-42, user_id=42) response = await bot.get_chat_member(chat_id=-42, user_id=42)
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -7,5 +7,5 @@ class TestGetChatMembersCount:
prepare_result = bot.add_result_for(GetChatMemberCount, ok=True, result=42) prepare_result = bot.add_result_for(GetChatMemberCount, ok=True, result=42)
response: int = await bot.get_chat_member_count(chat_id=-42) response: int = await bot.get_chat_member_count(chat_id=-42)
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -8,5 +8,5 @@ class TestGetChatMenuButton:
prepare_result = bot.add_result_for(GetChatMenuButton, ok=True, result=MenuButtonDefault()) prepare_result = bot.add_result_for(GetChatMenuButton, ok=True, result=MenuButtonDefault())
response: MenuButton = await bot.get_chat_menu_button() response: MenuButton = await bot.get_chat_menu_button()
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -1,5 +1,3 @@
from typing import List
from aiogram.methods import GetCustomEmojiStickers from aiogram.methods import GetCustomEmojiStickers
from aiogram.types import Sticker from aiogram.types import Sticker
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
@ -24,8 +22,8 @@ class TestGetCustomEmojiStickers:
], ],
) )
response: List[Sticker] = await bot.get_custom_emoji_stickers( response: list[Sticker] = await bot.get_custom_emoji_stickers(
custom_emoji_ids=["1", "2"], custom_emoji_ids=["1", "2"],
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -10,5 +10,5 @@ class TestGetFile:
) )
response: File = await bot.get_file(file_id="file id") response: File = await bot.get_file(file_id="file id")
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -1,5 +1,3 @@
from typing import List
from aiogram.methods import GetForumTopicIconStickers from aiogram.methods import GetForumTopicIconStickers
from aiogram.types import Sticker from aiogram.types import Sticker
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
@ -9,6 +7,6 @@ class TestGetForumTopicIconStickers:
async def test_bot_method(self, bot: MockedBot): async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(GetForumTopicIconStickers, ok=True, result=[]) prepare_result = bot.add_result_for(GetForumTopicIconStickers, ok=True, result=[])
response: List[Sticker] = await bot.get_forum_topic_icon_stickers() response: list[Sticker] = await bot.get_forum_topic_icon_stickers()
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -1,5 +1,3 @@
from typing import List
from aiogram.methods import GetGameHighScores from aiogram.methods import GetGameHighScores
from aiogram.types import GameHighScore, User from aiogram.types import GameHighScore, User
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
@ -17,6 +15,6 @@ class TestGetGameHighScores:
], ],
) )
response: List[GameHighScore] = await bot.get_game_high_scores(user_id=42) response: list[GameHighScore] = await bot.get_game_high_scores(user_id=42)
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -9,7 +9,7 @@ class TestGetMe:
GetMe, ok=True, result=User(id=42, is_bot=False, first_name="User") GetMe, ok=True, result=User(id=42, is_bot=False, first_name="User")
) )
response: User = await bot.get_me() response: User = await bot.get_me()
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result
async def test_me_property(self, bot: MockedBot): async def test_me_property(self, bot: MockedBot):

View file

@ -1,5 +1,3 @@
from typing import List
from aiogram.methods import GetMyCommands from aiogram.methods import GetMyCommands
from aiogram.types import BotCommand from aiogram.types import BotCommand
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
@ -9,6 +7,6 @@ class TestGetMyCommands:
async def test_bot_method(self, bot: MockedBot): async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(GetMyCommands, ok=True, result=None) prepare_result = bot.add_result_for(GetMyCommands, ok=True, result=None)
response: List[BotCommand] = await bot.get_my_commands() response: list[BotCommand] = await bot.get_my_commands()
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -24,5 +24,5 @@ class TestGetMyDefaultAdministratorRights:
) )
response: ChatAdministratorRights = await bot.get_my_default_administrator_rights() response: ChatAdministratorRights = await bot.get_my_default_administrator_rights()
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -10,5 +10,5 @@ class TestGetMyDescription:
) )
response: BotDescription = await bot.get_my_description() response: BotDescription = await bot.get_my_description()
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -10,5 +10,5 @@ class TestGetMyShortDescription:
) )
response: BotShortDescription = await bot.get_my_short_description() response: BotShortDescription = await bot.get_my_short_description()
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -14,5 +14,5 @@ class TestGetMyStarBalance:
) )
response: StarAmount = await bot.get_my_star_balance() response: StarAmount = await bot.get_my_star_balance()
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -3,7 +3,6 @@ from datetime import datetime
from aiogram.enums import TransactionPartnerUserTransactionTypeEnum from aiogram.enums import TransactionPartnerUserTransactionTypeEnum
from aiogram.methods import GetStarTransactions from aiogram.methods import GetStarTransactions
from aiogram.types import ( from aiogram.types import (
File,
StarTransaction, StarTransaction,
StarTransactions, StarTransactions,
TransactionPartnerUser, TransactionPartnerUser,
@ -45,5 +44,5 @@ class TestGetStarTransactions:
) )
response: StarTransactions = await bot.get_star_transactions(limit=10, offset=0) response: StarTransactions = await bot.get_star_transactions(limit=10, offset=0)
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -29,5 +29,5 @@ class TestGetStickerSet:
) )
response: StickerSet = await bot.get_sticker_set(name="test") response: StickerSet = await bot.get_sticker_set(name="test")
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -1,5 +1,3 @@
from typing import List
from aiogram.methods import GetUpdates from aiogram.methods import GetUpdates
from aiogram.types import Update from aiogram.types import Update
from tests.mocked_bot import MockedBot from tests.mocked_bot import MockedBot
@ -9,6 +7,6 @@ class TestGetUpdates:
async def test_bot_method(self, bot: MockedBot): async def test_bot_method(self, bot: MockedBot):
prepare_result = bot.add_result_for(GetUpdates, ok=True, result=[Update(update_id=42)]) prepare_result = bot.add_result_for(GetUpdates, ok=True, result=[Update(update_id=42)])
response: List[Update] = await bot.get_updates() response: list[Update] = await bot.get_updates()
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

View file

@ -1,5 +1,4 @@
import datetime import datetime
from typing import Optional
import pytest import pytest
@ -31,9 +30,9 @@ class TestGetMessageUrl:
bot: MockedBot, bot: MockedBot,
chat_type: str, chat_type: str,
chat_id: int, chat_id: int,
chat_username: Optional[str], chat_username: str | None,
force_private: bool, force_private: bool,
expected_result: Optional[str], expected_result: str | None,
): ):
fake_chat = Chat(id=chat_id, username=chat_username, type=chat_type) fake_chat = Chat(id=chat_id, username=chat_username, type=chat_type)
fake_message_id = 10 fake_message_id = 10
@ -80,11 +79,11 @@ class TestGetMessageUrl:
def test_get_url_if_topic_message( def test_get_url_if_topic_message(
self, self,
bot: MockedBot, bot: MockedBot,
chat_username: Optional[str], chat_username: str | None,
force_private: bool, force_private: bool,
include_thread_id: bool, include_thread_id: bool,
fake_thread_id_topic: Optional[int], fake_thread_id_topic: int | None,
expected_result: Optional[str], expected_result: str | None,
): ):
fake_message_id = 10 fake_message_id = 10
fake_chat_id = -1001234567890 fake_chat_id = -1001234567890

View file

@ -37,5 +37,5 @@ class TestGetUserGifts:
user_id=42, user_id=42,
limit=10, limit=10,
) )
request = bot.get_request() bot.get_request()
assert response == prepare_result.result assert response == prepare_result.result

Some files were not shown because too many files have changed in this diff Show more