mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
Bump dev dependencies (#1512)
* Bump dev dependencies * Pre-commit py3.8 support * Pre-commit py3.8 support (v3.5+) * Mute mypy python version bug
This commit is contained in:
parent
0df95a0276
commit
7760ab1d0d
20 changed files with 92 additions and 75 deletions
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
|
|
@ -67,7 +67,7 @@ jobs:
|
||||||
|
|
||||||
- name: Lint code
|
- name: Lint code
|
||||||
run: |
|
run: |
|
||||||
ruff --output-format=github aiogram examples
|
ruff check --output-format=github aiogram examples
|
||||||
mypy aiogram
|
mypy aiogram
|
||||||
black --check --diff aiogram tests
|
black --check --diff aiogram tests
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.2.0
|
rev: v4.6.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: "trailing-whitespace"
|
- id: "trailing-whitespace"
|
||||||
- id: "check-case-conflict"
|
- id: "check-case-conflict"
|
||||||
|
|
@ -14,13 +14,12 @@ repos:
|
||||||
- id: "check-json"
|
- id: "check-json"
|
||||||
|
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black
|
||||||
rev: 22.10.0
|
rev: 24.4.2
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
files: &files '^(aiogram|tests|examples)'
|
files: &files '^(aiogram|tests|examples)'
|
||||||
|
|
||||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: 'v0.0.215'
|
rev: 'v0.4.9'
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
args: [ "--force-exclude" ]
|
|
||||||
|
|
|
||||||
7
Makefile
7
Makefile
|
|
@ -26,6 +26,11 @@ clean:
|
||||||
rm -f .coverage
|
rm -f .coverage
|
||||||
rm -rf {build,dist,site,.cache,.mypy_cache,.ruff_cache,reports}
|
rm -rf {build,dist,site,.cache,.mypy_cache,.ruff_cache,reports}
|
||||||
|
|
||||||
|
.PHONY: install
|
||||||
|
install: clean
|
||||||
|
pip install -e ."[dev,test,docs]" -U --upgrade-strategy=eager
|
||||||
|
pre-commit install
|
||||||
|
|
||||||
# =================================================================================================
|
# =================================================================================================
|
||||||
# Code quality
|
# Code quality
|
||||||
# =================================================================================================
|
# =================================================================================================
|
||||||
|
|
@ -34,7 +39,7 @@ clean:
|
||||||
lint:
|
lint:
|
||||||
isort --check-only $(code_dir)
|
isort --check-only $(code_dir)
|
||||||
black --check --diff $(code_dir)
|
black --check --diff $(code_dir)
|
||||||
ruff $(package_dir)
|
ruff check $(package_dir) $(examples_dir)
|
||||||
mypy $(package_dir)
|
mypy $(package_dir)
|
||||||
|
|
||||||
.PHONY: reformat
|
.PHONY: reformat
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,10 @@ class RequestMiddlewareManager(Sequence[RequestMiddlewareType]):
|
||||||
def __call__(
|
def __call__(
|
||||||
self,
|
self,
|
||||||
middleware: Optional[RequestMiddlewareType] = None,
|
middleware: Optional[RequestMiddlewareType] = None,
|
||||||
) -> Union[Callable[[RequestMiddlewareType], RequestMiddlewareType], RequestMiddlewareType,]:
|
) -> Union[
|
||||||
|
Callable[[RequestMiddlewareType], RequestMiddlewareType],
|
||||||
|
RequestMiddlewareType,
|
||||||
|
]:
|
||||||
if middleware is None:
|
if middleware is None:
|
||||||
return self.register
|
return self.register
|
||||||
return self.register(middleware)
|
return self.register(middleware)
|
||||||
|
|
|
||||||
|
|
@ -61,5 +61,5 @@ class MiddlewareManager(Sequence[MiddlewareType[TelegramObject]]):
|
||||||
|
|
||||||
middleware = handler_wrapper
|
middleware = handler_wrapper
|
||||||
for m in reversed(middlewares):
|
for m in reversed(middlewares):
|
||||||
middleware = functools.partial(m, middleware)
|
middleware = functools.partial(m, middleware) # type: ignore[assignment]
|
||||||
return middleware
|
return middleware
|
||||||
|
|
|
||||||
|
|
@ -57,17 +57,19 @@ class UserContextMiddleware(BaseMiddleware):
|
||||||
return EventContext(
|
return EventContext(
|
||||||
chat=event.message.chat,
|
chat=event.message.chat,
|
||||||
user=event.message.from_user,
|
user=event.message.from_user,
|
||||||
thread_id=event.message.message_thread_id
|
thread_id=(
|
||||||
if event.message.is_topic_message
|
event.message.message_thread_id if event.message.is_topic_message else None
|
||||||
else None,
|
),
|
||||||
)
|
)
|
||||||
if event.edited_message:
|
if event.edited_message:
|
||||||
return EventContext(
|
return EventContext(
|
||||||
chat=event.edited_message.chat,
|
chat=event.edited_message.chat,
|
||||||
user=event.edited_message.from_user,
|
user=event.edited_message.from_user,
|
||||||
thread_id=event.edited_message.message_thread_id
|
thread_id=(
|
||||||
if event.edited_message.is_topic_message
|
event.edited_message.message_thread_id
|
||||||
else None,
|
if event.edited_message.is_topic_message
|
||||||
|
else None
|
||||||
|
),
|
||||||
)
|
)
|
||||||
if event.channel_post:
|
if event.channel_post:
|
||||||
return EventContext(chat=event.channel_post.chat)
|
return EventContext(chat=event.channel_post.chat)
|
||||||
|
|
@ -82,10 +84,12 @@ class UserContextMiddleware(BaseMiddleware):
|
||||||
return EventContext(
|
return EventContext(
|
||||||
chat=event.callback_query.message.chat,
|
chat=event.callback_query.message.chat,
|
||||||
user=event.callback_query.from_user,
|
user=event.callback_query.from_user,
|
||||||
thread_id=event.callback_query.message.message_thread_id
|
thread_id=(
|
||||||
if not isinstance(event.callback_query.message, InaccessibleMessage)
|
event.callback_query.message.message_thread_id
|
||||||
and event.callback_query.message.is_topic_message
|
if not isinstance(event.callback_query.message, InaccessibleMessage)
|
||||||
else None,
|
and event.callback_query.message.is_topic_message
|
||||||
|
else None
|
||||||
|
),
|
||||||
)
|
)
|
||||||
return EventContext(user=event.callback_query.from_user)
|
return EventContext(user=event.callback_query.from_user)
|
||||||
if event.shipping_query:
|
if event.shipping_query:
|
||||||
|
|
@ -132,18 +136,22 @@ class UserContextMiddleware(BaseMiddleware):
|
||||||
return EventContext(
|
return EventContext(
|
||||||
chat=event.business_message.chat,
|
chat=event.business_message.chat,
|
||||||
user=event.business_message.from_user,
|
user=event.business_message.from_user,
|
||||||
thread_id=event.business_message.message_thread_id
|
thread_id=(
|
||||||
if event.business_message.is_topic_message
|
event.business_message.message_thread_id
|
||||||
else None,
|
if event.business_message.is_topic_message
|
||||||
|
else None
|
||||||
|
),
|
||||||
business_connection_id=event.business_message.business_connection_id,
|
business_connection_id=event.business_message.business_connection_id,
|
||||||
)
|
)
|
||||||
if event.edited_business_message:
|
if event.edited_business_message:
|
||||||
return EventContext(
|
return EventContext(
|
||||||
chat=event.edited_business_message.chat,
|
chat=event.edited_business_message.chat,
|
||||||
user=event.edited_business_message.from_user,
|
user=event.edited_business_message.from_user,
|
||||||
thread_id=event.edited_business_message.message_thread_id
|
thread_id=(
|
||||||
if event.edited_business_message.is_topic_message
|
event.edited_business_message.message_thread_id
|
||||||
else None,
|
if event.edited_business_message.is_topic_message
|
||||||
|
else None
|
||||||
|
),
|
||||||
business_connection_id=event.edited_business_message.business_connection_id,
|
business_connection_id=event.edited_business_message.business_connection_id,
|
||||||
)
|
)
|
||||||
return EventContext()
|
return EventContext()
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ from __future__ import annotations
|
||||||
import re
|
import re
|
||||||
from dataclasses import dataclass, field, replace
|
from dataclasses import dataclass, field, replace
|
||||||
from typing import (
|
from typing import (
|
||||||
TYPE_CHECKING,
|
|
||||||
Any,
|
Any,
|
||||||
Dict,
|
Dict,
|
||||||
Iterable,
|
Iterable,
|
||||||
|
|
@ -11,6 +10,7 @@ from typing import (
|
||||||
Optional,
|
Optional,
|
||||||
Pattern,
|
Pattern,
|
||||||
Sequence,
|
Sequence,
|
||||||
|
TYPE_CHECKING,
|
||||||
Union,
|
Union,
|
||||||
cast,
|
cast,
|
||||||
)
|
)
|
||||||
|
|
@ -24,7 +24,8 @@ from aiogram.utils.deep_linking import decode_payload
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from aiogram import Bot
|
from aiogram import Bot
|
||||||
|
|
||||||
CommandPatternType = Union[str, re.Pattern, BotCommand]
|
# TODO: rm type ignore after py3.8 support expiration or mypy bug fix
|
||||||
|
CommandPatternType = Union[str, re.Pattern, BotCommand] # type: ignore[type-arg]
|
||||||
|
|
||||||
|
|
||||||
class CommandException(Exception):
|
class CommandException(Exception):
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ class BotCommandScopeAllChatAdministrators(BotCommandScope):
|
||||||
Source: https://core.telegram.org/bots/api#botcommandscopeallchatadministrators
|
Source: https://core.telegram.org/bots/api#botcommandscopeallchatadministrators
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type: Literal[
|
type: Literal[BotCommandScopeType.ALL_CHAT_ADMINISTRATORS] = (
|
||||||
BotCommandScopeType.ALL_CHAT_ADMINISTRATORS
|
BotCommandScopeType.ALL_CHAT_ADMINISTRATORS
|
||||||
] = BotCommandScopeType.ALL_CHAT_ADMINISTRATORS
|
)
|
||||||
"""Scope type, must be *all_chat_administrators*"""
|
"""Scope type, must be *all_chat_administrators*"""
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ class BotCommandScopeChatAdministrators(BotCommandScope):
|
||||||
Source: https://core.telegram.org/bots/api#botcommandscopechatadministrators
|
Source: https://core.telegram.org/bots/api#botcommandscopechatadministrators
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type: Literal[
|
type: Literal[BotCommandScopeType.CHAT_ADMINISTRATORS] = (
|
||||||
BotCommandScopeType.CHAT_ADMINISTRATORS
|
BotCommandScopeType.CHAT_ADMINISTRATORS
|
||||||
] = BotCommandScopeType.CHAT_ADMINISTRATORS
|
)
|
||||||
"""Scope type, must be *chat_administrators*"""
|
"""Scope type, must be *chat_administrators*"""
|
||||||
chat_id: Union[int, str]
|
chat_id: Union[int, str]
|
||||||
"""Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)"""
|
"""Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)"""
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ class PassportElementErrorTranslationFile(PassportElementError):
|
||||||
Source: https://core.telegram.org/bots/api#passportelementerrortranslationfile
|
Source: https://core.telegram.org/bots/api#passportelementerrortranslationfile
|
||||||
"""
|
"""
|
||||||
|
|
||||||
source: Literal[
|
source: Literal[PassportElementErrorType.TRANSLATION_FILE] = (
|
||||||
PassportElementErrorType.TRANSLATION_FILE
|
PassportElementErrorType.TRANSLATION_FILE
|
||||||
] = PassportElementErrorType.TRANSLATION_FILE
|
)
|
||||||
"""Error source, must be *translation_file*"""
|
"""Error source, must be *translation_file*"""
|
||||||
type: str
|
type: str
|
||||||
"""Type of element of the user's Telegram Passport which has the issue, one of 'passport', 'driver_license', 'identity_card', 'internal_passport', 'utility_bill', 'bank_statement', 'rental_agreement', 'passport_registration', 'temporary_registration'"""
|
"""Type of element of the user's Telegram Passport which has the issue, one of 'passport', 'driver_license', 'identity_card', 'internal_passport', 'utility_bill', 'bank_statement', 'rental_agreement', 'passport_registration', 'temporary_registration'"""
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ class PassportElementErrorTranslationFiles(PassportElementError):
|
||||||
Source: https://core.telegram.org/bots/api#passportelementerrortranslationfiles
|
Source: https://core.telegram.org/bots/api#passportelementerrortranslationfiles
|
||||||
"""
|
"""
|
||||||
|
|
||||||
source: Literal[
|
source: Literal[PassportElementErrorType.TRANSLATION_FILES] = (
|
||||||
PassportElementErrorType.TRANSLATION_FILES
|
PassportElementErrorType.TRANSLATION_FILES
|
||||||
] = PassportElementErrorType.TRANSLATION_FILES
|
)
|
||||||
"""Error source, must be *translation_files*"""
|
"""Error source, must be *translation_files*"""
|
||||||
type: str
|
type: str
|
||||||
"""Type of element of the user's Telegram Passport which has the issue, one of 'passport', 'driver_license', 'identity_card', 'internal_passport', 'utility_bill', 'bank_statement', 'rental_agreement', 'passport_registration', 'temporary_registration'"""
|
"""Type of element of the user's Telegram Passport which has the issue, one of 'passport', 'driver_license', 'identity_card', 'internal_passport', 'utility_bill', 'bank_statement', 'rental_agreement', 'passport_registration', 'temporary_registration'"""
|
||||||
|
|
|
||||||
|
|
@ -397,8 +397,7 @@ class ReplyKeyboardBuilder(KeyboardBuilder[KeyboardButton]):
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
||||||
def as_markup(self, **kwargs: Any) -> ReplyKeyboardMarkup:
|
def as_markup(self, **kwargs: Any) -> ReplyKeyboardMarkup: ...
|
||||||
...
|
|
||||||
|
|
||||||
def __init__(self, markup: Optional[List[List[KeyboardButton]]] = None) -> None:
|
def __init__(self, markup: Optional[List[List[KeyboardButton]]] = None) -> None:
|
||||||
super().__init__(button_type=KeyboardButton, markup=markup)
|
super().__init__(button_type=KeyboardButton, markup=markup)
|
||||||
|
|
|
||||||
|
|
@ -359,8 +359,10 @@ class MediaGroupBuilder:
|
||||||
update_first_media["parse_mode"] = None
|
update_first_media["parse_mode"] = None
|
||||||
|
|
||||||
return [
|
return [
|
||||||
media.model_copy(update=update_first_media)
|
(
|
||||||
if index == 0 and self.caption is not None
|
media.model_copy(update=update_first_media)
|
||||||
else media
|
if index == 0 and self.caption is not None
|
||||||
|
else media
|
||||||
|
)
|
||||||
for index, media in enumerate(self._media)
|
for index, media in enumerate(self._media)
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ Encoding and decoding with your own methods:
|
||||||
# result: decoded == "foo"
|
# result: decoded == "foo"
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from base64 import urlsafe_b64decode, urlsafe_b64encode
|
from base64 import urlsafe_b64decode, urlsafe_b64encode
|
||||||
from typing import Callable, Optional
|
from typing import Callable, Optional
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ class HelloFilter(Filter):
|
||||||
async def __call__(
|
async def __call__(
|
||||||
self,
|
self,
|
||||||
message: Message,
|
message: Message,
|
||||||
event_from_user: User
|
event_from_user: User,
|
||||||
# Filters also can accept keyword parameters like in handlers
|
# Filters also can accept keyword parameters like in handlers
|
||||||
) -> Union[bool, Dict[str, Any]]:
|
) -> Union[bool, Dict[str, Any]]:
|
||||||
if message.text.casefold() == "hello":
|
if message.text.casefold() == "hello":
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
This example shows how to use webhook on behind of any reverse proxy (nginx, traefik, ingress etc.)
|
This example shows how to use webhook on behind of any reverse proxy (nginx, traefik, ingress etc.)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
from os import getenv
|
from os import getenv
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
This example shows how to use webhook with SSL certificate.
|
This example shows how to use webhook with SSL certificate.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import ssl
|
import ssl
|
||||||
import sys
|
import sys
|
||||||
|
|
|
||||||
|
|
@ -14,5 +14,4 @@ class MyFilter(Filter):
|
||||||
|
|
||||||
|
|
||||||
@router.message(MyFilter("hello"))
|
@router.message(MyFilter("hello"))
|
||||||
async def my_handler(message: Message):
|
async def my_handler(message: Message): ...
|
||||||
...
|
|
||||||
|
|
|
||||||
|
|
@ -101,13 +101,13 @@ docs = [
|
||||||
"sphinxcontrib-towncrier~=0.3.2a0",
|
"sphinxcontrib-towncrier~=0.3.2a0",
|
||||||
]
|
]
|
||||||
dev = [
|
dev = [
|
||||||
"black~=23.10.0",
|
"black~=24.4.2",
|
||||||
"isort~=5.12.0",
|
"isort~=5.13.2",
|
||||||
"ruff~=0.1.1",
|
"ruff~=0.4.9",
|
||||||
"mypy~=1.6.1",
|
"mypy~=1.10.0",
|
||||||
"toml~=0.10.2",
|
"toml~=0.10.2",
|
||||||
"pre-commit~=3.5.0",
|
"pre-commit~=3.5",
|
||||||
"packaging~=23.1",
|
"packaging~=24.1",
|
||||||
"motor-types~=1.0.0b4",
|
"motor-types~=1.0.0b4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -132,10 +132,10 @@ post-install-commands = [
|
||||||
|
|
||||||
[tool.hatch.envs.default.scripts]
|
[tool.hatch.envs.default.scripts]
|
||||||
reformat = [
|
reformat = [
|
||||||
"black aiogram tests",
|
"black aiogram tests examples",
|
||||||
"isort aiogram tests",
|
"isort aiogram tests examples",
|
||||||
]
|
]
|
||||||
lint = "ruff aiogram"
|
lint = "ruff check aiogram tests examples"
|
||||||
|
|
||||||
[tool.hatch.envs.docs]
|
[tool.hatch.envs.docs]
|
||||||
features = [
|
features = [
|
||||||
|
|
@ -202,19 +202,6 @@ python = ["38", "39", "310", "311", "312"]
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
line-length = 99
|
line-length = 99
|
||||||
select = [
|
|
||||||
# "C", # TODO: mccabe - code complecity
|
|
||||||
"C4",
|
|
||||||
"E",
|
|
||||||
"F",
|
|
||||||
"T10",
|
|
||||||
"T20",
|
|
||||||
"Q",
|
|
||||||
"RET",
|
|
||||||
]
|
|
||||||
ignore = [
|
|
||||||
"F401"
|
|
||||||
]
|
|
||||||
src = ["aiogram", "tests"]
|
src = ["aiogram", "tests"]
|
||||||
exclude = [
|
exclude = [
|
||||||
".git",
|
".git",
|
||||||
|
|
@ -230,7 +217,22 @@ exclude = [
|
||||||
]
|
]
|
||||||
target-version = "py310"
|
target-version = "py310"
|
||||||
|
|
||||||
[tool.ruff.isort]
|
[tool.ruff.lint]
|
||||||
|
select = [
|
||||||
|
# "C", # TODO: mccabe - code complecity
|
||||||
|
"C4",
|
||||||
|
"E",
|
||||||
|
"F",
|
||||||
|
"T10",
|
||||||
|
"T20",
|
||||||
|
"Q",
|
||||||
|
"RET",
|
||||||
|
]
|
||||||
|
ignore = [
|
||||||
|
"F401"
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.ruff.lint.isort]
|
||||||
known-first-party = [
|
known-first-party = [
|
||||||
"aiogram",
|
"aiogram",
|
||||||
"finite_state_machine",
|
"finite_state_machine",
|
||||||
|
|
@ -238,7 +240,7 @@ known-first-party = [
|
||||||
"routes",
|
"routes",
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.ruff.per-file-ignores]
|
[tool.ruff.lint.per-file-ignores]
|
||||||
"aiogram/client/bot.py" = ["E501"]
|
"aiogram/client/bot.py" = ["E501"]
|
||||||
"aiogram/types/*" = ["E501"]
|
"aiogram/types/*" = ["E501"]
|
||||||
"aiogram/methods/*" = ["E501"]
|
"aiogram/methods/*" = ["E501"]
|
||||||
|
|
|
||||||
|
|
@ -992,17 +992,13 @@ class TestDispatcher:
|
||||||
pytest.fail("Expected 'Detected slow response into webhook' warning.")
|
pytest.fail("Expected 'Detected slow response into webhook' warning.")
|
||||||
|
|
||||||
def test_specify_updates_calculation(self):
|
def test_specify_updates_calculation(self):
|
||||||
def simple_msg_handler() -> None:
|
def simple_msg_handler() -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
def simple_callback_query_handler() -> None:
|
def simple_callback_query_handler() -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
def simple_poll_handler() -> None:
|
def simple_poll_handler() -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
def simple_edited_msg_handler() -> None:
|
def simple_edited_msg_handler() -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
dispatcher = Dispatcher()
|
dispatcher = Dispatcher()
|
||||||
dispatcher.message.register(simple_msg_handler)
|
dispatcher.message.register(simple_msg_handler)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue