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`.
This commit is contained in:
zemf4you 2024-05-20 16:31:44 +07:00
parent 7cfb82674d
commit 879168f938
5 changed files with 20 additions and 11 deletions

View file

@ -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")

View file

@ -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
"""

View file

@ -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):

View file

@ -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)

View file

@ -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,