mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2024-12-22 14:35:00 +01:00
Handle Lists and Tuples and Datetimes Directly in TelegramObject.to_dict
(#3353)
This commit is contained in:
parent
e1d56178c8
commit
e54c6a04de
30 changed files with 65 additions and 254 deletions
|
@ -3665,7 +3665,7 @@ class Bot(TelegramObject, AbstractAsyncContextManager):
|
||||||
if inline_message_id:
|
if inline_message_id:
|
||||||
data["inline_message_id"] = inline_message_id
|
data["inline_message_id"] = inline_message_id
|
||||||
if entities:
|
if entities:
|
||||||
data["entities"] = [me.to_dict() for me in entities]
|
data["entities"] = [me.to_dict(recursive=True) for me in entities]
|
||||||
|
|
||||||
return await self._send_message(
|
return await self._send_message(
|
||||||
"editMessageText",
|
"editMessageText",
|
||||||
|
@ -5085,7 +5085,7 @@ class Bot(TelegramObject, AbstractAsyncContextManager):
|
||||||
data: JSONDict = {"shipping_query_id": shipping_query_id, "ok": ok}
|
data: JSONDict = {"shipping_query_id": shipping_query_id, "ok": ok}
|
||||||
|
|
||||||
if shipping_options is not None:
|
if shipping_options is not None:
|
||||||
data["shipping_options"] = [option.to_dict() for option in shipping_options]
|
data["shipping_options"] = [option.to_dict(True) for option in shipping_options]
|
||||||
if error_message is not None:
|
if error_message is not None:
|
||||||
data["error_message"] = error_message
|
data["error_message"] = error_message
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ from typing import TYPE_CHECKING, Optional
|
||||||
|
|
||||||
from telegram._telegramobject import TelegramObject
|
from telegram._telegramobject import TelegramObject
|
||||||
from telegram._user import User
|
from telegram._user import User
|
||||||
from telegram._utils.datetime import from_timestamp, to_timestamp
|
from telegram._utils.datetime import from_timestamp
|
||||||
from telegram._utils.types import JSONDict
|
from telegram._utils.types import JSONDict
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
@ -150,11 +150,3 @@ class ChatInviteLink(TelegramObject):
|
||||||
data["expire_date"] = from_timestamp(data.get("expire_date", None))
|
data["expire_date"] = from_timestamp(data.get("expire_date", None))
|
||||||
|
|
||||||
return super().de_json(data=data, bot=bot)
|
return super().de_json(data=data, bot=bot)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
data["expire_date"] = to_timestamp(self.expire_date)
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ from telegram._chat import Chat
|
||||||
from telegram._chatinvitelink import ChatInviteLink
|
from telegram._chatinvitelink import ChatInviteLink
|
||||||
from telegram._telegramobject import TelegramObject
|
from telegram._telegramobject import TelegramObject
|
||||||
from telegram._user import User
|
from telegram._user import User
|
||||||
from telegram._utils.datetime import from_timestamp, to_timestamp
|
from telegram._utils.datetime import from_timestamp
|
||||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||||
from telegram._utils.types import JSONDict, ODVInput
|
from telegram._utils.types import JSONDict, ODVInput
|
||||||
|
|
||||||
|
@ -103,14 +103,6 @@ class ChatJoinRequest(TelegramObject):
|
||||||
|
|
||||||
return super().de_json(data=data, bot=bot)
|
return super().de_json(data=data, bot=bot)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
data["date"] = to_timestamp(self.date)
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
async def approve(
|
async def approve(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
|
|
@ -23,7 +23,7 @@ from typing import TYPE_CHECKING, ClassVar, Dict, Optional, Type
|
||||||
from telegram import constants
|
from telegram import constants
|
||||||
from telegram._telegramobject import TelegramObject
|
from telegram._telegramobject import TelegramObject
|
||||||
from telegram._user import User
|
from telegram._user import User
|
||||||
from telegram._utils.datetime import from_timestamp, to_timestamp
|
from telegram._utils.datetime import from_timestamp
|
||||||
from telegram._utils.types import JSONDict
|
from telegram._utils.types import JSONDict
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
@ -123,15 +123,6 @@ class ChatMember(TelegramObject):
|
||||||
|
|
||||||
return super().de_json(data=data, bot=bot)
|
return super().de_json(data=data, bot=bot)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
if data.get("until_date", False):
|
|
||||||
data["until_date"] = to_timestamp(data["until_date"])
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
class ChatMemberOwner(ChatMember):
|
class ChatMemberOwner(ChatMember):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -25,7 +25,7 @@ from telegram._chatinvitelink import ChatInviteLink
|
||||||
from telegram._chatmember import ChatMember
|
from telegram._chatmember import ChatMember
|
||||||
from telegram._telegramobject import TelegramObject
|
from telegram._telegramobject import TelegramObject
|
||||||
from telegram._user import User
|
from telegram._user import User
|
||||||
from telegram._utils.datetime import from_timestamp, to_timestamp
|
from telegram._utils.datetime import from_timestamp
|
||||||
from telegram._utils.types import JSONDict
|
from telegram._utils.types import JSONDict
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
@ -122,15 +122,6 @@ class ChatMemberUpdated(TelegramObject):
|
||||||
|
|
||||||
return super().de_json(data=data, bot=bot)
|
return super().de_json(data=data, bot=bot)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
# Required
|
|
||||||
data["date"] = to_timestamp(self.date)
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
def _get_attribute_difference(self, attribute: str) -> Tuple[object, object]:
|
def _get_attribute_difference(self, attribute: str) -> Tuple[object, object]:
|
||||||
try:
|
try:
|
||||||
old = self.old_chat_member[attribute]
|
old = self.old_chat_member[attribute]
|
||||||
|
|
|
@ -90,15 +90,6 @@ class InputMedia(TelegramObject):
|
||||||
self.caption_entities = caption_entities
|
self.caption_entities = caption_entities
|
||||||
self.parse_mode = parse_mode
|
self.parse_mode = parse_mode
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
if self.caption_entities:
|
|
||||||
data["caption_entities"] = [ce.to_dict() for ce in self.caption_entities]
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _parse_thumb_input(thumb: Optional[FileInput]) -> Optional[Union[str, InputFile]]:
|
def _parse_thumb_input(thumb: Optional[FileInput]) -> Optional[Union[str, InputFile]]:
|
||||||
# We use local_mode=True because we don't have access to the actual setting and want
|
# We use local_mode=True because we don't have access to the actual setting and want
|
||||||
|
|
|
@ -282,14 +282,6 @@ class StickerSet(TelegramObject):
|
||||||
|
|
||||||
return super()._de_json(data=data, bot=bot, api_kwargs=api_kwargs)
|
return super()._de_json(data=data, bot=bot, api_kwargs=api_kwargs)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
data["stickers"] = [s.to_dict() for s in data.get("stickers")] # type: ignore[union-attr]
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
class MaskPosition(TelegramObject):
|
class MaskPosition(TelegramObject):
|
||||||
"""This object describes the position on faces where a mask should be placed by default.
|
"""This object describes the position on faces where a mask should be placed by default.
|
||||||
|
|
|
@ -117,16 +117,6 @@ class Game(TelegramObject):
|
||||||
|
|
||||||
return super().de_json(data=data, bot=bot)
|
return super().de_json(data=data, bot=bot)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
data["photo"] = [p.to_dict() for p in self.photo]
|
|
||||||
if self.text_entities:
|
|
||||||
data["text_entities"] = [x.to_dict() for x in self.text_entities]
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
def parse_text_entity(self, entity: MessageEntity) -> str:
|
def parse_text_entity(self, entity: MessageEntity) -> str:
|
||||||
"""Returns the text from a given :class:`telegram.MessageEntity`.
|
"""Returns the text from a given :class:`telegram.MessageEntity`.
|
||||||
|
|
||||||
|
|
|
@ -68,16 +68,6 @@ class InlineKeyboardMarkup(TelegramObject):
|
||||||
|
|
||||||
self._id_attrs = (self.inline_keyboard,)
|
self._id_attrs = (self.inline_keyboard,)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
data["inline_keyboard"] = []
|
|
||||||
for inline_keyboard in self.inline_keyboard:
|
|
||||||
data["inline_keyboard"].append([x.to_dict() for x in inline_keyboard])
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["InlineKeyboardMarkup"]:
|
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["InlineKeyboardMarkup"]:
|
||||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||||
|
|
|
@ -53,18 +53,3 @@ class InlineQueryResult(TelegramObject):
|
||||||
self.id = str(id) # pylint: disable=invalid-name
|
self.id = str(id) # pylint: disable=invalid-name
|
||||||
|
|
||||||
self._id_attrs = (self.id,)
|
self._id_attrs = (self.id,)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
# pylint: disable=no-member
|
|
||||||
if (
|
|
||||||
hasattr(self, "caption_entities")
|
|
||||||
and self.caption_entities # type: ignore[attr-defined]
|
|
||||||
):
|
|
||||||
data["caption_entities"] = [
|
|
||||||
ce.to_dict() for ce in self.caption_entities # type: ignore[attr-defined]
|
|
||||||
]
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
|
@ -228,14 +228,6 @@ class InputInvoiceMessageContent(InputMessageContent):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
data["prices"] = [price.to_dict() for price in self.prices]
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def de_json(
|
def de_json(
|
||||||
cls, data: Optional[JSONDict], bot: "Bot"
|
cls, data: Optional[JSONDict], bot: "Bot"
|
||||||
|
|
|
@ -83,12 +83,3 @@ class InputTextMessageContent(InputMessageContent):
|
||||||
self.disable_web_page_preview = disable_web_page_preview
|
self.disable_web_page_preview = disable_web_page_preview
|
||||||
|
|
||||||
self._id_attrs = (self.message_text,)
|
self._id_attrs = (self.message_text,)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
if self.entities:
|
|
||||||
data["entities"] = [ce.to_dict() for ce in self.entities]
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
|
@ -161,12 +161,6 @@ class MenuButtonWebApp(MenuButton):
|
||||||
|
|
||||||
return super().de_json(data=data, bot=bot) # type: ignore[return-value]
|
return super().de_json(data=data, bot=bot) # type: ignore[return-value]
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
data["web_app"] = self.web_app.to_dict()
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
class MenuButtonDefault(MenuButton):
|
class MenuButtonDefault(MenuButton):
|
||||||
"""Describes that no specific value for the menu button was set.
|
"""Describes that no specific value for the menu button was set.
|
||||||
|
|
|
@ -47,7 +47,7 @@ from telegram._poll import Poll
|
||||||
from telegram._proximityalerttriggered import ProximityAlertTriggered
|
from telegram._proximityalerttriggered import ProximityAlertTriggered
|
||||||
from telegram._telegramobject import TelegramObject
|
from telegram._telegramobject import TelegramObject
|
||||||
from telegram._user import User
|
from telegram._user import User
|
||||||
from telegram._utils.datetime import from_timestamp, to_timestamp
|
from telegram._utils.datetime import from_timestamp
|
||||||
from telegram._utils.defaultvalue import DEFAULT_NONE, DefaultValue
|
from telegram._utils.defaultvalue import DEFAULT_NONE, DefaultValue
|
||||||
from telegram._utils.types import DVInput, FileInput, JSONDict, ODVInput, ReplyMarkup
|
from telegram._utils.types import DVInput, FileInput, JSONDict, ODVInput, ReplyMarkup
|
||||||
from telegram._videochat import (
|
from telegram._videochat import (
|
||||||
|
@ -719,30 +719,6 @@ class Message(TelegramObject):
|
||||||
|
|
||||||
return self._effective_attachment # type: ignore[return-value]
|
return self._effective_attachment # type: ignore[return-value]
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
# Required
|
|
||||||
data["date"] = to_timestamp(self.date)
|
|
||||||
# Optionals
|
|
||||||
if self.forward_date:
|
|
||||||
data["forward_date"] = to_timestamp(self.forward_date)
|
|
||||||
if self.edit_date:
|
|
||||||
data["edit_date"] = to_timestamp(self.edit_date)
|
|
||||||
if self.photo:
|
|
||||||
data["photo"] = [p.to_dict() for p in self.photo]
|
|
||||||
if self.entities:
|
|
||||||
data["entities"] = [e.to_dict() for e in self.entities]
|
|
||||||
if self.caption_entities:
|
|
||||||
data["caption_entities"] = [e.to_dict() for e in self.caption_entities]
|
|
||||||
if self.new_chat_photo:
|
|
||||||
data["new_chat_photo"] = [p.to_dict() for p in self.new_chat_photo]
|
|
||||||
if self.new_chat_members:
|
|
||||||
data["new_chat_members"] = [u.to_dict() for u in self.new_chat_members]
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
def _quote(self, quote: Optional[bool], reply_to_message_id: Optional[int]) -> Optional[int]:
|
def _quote(self, quote: Optional[bool], reply_to_message_id: Optional[int]) -> Optional[int]:
|
||||||
"""Modify kwargs for replying with or without quoting."""
|
"""Modify kwargs for replying with or without quoting."""
|
||||||
if reply_to_message_id is not None:
|
if reply_to_message_id is not None:
|
||||||
|
|
|
@ -404,15 +404,6 @@ class SecureValue(TelegramObject):
|
||||||
|
|
||||||
return super().de_json(data=data, bot=bot)
|
return super().de_json(data=data, bot=bot)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
data["files"] = [p.to_dict() for p in self.files] # type: ignore[union-attr]
|
|
||||||
data["translation"] = [p.to_dict() for p in self.translation] # type: ignore[union-attr]
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
class _CredentialsBase(TelegramObject):
|
class _CredentialsBase(TelegramObject):
|
||||||
"""Base class for DataCredentials and FileCredentials."""
|
"""Base class for DataCredentials and FileCredentials."""
|
||||||
|
@ -450,15 +441,6 @@ class DataCredentials(_CredentialsBase):
|
||||||
def __init__(self, data_hash: str, secret: str, *, api_kwargs: JSONDict = None):
|
def __init__(self, data_hash: str, secret: str, *, api_kwargs: JSONDict = None):
|
||||||
super().__init__(hash=data_hash, secret=secret, api_kwargs=api_kwargs)
|
super().__init__(hash=data_hash, secret=secret, api_kwargs=api_kwargs)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
del data["file_hash"]
|
|
||||||
del data["hash"]
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
class FileCredentials(_CredentialsBase):
|
class FileCredentials(_CredentialsBase):
|
||||||
"""
|
"""
|
||||||
|
@ -478,12 +460,3 @@ class FileCredentials(_CredentialsBase):
|
||||||
|
|
||||||
def __init__(self, file_hash: str, secret: str, *, api_kwargs: JSONDict = None):
|
def __init__(self, file_hash: str, secret: str, *, api_kwargs: JSONDict = None):
|
||||||
super().__init__(hash=file_hash, secret=secret, api_kwargs=api_kwargs)
|
super().__init__(hash=file_hash, secret=secret, api_kwargs=api_kwargs)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
del data["data_hash"]
|
|
||||||
del data["hash"]
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
|
@ -244,14 +244,3 @@ class EncryptedPassportElement(TelegramObject):
|
||||||
)
|
)
|
||||||
|
|
||||||
return super().de_json(data=data, bot=bot)
|
return super().de_json(data=data, bot=bot)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
if self.files:
|
|
||||||
data["files"] = [p.to_dict() for p in self.files]
|
|
||||||
if self.translation:
|
|
||||||
data["translation"] = [p.to_dict() for p in self.translation]
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
|
@ -81,14 +81,6 @@ class PassportData(TelegramObject):
|
||||||
|
|
||||||
return super().de_json(data=data, bot=bot)
|
return super().de_json(data=data, bot=bot)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
data["data"] = [e.to_dict() for e in self.data]
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def decrypted_data(self) -> List[EncryptedPassportElement]:
|
def decrypted_data(self) -> List[EncryptedPassportElement]:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -64,11 +64,3 @@ class ShippingOption(TelegramObject):
|
||||||
self.prices = prices
|
self.prices = prices
|
||||||
|
|
||||||
self._id_attrs = (self.id,)
|
self._id_attrs = (self.id,)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
data["prices"] = [p.to_dict() for p in self.prices]
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ from telegram._messageentity import MessageEntity
|
||||||
from telegram._telegramobject import TelegramObject
|
from telegram._telegramobject import TelegramObject
|
||||||
from telegram._user import User
|
from telegram._user import User
|
||||||
from telegram._utils import enum
|
from telegram._utils import enum
|
||||||
from telegram._utils.datetime import from_timestamp, to_timestamp
|
from telegram._utils.datetime import from_timestamp
|
||||||
from telegram._utils.types import JSONDict
|
from telegram._utils.types import JSONDict
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
@ -228,17 +228,6 @@ class Poll(TelegramObject):
|
||||||
|
|
||||||
return super().de_json(data=data, bot=bot)
|
return super().de_json(data=data, bot=bot)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
data["options"] = [x.to_dict() for x in self.options]
|
|
||||||
if self.explanation_entities:
|
|
||||||
data["explanation_entities"] = [e.to_dict() for e in self.explanation_entities]
|
|
||||||
data["close_date"] = to_timestamp(data.get("close_date"))
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
def parse_explanation_entity(self, entity: MessageEntity) -> str:
|
def parse_explanation_entity(self, entity: MessageEntity) -> str:
|
||||||
"""Returns the text from a given :class:`telegram.MessageEntity`.
|
"""Returns the text from a given :class:`telegram.MessageEntity`.
|
||||||
|
|
||||||
|
|
|
@ -119,15 +119,6 @@ class ReplyKeyboardMarkup(TelegramObject):
|
||||||
|
|
||||||
self._id_attrs = (self.keyboard,)
|
self._id_attrs = (self.keyboard,)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
data["keyboard"] = []
|
|
||||||
for row in self.keyboard:
|
|
||||||
data["keyboard"].append([button.to_dict() for button in row])
|
|
||||||
return data
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_button(
|
def from_button(
|
||||||
cls,
|
cls,
|
||||||
|
|
|
@ -17,12 +17,14 @@
|
||||||
# You should have received a copy of the GNU Lesser Public License
|
# You should have received a copy of the GNU Lesser Public License
|
||||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||||
"""Base class for Telegram Objects."""
|
"""Base class for Telegram Objects."""
|
||||||
|
import datetime
|
||||||
import inspect
|
import inspect
|
||||||
import json
|
import json
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Sized, Tuple, Type, TypeVar, Union
|
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Sized, Tuple, Type, TypeVar, Union
|
||||||
|
|
||||||
|
from telegram._utils.datetime import to_timestamp
|
||||||
from telegram._utils.types import JSONDict
|
from telegram._utils.types import JSONDict
|
||||||
from telegram._utils.warnings import warn
|
from telegram._utils.warnings import warn
|
||||||
|
|
||||||
|
@ -327,6 +329,32 @@ class TelegramObject:
|
||||||
:obj:`dict`
|
:obj:`dict`
|
||||||
"""
|
"""
|
||||||
out = self._get_attrs(recursive=recursive)
|
out = self._get_attrs(recursive=recursive)
|
||||||
|
|
||||||
|
# Now we should convert TGObjects to dicts inside objects such as sequences, and convert
|
||||||
|
# datetimes to timestamps. This mostly eliminates the need for subclasses to override
|
||||||
|
# `to_dict`
|
||||||
|
for key, value in out.items():
|
||||||
|
if isinstance(value, (tuple, list)) and value:
|
||||||
|
val = [] # empty list to append our converted values to
|
||||||
|
for item in value:
|
||||||
|
if hasattr(item, "to_dict"):
|
||||||
|
val.append(item.to_dict(recursive=recursive))
|
||||||
|
# This branch is useful for e.g. List[List[PhotoSize|KeyboardButton]]
|
||||||
|
elif isinstance(item, (tuple, list)):
|
||||||
|
val.append(
|
||||||
|
[
|
||||||
|
i.to_dict(recursive=recursive) if hasattr(i, "to_dict") else i
|
||||||
|
for i in item
|
||||||
|
]
|
||||||
|
)
|
||||||
|
else: # if it's not a TGObject, just append it. E.g. [TGObject, 2]
|
||||||
|
val.append(item)
|
||||||
|
out[key] = val
|
||||||
|
|
||||||
|
elif isinstance(value, datetime.datetime):
|
||||||
|
out[key] = to_timestamp(value)
|
||||||
|
|
||||||
|
# Effectively "unpack" api_kwargs into `out`:
|
||||||
out.update(out.pop("api_kwargs", {})) # type: ignore[call-overload]
|
out.update(out.pop("api_kwargs", {})) # type: ignore[call-overload]
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
|
@ -69,15 +69,5 @@ class UserProfilePhotos(TelegramObject):
|
||||||
|
|
||||||
return super().de_json(data=data, bot=bot)
|
return super().de_json(data=data, bot=bot)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
data["photos"] = []
|
|
||||||
for photo in self.photos:
|
|
||||||
data["photos"].append([x.to_dict() for x in photo])
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
def __hash__(self) -> int:
|
def __hash__(self) -> int:
|
||||||
return hash(tuple(tuple(p for p in photo) for photo in self.photos))
|
return hash(tuple(tuple(p for p in photo) for photo in self.photos))
|
||||||
|
|
|
@ -23,7 +23,7 @@ from typing import TYPE_CHECKING, List, Optional
|
||||||
|
|
||||||
from telegram._telegramobject import TelegramObject
|
from telegram._telegramobject import TelegramObject
|
||||||
from telegram._user import User
|
from telegram._user import User
|
||||||
from telegram._utils.datetime import from_timestamp, to_timestamp
|
from telegram._utils.datetime import from_timestamp
|
||||||
from telegram._utils.types import JSONDict
|
from telegram._utils.types import JSONDict
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
@ -121,14 +121,6 @@ class VideoChatParticipantsInvited(TelegramObject):
|
||||||
data["users"] = User.de_list(data.get("users", []), bot)
|
data["users"] = User.de_list(data.get("users", []), bot)
|
||||||
return super().de_json(data=data, bot=bot)
|
return super().de_json(data=data, bot=bot)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
if self.users is not None:
|
|
||||||
data["users"] = [u.to_dict() for u in self.users]
|
|
||||||
return data
|
|
||||||
|
|
||||||
def __hash__(self) -> int:
|
def __hash__(self) -> int:
|
||||||
return hash(None) if self.users is None else hash(tuple(self.users))
|
return hash(None) if self.users is None else hash(tuple(self.users))
|
||||||
|
|
||||||
|
@ -175,12 +167,3 @@ class VideoChatScheduled(TelegramObject):
|
||||||
data["start_date"] = from_timestamp(data["start_date"])
|
data["start_date"] = from_timestamp(data["start_date"])
|
||||||
|
|
||||||
return super().de_json(data=data, bot=bot)
|
return super().de_json(data=data, bot=bot)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict:
|
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
|
||||||
data = super().to_dict(recursive=recursive)
|
|
||||||
|
|
||||||
# Required
|
|
||||||
data["start_date"] = to_timestamp(self.start_date)
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
|
@ -1714,7 +1714,7 @@ class TestBot:
|
||||||
message=Message(
|
message=Message(
|
||||||
1,
|
1,
|
||||||
from_user=User(1, "", False),
|
from_user=User(1, "", False),
|
||||||
date=None,
|
date=dtm.datetime.utcnow(),
|
||||||
chat=Chat(1, ""),
|
chat=Chat(1, ""),
|
||||||
text="Webhook",
|
text="Webhook",
|
||||||
),
|
),
|
||||||
|
@ -2997,7 +2997,10 @@ class TestBot:
|
||||||
)
|
)
|
||||||
|
|
||||||
message = Message(
|
message = Message(
|
||||||
1, None, None, reply_markup=bot.callback_data_cache.process_keyboard(reply_markup)
|
1,
|
||||||
|
dtm.datetime.utcnow(),
|
||||||
|
None,
|
||||||
|
reply_markup=bot.callback_data_cache.process_keyboard(reply_markup),
|
||||||
)
|
)
|
||||||
# We do to_dict -> de_json to make sure those aren't the same objects
|
# We do to_dict -> de_json to make sure those aren't the same objects
|
||||||
message.pinned_message = Message.de_json(message.to_dict(), bot)
|
message.pinned_message = Message.de_json(message.to_dict(), bot)
|
||||||
|
@ -3008,7 +3011,7 @@ class TestBot:
|
||||||
**{
|
**{
|
||||||
message_type: Message(
|
message_type: Message(
|
||||||
1,
|
1,
|
||||||
None,
|
dtm.datetime.utcnow(),
|
||||||
None,
|
None,
|
||||||
pinned_message=message,
|
pinned_message=message,
|
||||||
reply_to_message=Message.de_json(message.to_dict(), bot),
|
reply_to_message=Message.de_json(message.to_dict(), bot),
|
||||||
|
@ -3075,7 +3078,7 @@ class TestBot:
|
||||||
reply_markup = bot.callback_data_cache.process_keyboard(reply_markup)
|
reply_markup = bot.callback_data_cache.process_keyboard(reply_markup)
|
||||||
message = Message(
|
message = Message(
|
||||||
1,
|
1,
|
||||||
None,
|
dtm.datetime.utcnow(),
|
||||||
None,
|
None,
|
||||||
reply_markup=reply_markup,
|
reply_markup=reply_markup,
|
||||||
via_bot=bot.bot if self_sender else User(1, "first", False),
|
via_bot=bot.bot if self_sender else User(1, "first", False),
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
# You should have received a copy of the GNU Lesser Public License
|
# You should have received a copy of the GNU Lesser Public License
|
||||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from telegram import Audio, Bot, CallbackQuery, Chat, Message, User
|
from telegram import Audio, Bot, CallbackQuery, Chat, Message, User
|
||||||
|
@ -45,7 +47,7 @@ class TestCallbackQuery:
|
||||||
id_ = "id"
|
id_ = "id"
|
||||||
from_user = User(1, "test_user", False)
|
from_user = User(1, "test_user", False)
|
||||||
chat_instance = "chat_instance"
|
chat_instance = "chat_instance"
|
||||||
message = Message(3, None, Chat(4, "private"), from_user=User(5, "bot", False))
|
message = Message(3, datetime.utcnow(), Chat(4, "private"), from_user=User(5, "bot", False))
|
||||||
data = "data"
|
data = "data"
|
||||||
inline_message_id = "inline_message_id"
|
inline_message_id = "inline_message_id"
|
||||||
game_short_name = "the_game"
|
game_short_name = "the_game"
|
||||||
|
|
|
@ -47,7 +47,7 @@ def invite_link(creator):
|
||||||
class TestChatInviteLink:
|
class TestChatInviteLink:
|
||||||
|
|
||||||
link = "thisialink"
|
link = "thisialink"
|
||||||
creates_join_request = (False,)
|
creates_join_request = False
|
||||||
primary = True
|
primary = True
|
||||||
revoked = False
|
revoked = False
|
||||||
expire_date = datetime.datetime.now(datetime.timezone.utc)
|
expire_date = datetime.datetime.now(datetime.timezone.utc)
|
||||||
|
|
|
@ -223,6 +223,9 @@ class TestChatMemberTypes:
|
||||||
assert chat_member_dict["status"] == chat_member_type.status
|
assert chat_member_dict["status"] == chat_member_type.status
|
||||||
assert chat_member_dict["user"] == chat_member_type.user.to_dict()
|
assert chat_member_dict["user"] == chat_member_type.user.to_dict()
|
||||||
|
|
||||||
|
for slot in chat_member_type.__slots__: # additional verification for the optional args
|
||||||
|
assert getattr(chat_member_type, slot) == chat_member_dict[slot]
|
||||||
|
|
||||||
def test_equality(self, chat_member_type):
|
def test_equality(self, chat_member_type):
|
||||||
a = ChatMember(status="status", user=CMDefaults.user)
|
a = ChatMember(status="status", user=CMDefaults.user)
|
||||||
b = ChatMember(status="status", user=CMDefaults.user)
|
b = ChatMember(status="status", user=CMDefaults.user)
|
||||||
|
|
|
@ -80,7 +80,11 @@ def message(bot):
|
||||||
"forward_from_message_id": 101,
|
"forward_from_message_id": 101,
|
||||||
"forward_date": datetime.utcnow(),
|
"forward_date": datetime.utcnow(),
|
||||||
},
|
},
|
||||||
{"reply_to_message": Message(50, None, None, None)},
|
{
|
||||||
|
"reply_to_message": Message(
|
||||||
|
50, datetime.utcnow(), Chat(13, "channel"), User(9, "i", False)
|
||||||
|
)
|
||||||
|
},
|
||||||
{"edit_date": datetime.utcnow()},
|
{"edit_date": datetime.utcnow()},
|
||||||
{
|
{
|
||||||
"text": "a text message",
|
"text": "a text message",
|
||||||
|
@ -124,7 +128,11 @@ def message(bot):
|
||||||
{"message_auto_delete_timer_changed": MessageAutoDeleteTimerChanged(42)},
|
{"message_auto_delete_timer_changed": MessageAutoDeleteTimerChanged(42)},
|
||||||
{"migrate_to_chat_id": -12345},
|
{"migrate_to_chat_id": -12345},
|
||||||
{"migrate_from_chat_id": -54321},
|
{"migrate_from_chat_id": -54321},
|
||||||
{"pinned_message": Message(7, None, None, None)},
|
{
|
||||||
|
"pinned_message": Message(
|
||||||
|
7, datetime.utcnow(), Chat(13, "channel"), User(9, "i", False)
|
||||||
|
)
|
||||||
|
},
|
||||||
{"invoice": Invoice("my invoice", "invoice", "start", "EUR", 243)},
|
{"invoice": Invoice("my invoice", "invoice", "start", "EUR", 243)},
|
||||||
{
|
{
|
||||||
"successful_payment": SuccessfulPayment(
|
"successful_payment": SuccessfulPayment(
|
||||||
|
|
|
@ -238,9 +238,9 @@ class TestTelegramObject:
|
||||||
with pytest.raises(RuntimeError):
|
with pytest.raises(RuntimeError):
|
||||||
unpickled.get_bot() # There should be no bot when we pickle TGObjects
|
unpickled.get_bot() # There should be no bot when we pickle TGObjects
|
||||||
|
|
||||||
assert unpickled.chat == chat
|
assert unpickled.chat == chat, f"{unpickled.chat._id_attrs} != {chat._id_attrs}"
|
||||||
assert unpickled.from_user == user
|
assert unpickled.from_user == user
|
||||||
assert unpickled.date == date
|
assert unpickled.date == date, f"{unpickled.date} != {date}"
|
||||||
assert unpickled.photo[0] == photo
|
assert unpickled.photo[0] == photo
|
||||||
|
|
||||||
def test_pickle_apply_api_kwargs(self, bot):
|
def test_pickle_apply_api_kwargs(self, bot):
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
# You should have received a copy of the GNU Lesser Public License
|
# You should have received a copy of the GNU Lesser Public License
|
||||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||||
import time
|
import time
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ from telegram import (
|
||||||
)
|
)
|
||||||
from telegram._utils.datetime import from_timestamp
|
from telegram._utils.datetime import from_timestamp
|
||||||
|
|
||||||
message = Message(1, None, Chat(1, ""), from_user=User(1, "", False), text="Text")
|
message = Message(1, datetime.utcnow(), Chat(1, ""), from_user=User(1, "", False), text="Text")
|
||||||
chat_member_updated = ChatMemberUpdated(
|
chat_member_updated = ChatMemberUpdated(
|
||||||
Chat(1, "chat"),
|
Chat(1, "chat"),
|
||||||
User(1, "", False),
|
User(1, "", False),
|
||||||
|
|
Loading…
Reference in a new issue