Handle Lists and Tuples and Datetimes Directly in TelegramObject.to_dict (#3353)

This commit is contained in:
Harshil 2022-11-14 01:58:41 +05:30 committed by GitHub
parent e1d56178c8
commit e54c6a04de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 65 additions and 254 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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`.

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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`.

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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