Merge branch 'aiogram:dev-3.x' into dev-3.x

This commit is contained in:
m-xim 2025-02-14 01:32:22 +03:00 committed by GitHub
commit b939b4e95d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 27 additions and 14 deletions

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

@ -0,0 +1 @@
Removed redundant :code:`Path` to :code:`str` convertion on file download.

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

@ -0,0 +1 @@
Change the :code:`Downloadable` protocol to be non-writable to shut up type checking that checks code that uses the :code:`bot.download(...)` method

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

@ -0,0 +1 @@
Fix the regex pattern that finds the "bad characters" for deeplink payload.

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

@ -0,0 +1 @@
Increased max :code:`redis` version support from “<5.1.0” to “<5.3.0”

View file

@ -391,7 +391,7 @@ class Bot:
@classmethod
async def __aiofiles_reader(
cls, file: str, chunk_size: int = 65536
cls, file: Union[str, pathlib.Path], chunk_size: int = 65536
) -> AsyncGenerator[bytes, None]:
async with aiofiles.open(file, "rb") as f:
while chunk := await f.read(chunk_size):
@ -399,7 +399,7 @@ class Bot:
async def download_file(
self,
file_path: str,
file_path: Union[str, pathlib.Path],
destination: Optional[Union[BinaryIO, pathlib.Path, str]] = None,
timeout: int = 30,
chunk_size: int = 65536,
@ -423,7 +423,7 @@ class Bot:
close_stream = False
if self.session.api.is_local:
stream = self.__aiofiles_reader(
str(self.session.api.wrap_local_file.to_local(file_path)), chunk_size=chunk_size
self.session.api.wrap_local_file.to_local(file_path), chunk_size=chunk_size
)
close_stream = True
else:

View file

@ -67,7 +67,7 @@ class TelegramAPIServer:
"""
return self.base.format(token=token, method=method)
def file_url(self, token: str, path: str) -> str:
def file_url(self, token: str, path: Union[str, Path]) -> str:
"""
Generate URL for downloading files

View file

@ -2,4 +2,5 @@ from typing import Protocol
class Downloadable(Protocol):
file_id: str
@property
def file_id(self) -> str: ...

View file

@ -18,7 +18,7 @@ from aiogram.utils.payload import decode_payload, encode_payload
if TYPE_CHECKING:
from aiogram import Bot
BAD_PATTERN = re.compile(r"[^A-z0-9-]")
BAD_PATTERN = re.compile(r"[^a-zA-Z0-9-_]")
async def create_start_link(

View file

@ -173,7 +173,7 @@ msgstr ""
#: ../../../README.rst:71
msgid "If you have any questions, you can visit our community chats on Telegram:"
msgstr "Якщо є якість додаткові запитання, ласкаво просимо до онлайн-спільнот:"
msgstr "Якщо є додаткові запитання, ласкаво просимо до онлайн-спільнот:"
#: ../../../README.rst:73
msgid "🇺🇸 `@aiogram <https://t.me/aiogram>`_"

View file

@ -60,7 +60,7 @@ fast = [
"aiodns>=3.0.0",
]
redis = [
"redis[hiredis]>=5.0.1,<5.1.0",
"redis[hiredis]>=5.0.1,<5.3.0",
]
mongo = [
"motor>=3.3.2,<3.7.0",

View file

@ -1,5 +1,7 @@
from pathlib import Path
import pytest
from aiogram.client.telegram import (
PRODUCTION,
BareFilesPathWrapper,
@ -13,15 +15,17 @@ class TestAPIServer:
method_url = PRODUCTION.api_url(token="42:TEST", method="apiMethod")
assert method_url == "https://api.telegram.org/bot42:TEST/apiMethod"
def test_file_url(self):
file_url = PRODUCTION.file_url(token="42:TEST", path="path")
@pytest.mark.parametrize("path", ["path", Path("path")])
def test_file_url(self, path):
file_url = PRODUCTION.file_url(token="42:TEST", path=path)
assert file_url == "https://api.telegram.org/file/bot42:TEST/path"
def test_from_base(self):
@pytest.mark.parametrize("path", ["path", Path("path")])
def test_from_base(self, path):
local_server = TelegramAPIServer.from_base("http://localhost:8081", is_local=True)
method_url = local_server.api_url("42:TEST", method="apiMethod")
file_url = local_server.file_url(token="42:TEST", path="path")
file_url = local_server.file_url(token="42:TEST", path=path)
assert method_url == "http://localhost:8081/bot42:TEST/apiMethod"
assert file_url == "http://localhost:8081/file/bot42:TEST/path"

View file

@ -1,5 +1,6 @@
import io
import os
from pathlib import Path
from tempfile import mkstemp
from unittest.mock import AsyncMock, MagicMock, patch
@ -112,7 +113,8 @@ class TestBot:
mocked_close.assert_not_awaited()
await session.close()
async def test_download_file(self, aresponses: ResponsesMockServer):
@pytest.mark.parametrize("file_path", ["file.png", Path("file.png")])
async def test_download_file(self, aresponses: ResponsesMockServer, file_path):
aresponses.add(
method_pattern="get",
response=aresponses.Response(status=200, body=b"\f" * 10),
@ -127,7 +129,7 @@ class TestBot:
async with Bot("42:TEST").context() as bot:
with patch("aiofiles.threadpool.sync_open", return_value=mock_file):
await bot.download_file("TEST", "file.png")
await bot.download_file("TEST", file_path)
mock_file.write.assert_called_once_with(b"\f" * 10)
async def test_download_file_default_destination(

View file

@ -10,12 +10,14 @@ PAYLOADS = [
"aaBBccDDeeFF5544332211",
-12345678901234567890,
12345678901234567890,
"underscore_and-dash",
]
WRONG_PAYLOADS = [
"@BotFather",
"Some:special$characters#=",
"spaces spaces spaces",
1234567890123456789.0,
"has`backtick",
]