diff --git a/aiogram/client/session/base.py b/aiogram/client/session/base.py index b4c7ce70..9342cbcc 100644 --- a/aiogram/client/session/base.py +++ b/aiogram/client/session/base.py @@ -89,9 +89,8 @@ class BaseSession(abc.ABC): raise ClientDecodeError("Failed to decode object", e, content) try: - response = Response[method.__returning__].model_validate( - json_data, context={"bot": bot} - ) + response_type = Response[method.__returning__] # type: ignore + response = response_type.model_validate(json_data, context={"bot": bot}) except ValidationError as e: raise ClientDecodeError("Failed to deserialize object", e, json_data) diff --git a/aiogram/methods/base.py b/aiogram/methods/base.py index 2fefa209..221ad9c0 100644 --- a/aiogram/methods/base.py +++ b/aiogram/methods/base.py @@ -1,7 +1,16 @@ from __future__ import annotations from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Any, Dict, Generator, Generic, Optional, TypeVar +from typing import ( + TYPE_CHECKING, + Any, + ClassVar, + Dict, + Generator, + Generic, + Optional, + TypeVar, +) from pydantic import BaseModel, ConfigDict from pydantic.functional_validators import model_validator @@ -54,15 +63,20 @@ class TelegramMethod(BotContextController, BaseModel, Generic[TelegramType], ABC """ return {k: v for k, v in values.items() if not isinstance(v, UNSET_TYPE)} - @property - @abstractmethod - def __returning__(self) -> type: - pass + if TYPE_CHECKING: + __returning__: ClassVar[type] + __api_method__: ClassVar[str] + else: - @property - @abstractmethod - def __api_method__(self) -> str: - pass + @property + @abstractmethod + def __returning__(self) -> type: + pass + + @property + @abstractmethod + def __api_method__(self) -> str: + pass async def emit(self, bot: Bot) -> TelegramType: return await bot(self) diff --git a/aiogram/types/input_file.py b/aiogram/types/input_file.py index db55017a..ed0a2433 100644 --- a/aiogram/types/input_file.py +++ b/aiogram/types/input_file.py @@ -121,11 +121,11 @@ class URLInputFile(InputFile): def __init__( self, url: str, + bot: "Bot", headers: Optional[Dict[str, Any]] = None, filename: Optional[str] = None, chunk_size: int = DEFAULT_CHUNK_SIZE, timeout: int = 30, - bot: "Bot" = None, ): """ Represents object for streaming files from internet @@ -148,13 +148,7 @@ class URLInputFile(InputFile): self.bot = bot async def read(self, chunk_size: int) -> AsyncGenerator[bytes, None]: - bot = self.bot - if bot is None: - from aiogram.client.bot import Bot - - bot = Bot.get_current(no_error=False) - - stream = bot.session.stream_content( + stream = self.bot.session.stream_content( url=self.url, headers=self.headers, timeout=self.timeout, diff --git a/tests/test_api/test_types/test_input_file.py b/tests/test_api/test_types/test_input_file.py index 05391a8e..81e80ad5 100644 --- a/tests/test_api/test_types/test_input_file.py +++ b/tests/test_api/test_types/test_input_file.py @@ -4,6 +4,7 @@ from aresponses import ResponsesMockServer from aiogram import Bot from aiogram.types import BufferedInputFile, FSInputFile, InputFile, URLInputFile +from tests.mocked_bot import MockedBot class TestInputFile: @@ -72,10 +73,8 @@ class TestInputFile: aresponses.add( aresponses.ANY, aresponses.ANY, "get", aresponses.Response(status=200, body=b"\f" * 10) ) - - Bot.set_current(Bot("42:TEST")) - - file = URLInputFile("https://test.org/", chunk_size=1) + bot = Bot(token="42:TEST") + file = URLInputFile("https://test.org/", bot, chunk_size=1) size = 0 async for chunk in file: