From 879168f938e1e7ed51f73cc156dc8749b8bacf66 Mon Sep 17 00:00:00 2001 From: zemf4you Date: Mon, 20 May 2024 16:31:44 +0700 Subject: [PATCH] fix(types): improve type annotations and fix serialization issues (dev-3.x) - Enhanced type annotations in `base.py`, including the return type of `json_serialize` method. - Fixed issue with non-TelegramObject serialization in `json_serialize`. - Reorganized imports in `bot.py` for better readability. - Added `Annotated` import from `typing_extensions` in `custom.py` and removed redundant `Annotated` import from `typing`. - Added type hints and error handling in `input_file` module to prevent bot attribute issues. - Adjusted formatting for better readability and consistency in `form.py`. --- aiogram/client/bot.py | 7 ++++--- aiogram/client/form.py | 7 +++++-- aiogram/types/base.py | 8 +++++--- aiogram/types/custom.py | 3 ++- aiogram/types/input_file.py | 6 ++++-- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/aiogram/client/bot.py b/aiogram/client/bot.py index 1c6de27c..ab25a549 100644 --- a/aiogram/client/bot.py +++ b/aiogram/client/bot.py @@ -20,9 +20,7 @@ from typing import ( import aiofiles from aiogram.utils.token import extract_bot_id, validate_token -from .default import Default, DefaultBotProperties -from .session.aiohttp import AiohttpSession -from .session.base import BaseSession + from ..methods import ( AddStickerToSet, AnswerCallbackQuery, @@ -235,6 +233,9 @@ from ..types import ( UserProfilePhotos, WebhookInfo, ) +from .default import Default, DefaultBotProperties +from .session.aiohttp import AiohttpSession +from .session.base import BaseSession T = TypeVar("T") diff --git a/aiogram/client/form.py b/aiogram/client/form.py index fb6511df..0e2750da 100644 --- a/aiogram/client/form.py +++ b/aiogram/client/form.py @@ -30,7 +30,10 @@ def _extract_files(value: Any) -> Tuple[Any, Dict[str, InputFile]]: return value, files -def extract_files(model: M, files: Dict[str, InputFile] = None) -> Tuple[M, Dict[str, InputFile]]: +def extract_files( + model: M, + files: Optional[Dict[str, InputFile]] = None, +) -> Tuple[M, Dict[str, InputFile]]: if files is None: files = {} update = {} @@ -53,7 +56,7 @@ def extract_files(model: M, files: Dict[str, InputFile] = None) -> Tuple[M, Dict return modified_model, files -def form_serialize(value: Any) -> Optional[str]: +def form_serialize(value: Any) -> str: """ Prepare jsonable value to send """ diff --git a/aiogram/types/base.py b/aiogram/types/base.py index e251cfa0..6756e3a1 100644 --- a/aiogram/types/base.py +++ b/aiogram/types/base.py @@ -1,4 +1,4 @@ -from typing import Any, Dict +from typing import Any, Dict, Union from unittest.mock import sentinel from pydantic import ( @@ -40,7 +40,9 @@ class TelegramObject(BotContextController, BaseModel): return {k: v for k, v in values.items() if not isinstance(v, UNSET_TYPE)} @model_serializer(mode="wrap", when_used="json") - def json_serialize(self, serializer: SerializerFunctionWrapHandler): + def json_serialize( + self, serializer: SerializerFunctionWrapHandler + ) -> Union[Dict[str, Any], Any]: """ Replacing `Default` placeholders with actual values from bot defaults. Ensures JSON serialization backward compatibility by handling non-standard objects. @@ -51,7 +53,7 @@ class TelegramObject(BotContextController, BaseModel): key: properties[value.name] for key, value in self if isinstance(value, Default) } return serializer(self.model_copy(update=default_fields)) - return serializer(self) + return serializer(self) # FIXME: why non-TelegramObject passed there? class MutableTelegramObject(TelegramObject): diff --git a/aiogram/types/custom.py b/aiogram/types/custom.py index 0fc6ecc8..252bdf75 100644 --- a/aiogram/types/custom.py +++ b/aiogram/types/custom.py @@ -1,7 +1,8 @@ from datetime import datetime, timedelta -from typing import Annotated, Union +from typing import Union from pydantic import PlainSerializer +from typing_extensions import Annotated # Make datetime compatible with Telegram Bot API (unixtime) diff --git a/aiogram/types/input_file.py b/aiogram/types/input_file.py index 692b0fd9..1fefb80e 100644 --- a/aiogram/types/input_file.py +++ b/aiogram/types/input_file.py @@ -116,8 +116,8 @@ class FSInputFile(InputFile): chunk_size=chunk_size, ) - @model_validator(mode="after") - def filename_from_path(self): + @model_validator(mode="after") # type: ignore + def filename_from_path(self) -> None: self.filename = self.filename or Path(self.path).name async def read(self, bot: "Bot") -> AsyncGenerator[bytes, None]: @@ -162,6 +162,8 @@ class URLInputFile(BotContextController, InputFile): async def read(self, bot: Optional["Bot"] = None) -> AsyncGenerator[bytes, None]: bot = self.bot or bot # FIXME: invalid order suspected + if bot is None: + raise AttributeError("There is no default bot. Specify it through param") stream = bot.session.stream_content( url=self.url, headers=self.headers,