mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2025-03-17 04:39:55 +01:00
Fix Signatures and Improve test_official (#2643)
This commit is contained in:
parent
641f931f19
commit
5c500fb6fd
23 changed files with 543 additions and 722 deletions
|
@ -1850,7 +1850,7 @@ class Bot(TelegramObject):
|
|||
:obj:`title` and :obj:`address` and optionally :obj:`foursquare_id` and
|
||||
:obj:`foursquare_type` or optionally :obj:`google_place_id` and
|
||||
:obj:`google_place_type`.
|
||||
* Foursquare details and Google Pace details are mutually exclusive. However, this
|
||||
* Foursquare details and Google Place details are mutually exclusive. However, this
|
||||
behaviour is undocumented and might be changed by Telegram.
|
||||
|
||||
Args:
|
||||
|
@ -2850,10 +2850,10 @@ class Bot(TelegramObject):
|
|||
@log
|
||||
def edit_message_media(
|
||||
self,
|
||||
media: 'InputMedia',
|
||||
chat_id: Union[str, int] = None,
|
||||
message_id: int = None,
|
||||
inline_message_id: int = None,
|
||||
media: 'InputMedia' = None,
|
||||
reply_markup: InlineKeyboardMarkup = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
|
@ -2866,6 +2866,8 @@ class Bot(TelegramObject):
|
|||
``file_id`` or specify a URL.
|
||||
|
||||
Args:
|
||||
media (:class:`telegram.InputMedia`): An object for a new media content
|
||||
of the message.
|
||||
chat_id (:obj:`int` | :obj:`str`, optional): Required if inline_message_id is not
|
||||
specified. Unique identifier for the target chat or username of the target channel
|
||||
(in the format ``@channelusername``).
|
||||
|
@ -2873,8 +2875,6 @@ class Bot(TelegramObject):
|
|||
Identifier of the message to edit.
|
||||
inline_message_id (:obj:`str`, optional): Required if chat_id and message_id are not
|
||||
specified. Identifier of the inline message.
|
||||
media (:class:`telegram.InputMedia`): An object for a new media content
|
||||
of the message.
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): A JSON-serialized
|
||||
object for an inline keyboard.
|
||||
timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as
|
||||
|
@ -2884,7 +2884,7 @@ class Bot(TelegramObject):
|
|||
Telegram API.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
|
||||
:class:`telegram.Message`: On success, if edited message is not an inline message, the
|
||||
edited Message is returned, otherwise :obj:`True` is returned.
|
||||
|
||||
Raises:
|
||||
|
@ -3061,7 +3061,7 @@ class Bot(TelegramObject):
|
|||
@log
|
||||
def set_webhook(
|
||||
self,
|
||||
url: str = None,
|
||||
url: str,
|
||||
certificate: FileInput = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
max_connections: int = 40,
|
||||
|
@ -3132,10 +3132,8 @@ class Bot(TelegramObject):
|
|||
.. _`guide to Webhooks`: https://core.telegram.org/bots/webhooks
|
||||
|
||||
"""
|
||||
data: JSONDict = {}
|
||||
data: JSONDict = {'url': url}
|
||||
|
||||
if url is not None:
|
||||
data['url'] = url
|
||||
if certificate:
|
||||
data['certificate'] = parse_file_input(certificate)
|
||||
if max_connections is not None:
|
||||
|
@ -4553,7 +4551,7 @@ class Bot(TelegramObject):
|
|||
def set_chat_description(
|
||||
self,
|
||||
chat_id: Union[str, int],
|
||||
description: str,
|
||||
description: str = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> bool:
|
||||
|
@ -4565,7 +4563,7 @@ class Bot(TelegramObject):
|
|||
Args:
|
||||
chat_id (:obj:`int` | :obj:`str`): Unique identifier for the target chat or username
|
||||
of the target channel (in the format ``@channelusername``).
|
||||
description (:obj:`str`): New chat description, 0-255 characters.
|
||||
description (:obj:`str`, optional): New chat description, 0-255 characters.
|
||||
timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as
|
||||
the read timeout from the server (instead of the one specified during creation of
|
||||
the connection pool).
|
||||
|
@ -4579,7 +4577,10 @@ class Bot(TelegramObject):
|
|||
:class:`telegram.error.TelegramError`
|
||||
|
||||
"""
|
||||
data: JSONDict = {'chat_id': chat_id, 'description': description}
|
||||
data: JSONDict = {'chat_id': chat_id}
|
||||
|
||||
if description is not None:
|
||||
data['description'] = description
|
||||
|
||||
result = self._post('setChatDescription', data, timeout=timeout, api_kwargs=api_kwargs)
|
||||
|
||||
|
|
|
@ -319,7 +319,7 @@ class CallbackQuery(TelegramObject):
|
|||
|
||||
def edit_message_media(
|
||||
self,
|
||||
media: 'InputMedia' = None,
|
||||
media: 'InputMedia',
|
||||
reply_markup: 'InlineKeyboardMarkup' = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
|
@ -337,7 +337,7 @@ class CallbackQuery(TelegramObject):
|
|||
:meth:`telegram.Bot.edit_message_media` and :meth:`telegram.Message.edit_media`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
|
||||
:class:`telegram.Message`: On success, if edited message is not an inline message, the
|
||||
edited Message is returned, otherwise :obj:`True` is returned.
|
||||
|
||||
"""
|
||||
|
|
|
@ -32,14 +32,23 @@ class ChatInviteLink(TelegramObject):
|
|||
"""This object represents an invite link for a chat.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`invite_link`, :attr:`creator`, :attr:`is_primary` and
|
||||
:attr:`is_revoked` are equal.
|
||||
considered equal, if their :attr:`invite_link`, :attr:`creator`, :attr:`creates_join_request`,
|
||||
:attr:`is_primary` and :attr:`is_revoked` are equal.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
.. versionchanged:: 14.0
|
||||
|
||||
* The argument & attribute :attr:`creates_join_request` is now required to comply with the
|
||||
Bot API.
|
||||
* Comparing objects of this class now also takes :attr:`creates_join_request` into account.
|
||||
|
||||
Args:
|
||||
invite_link (:obj:`str`): The invite link.
|
||||
creator (:class:`telegram.User`): Creator of the link.
|
||||
creates_join_request (:obj:`bool`): :obj:`True`, if users joining the chat via
|
||||
the link need to be approved by chat administrators.
|
||||
|
||||
.. versionadded:: 13.8
|
||||
is_primary (:obj:`bool`): :obj:`True`, if the link is primary.
|
||||
is_revoked (:obj:`bool`): :obj:`True`, if the link is revoked.
|
||||
expire_date (:class:`datetime.datetime`, optional): Date when the link will expire or
|
||||
|
@ -48,10 +57,6 @@ class ChatInviteLink(TelegramObject):
|
|||
chat simultaneously after joining the chat via this invite link; 1-99999.
|
||||
name (:obj:`str`, optional): Invite link name.
|
||||
|
||||
.. versionadded:: 13.8
|
||||
creates_join_request (:obj:`bool`, optional): :obj:`True`, if users joining the chat via
|
||||
the link need to be approved by chat administrators.
|
||||
|
||||
.. versionadded:: 13.8
|
||||
pending_join_request_count (:obj:`int`, optional): Number of pending join requests
|
||||
created using this link.
|
||||
|
@ -62,6 +67,10 @@ class ChatInviteLink(TelegramObject):
|
|||
invite_link (:obj:`str`): The invite link. If the link was created by another chat
|
||||
administrator, then the second part of the link will be replaced with ``'…'``.
|
||||
creator (:class:`telegram.User`): Creator of the link.
|
||||
creates_join_request (:obj:`bool`): :obj:`True`, if users joining the chat via
|
||||
the link need to be approved by chat administrators.
|
||||
|
||||
.. versionadded:: 13.8
|
||||
is_primary (:obj:`bool`): :obj:`True`, if the link is primary.
|
||||
is_revoked (:obj:`bool`): :obj:`True`, if the link is revoked.
|
||||
expire_date (:class:`datetime.datetime`): Optional. Date when the link will expire or
|
||||
|
@ -70,10 +79,6 @@ class ChatInviteLink(TelegramObject):
|
|||
of the chat simultaneously after joining the chat via this invite link; 1-99999.
|
||||
name (:obj:`str`): Optional. Invite link name.
|
||||
|
||||
.. versionadded:: 13.8
|
||||
creates_join_request (:obj:`bool`): Optional. :obj:`True`, if users joining the chat via
|
||||
the link need to be approved by chat administrators.
|
||||
|
||||
.. versionadded:: 13.8
|
||||
pending_join_request_count (:obj:`int`): Optional. Number of pending join requests
|
||||
created using this link.
|
||||
|
@ -98,18 +103,19 @@ class ChatInviteLink(TelegramObject):
|
|||
self,
|
||||
invite_link: str,
|
||||
creator: User,
|
||||
creates_join_request: bool,
|
||||
is_primary: bool,
|
||||
is_revoked: bool,
|
||||
expire_date: datetime.datetime = None,
|
||||
member_limit: int = None,
|
||||
name: str = None,
|
||||
creates_join_request: bool = None,
|
||||
pending_join_request_count: int = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
# Required
|
||||
self.invite_link = invite_link
|
||||
self.creator = creator
|
||||
self.creates_join_request = creates_join_request
|
||||
self.is_primary = is_primary
|
||||
self.is_revoked = is_revoked
|
||||
|
||||
|
@ -117,11 +123,16 @@ class ChatInviteLink(TelegramObject):
|
|||
self.expire_date = expire_date
|
||||
self.member_limit = int(member_limit) if member_limit is not None else None
|
||||
self.name = name
|
||||
self.creates_join_request = creates_join_request
|
||||
self.pending_join_request_count = (
|
||||
int(pending_join_request_count) if pending_join_request_count is not None else None
|
||||
)
|
||||
self._id_attrs = (self.invite_link, self.creator, self.is_primary, self.is_revoked)
|
||||
self._id_attrs = (
|
||||
self.invite_link,
|
||||
self.creates_join_request,
|
||||
self.creator,
|
||||
self.is_primary,
|
||||
self.is_revoked,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: 'Bot') -> Optional['ChatInviteLink']:
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram ChatMember."""
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, Any, Optional, ClassVar, Dict, Type
|
||||
from typing import TYPE_CHECKING, Optional, ClassVar, Dict, Type
|
||||
|
||||
from telegram import TelegramObject, User, constants
|
||||
from telegram.utils.helpers import from_timestamp, to_timestamp
|
||||
|
@ -42,10 +42,10 @@ class ChatMember(TelegramObject):
|
|||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`user` and :attr:`status` are equal.
|
||||
|
||||
Note:
|
||||
As of Bot API 5.3, :class:`ChatMember` is nothing but the base class for the subclasses
|
||||
.. versionchanged:: 14.0
|
||||
As of Bot API 5.3, :class:`ChatMember` is nothing but the base class for the subclasses
|
||||
listed above and is no longer returned directly by :meth:`~telegram.Bot.get_chat`.
|
||||
Therefore, most of the arguments and attributes were deprecated and you should no longer
|
||||
Therefore, most of the arguments and attributes were removed and you should no longer
|
||||
use :class:`ChatMember` directly.
|
||||
|
||||
Args:
|
||||
|
@ -54,240 +54,14 @@ class ChatMember(TelegramObject):
|
|||
:attr:`~telegram.ChatMember.ADMINISTRATOR`, :attr:`~telegram.ChatMember.CREATOR`,
|
||||
:attr:`~telegram.ChatMember.KICKED`, :attr:`~telegram.ChatMember.LEFT`,
|
||||
:attr:`~telegram.ChatMember.MEMBER` or :attr:`~telegram.ChatMember.RESTRICTED`.
|
||||
custom_title (:obj:`str`, optional): Owner and administrators only.
|
||||
Custom title for this user.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
is_anonymous (:obj:`bool`, optional): Owner and administrators only. :obj:`True`, if the
|
||||
user's presence in the chat is hidden.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
until_date (:class:`datetime.datetime`, optional): Restricted and kicked only. Date when
|
||||
restrictions will be lifted for this user.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_be_edited (:obj:`bool`, optional): Administrators only. :obj:`True`, if the bot is
|
||||
allowed to edit administrator privileges of that user.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_manage_chat (:obj:`bool`, optional): Administrators only. :obj:`True`, if the
|
||||
administrator can access the chat event log, chat statistics, message statistics in
|
||||
channels, see channel members, see anonymous administrators in supergroups and ignore
|
||||
slow mode. Implied by any other administrator privilege.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_manage_voice_chats (:obj:`bool`, optional): Administrators only. :obj:`True`, if the
|
||||
administrator can manage voice chats.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_change_info (:obj:`bool`, optional): Administrators and restricted only. :obj:`True`,
|
||||
if the user can change the chat title, photo and other settings.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_post_messages (:obj:`bool`, optional): Administrators only. :obj:`True`, if the
|
||||
administrator can post in the channel, channels only.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_edit_messages (:obj:`bool`, optional): Administrators only. :obj:`True`, if the
|
||||
administrator can edit messages of other users and can pin messages; channels only.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_delete_messages (:obj:`bool`, optional): Administrators only. :obj:`True`, if the
|
||||
administrator can delete messages of other users.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_invite_users (:obj:`bool`, optional): Administrators and restricted only. :obj:`True`,
|
||||
if the user can invite new users to the chat.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_restrict_members (:obj:`bool`, optional): Administrators only. :obj:`True`, if the
|
||||
administrator can restrict, ban or unban chat members.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_pin_messages (:obj:`bool`, optional): Administrators and restricted only. :obj:`True`,
|
||||
if the user can pin messages, groups and supergroups only.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_promote_members (:obj:`bool`, optional): Administrators only. :obj:`True`, if the
|
||||
administrator can add new administrators with a subset of his own privileges or demote
|
||||
administrators that he has promoted, directly or indirectly (promoted by administrators
|
||||
that were appointed by the user).
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
is_member (:obj:`bool`, optional): Restricted only. :obj:`True`, if the user is a member of
|
||||
the chat at the moment of the request.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_send_messages (:obj:`bool`, optional): Restricted only. :obj:`True`, if the user can
|
||||
send text messages, contacts, locations and venues.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_send_media_messages (:obj:`bool`, optional): Restricted only. :obj:`True`, if the user
|
||||
can send audios, documents, photos, videos, video notes and voice notes.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_send_polls (:obj:`bool`, optional): Restricted only. :obj:`True`, if the user is
|
||||
allowed to send polls.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_send_other_messages (:obj:`bool`, optional): Restricted only. :obj:`True`, if the user
|
||||
can send animations, games, stickers and use inline bots.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_add_web_page_previews (:obj:`bool`, optional): Restricted only. :obj:`True`, if user
|
||||
may add web page previews to his messages.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
Attributes:
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
status (:obj:`str`): The member's status in the chat.
|
||||
custom_title (:obj:`str`): Optional. Custom title for owner and administrators.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
is_anonymous (:obj:`bool`): Optional. :obj:`True`, if the user's presence in the chat is
|
||||
hidden.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
until_date (:class:`datetime.datetime`): Optional. Date when restrictions will be lifted
|
||||
for this user.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_be_edited (:obj:`bool`): Optional. If the bot is allowed to edit administrator
|
||||
privileges of that user.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_manage_chat (:obj:`bool`): Optional. If the administrator can access the chat event
|
||||
log, chat statistics, message statistics in channels, see channel members, see
|
||||
anonymous administrators in supergroups and ignore slow mode.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_manage_voice_chats (:obj:`bool`): Optional. if the administrator can manage
|
||||
voice chats.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_change_info (:obj:`bool`): Optional. If the user can change the chat title, photo and
|
||||
other settings.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_post_messages (:obj:`bool`): Optional. If the administrator can post in the channel.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_edit_messages (:obj:`bool`): Optional. If the administrator can edit messages of other
|
||||
users.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_delete_messages (:obj:`bool`): Optional. If the administrator can delete messages of
|
||||
other users.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_invite_users (:obj:`bool`): Optional. If the user can invite new users to the chat.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_restrict_members (:obj:`bool`): Optional. If the administrator can restrict, ban or
|
||||
unban chat members.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_pin_messages (:obj:`bool`): Optional. If the user can pin messages.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_promote_members (:obj:`bool`): Optional. If the administrator can add new
|
||||
administrators.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
is_member (:obj:`bool`): Optional. Restricted only. :obj:`True`, if the user is a member of
|
||||
the chat at the moment of the request.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_send_messages (:obj:`bool`): Optional. If the user can send text messages, contacts,
|
||||
locations and venues.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_send_media_messages (:obj:`bool`): Optional. If the user can send media messages,
|
||||
implies can_send_messages.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_send_polls (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to
|
||||
send polls.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_send_other_messages (:obj:`bool`): Optional. If the user can send animations, games,
|
||||
stickers and use inline bots, implies can_send_media_messages.
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
can_add_web_page_previews (:obj:`bool`): Optional. If user may add web page previews to his
|
||||
messages, implies can_send_media_messages
|
||||
|
||||
.. deprecated:: 13.7
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
'is_member',
|
||||
'can_restrict_members',
|
||||
'can_delete_messages',
|
||||
'custom_title',
|
||||
'can_be_edited',
|
||||
'can_post_messages',
|
||||
'can_send_messages',
|
||||
'can_edit_messages',
|
||||
'can_send_media_messages',
|
||||
'is_anonymous',
|
||||
'can_add_web_page_previews',
|
||||
'can_send_other_messages',
|
||||
'can_invite_users',
|
||||
'can_send_polls',
|
||||
'user',
|
||||
'can_promote_members',
|
||||
'status',
|
||||
'can_change_info',
|
||||
'can_pin_messages',
|
||||
'can_manage_chat',
|
||||
'can_manage_voice_chats',
|
||||
'until_date',
|
||||
)
|
||||
__slots__ = ('user', 'status')
|
||||
|
||||
ADMINISTRATOR: ClassVar[str] = constants.CHATMEMBER_ADMINISTRATOR
|
||||
""":const:`telegram.constants.CHATMEMBER_ADMINISTRATOR`"""
|
||||
|
@ -302,58 +76,11 @@ class ChatMember(TelegramObject):
|
|||
RESTRICTED: ClassVar[str] = constants.CHATMEMBER_RESTRICTED
|
||||
""":const:`telegram.constants.CHATMEMBER_RESTRICTED`"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
user: User,
|
||||
status: str,
|
||||
until_date: datetime.datetime = None,
|
||||
can_be_edited: bool = None,
|
||||
can_change_info: bool = None,
|
||||
can_post_messages: bool = None,
|
||||
can_edit_messages: bool = None,
|
||||
can_delete_messages: bool = None,
|
||||
can_invite_users: bool = None,
|
||||
can_restrict_members: bool = None,
|
||||
can_pin_messages: bool = None,
|
||||
can_promote_members: bool = None,
|
||||
can_send_messages: bool = None,
|
||||
can_send_media_messages: bool = None,
|
||||
can_send_polls: bool = None,
|
||||
can_send_other_messages: bool = None,
|
||||
can_add_web_page_previews: bool = None,
|
||||
is_member: bool = None,
|
||||
custom_title: str = None,
|
||||
is_anonymous: bool = None,
|
||||
can_manage_chat: bool = None,
|
||||
can_manage_voice_chats: bool = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
# Required
|
||||
def __init__(self, user: User, status: str, **_kwargs: object):
|
||||
# Required by all subclasses
|
||||
self.user = user
|
||||
self.status = status
|
||||
|
||||
# Optionals
|
||||
self.custom_title = custom_title
|
||||
self.is_anonymous = is_anonymous
|
||||
self.until_date = until_date
|
||||
self.can_be_edited = can_be_edited
|
||||
self.can_change_info = can_change_info
|
||||
self.can_post_messages = can_post_messages
|
||||
self.can_edit_messages = can_edit_messages
|
||||
self.can_delete_messages = can_delete_messages
|
||||
self.can_invite_users = can_invite_users
|
||||
self.can_restrict_members = can_restrict_members
|
||||
self.can_pin_messages = can_pin_messages
|
||||
self.can_promote_members = can_promote_members
|
||||
self.can_send_messages = can_send_messages
|
||||
self.can_send_media_messages = can_send_media_messages
|
||||
self.can_send_polls = can_send_polls
|
||||
self.can_send_other_messages = can_send_other_messages
|
||||
self.can_add_web_page_previews = can_add_web_page_previews
|
||||
self.is_member = is_member
|
||||
self.can_manage_chat = can_manage_chat
|
||||
self.can_manage_voice_chats = can_manage_voice_chats
|
||||
|
||||
self._id_attrs = (self.user, self.status)
|
||||
|
||||
@classmethod
|
||||
|
@ -384,7 +111,8 @@ class ChatMember(TelegramObject):
|
|||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
||||
data = super().to_dict()
|
||||
|
||||
data['until_date'] = to_timestamp(self.until_date)
|
||||
if data.get('until_date', False):
|
||||
data['until_date'] = to_timestamp(data['until_date'])
|
||||
|
||||
return data
|
||||
|
||||
|
@ -398,35 +126,32 @@ class ChatMemberOwner(ChatMember):
|
|||
|
||||
Args:
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
custom_title (:obj:`str`, optional): Custom title for this user.
|
||||
is_anonymous (:obj:`bool`, optional): :obj:`True`, if the
|
||||
is_anonymous (:obj:`bool`): :obj:`True`, if the
|
||||
user's presence in the chat is hidden.
|
||||
custom_title (:obj:`str`, optional): Custom title for this user.
|
||||
|
||||
Attributes:
|
||||
status (:obj:`str`): The member's status in the chat,
|
||||
always :attr:`telegram.ChatMember.CREATOR`.
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
is_anonymous (:obj:`bool`): :obj:`True`, if the user's
|
||||
presence in the chat is hidden.
|
||||
custom_title (:obj:`str`): Optional. Custom title for
|
||||
this user.
|
||||
is_anonymous (:obj:`bool`): Optional. :obj:`True`, if the user's
|
||||
presence in the chat is hidden.
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
__slots__ = ('is_anonymous', 'custom_title')
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
user: User,
|
||||
is_anonymous: bool,
|
||||
custom_title: str = None,
|
||||
is_anonymous: bool = None,
|
||||
**_kwargs: Any,
|
||||
**_kwargs: object,
|
||||
):
|
||||
super().__init__(
|
||||
status=ChatMember.CREATOR,
|
||||
user=user,
|
||||
custom_title=custom_title,
|
||||
is_anonymous=is_anonymous,
|
||||
)
|
||||
super().__init__(status=ChatMember.CREATOR, user=user)
|
||||
self.is_anonymous = is_anonymous
|
||||
self.custom_title = custom_title
|
||||
|
||||
|
||||
class ChatMemberAdministrator(ChatMember):
|
||||
|
@ -437,110 +162,121 @@ class ChatMemberAdministrator(ChatMember):
|
|||
|
||||
Args:
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
can_be_edited (:obj:`bool`, optional): :obj:`True`, if the bot
|
||||
can_be_edited (:obj:`bool`): :obj:`True`, if the bot
|
||||
is allowed to edit administrator privileges of that user.
|
||||
custom_title (:obj:`str`, optional): Custom title for this user.
|
||||
is_anonymous (:obj:`bool`, optional): :obj:`True`, if the user's
|
||||
is_anonymous (:obj:`bool`): :obj:`True`, if the user's
|
||||
presence in the chat is hidden.
|
||||
can_manage_chat (:obj:`bool`, optional): :obj:`True`, if the administrator
|
||||
can_manage_chat (:obj:`bool`): :obj:`True`, if the administrator
|
||||
can access the chat event log, chat statistics, message statistics in
|
||||
channels, see channel members, see anonymous administrators in supergroups
|
||||
and ignore slow mode. Implied by any other administrator privilege.
|
||||
can_delete_messages (:obj:`bool`): :obj:`True`, if the
|
||||
administrator can delete messages of other users.
|
||||
can_manage_voice_chats (:obj:`bool`): :obj:`True`, if the
|
||||
administrator can manage voice chats.
|
||||
can_restrict_members (:obj:`bool`): :obj:`True`, if the
|
||||
administrator can restrict, ban or unban chat members.
|
||||
can_promote_members (:obj:`bool`): :obj:`True`, if the administrator
|
||||
can add new administrators with a subset of his own privileges or demote
|
||||
administrators that he has promoted, directly or indirectly (promoted by
|
||||
administrators that were appointed by the user).
|
||||
can_change_info (:obj:`bool`): :obj:`True`, if the user can change
|
||||
the chat title, photo and other settings.
|
||||
can_invite_users (:obj:`bool`): :obj:`True`, if the user can invite
|
||||
new users to the chat.
|
||||
can_post_messages (:obj:`bool`, optional): :obj:`True`, if the
|
||||
administrator can post in the channel, channels only.
|
||||
can_edit_messages (:obj:`bool`, optional): :obj:`True`, if the
|
||||
administrator can edit messages of other users and can pin
|
||||
messages; channels only.
|
||||
can_delete_messages (:obj:`bool`, optional): :obj:`True`, if the
|
||||
administrator can delete messages of other users.
|
||||
can_manage_voice_chats (:obj:`bool`, optional): :obj:`True`, if the
|
||||
administrator can manage voice chats.
|
||||
can_restrict_members (:obj:`bool`, optional): :obj:`True`, if the
|
||||
administrator can restrict, ban or unban chat members.
|
||||
can_promote_members (:obj:`bool`, optional): :obj:`True`, if the administrator
|
||||
can add new administrators with a subset of his own privileges or demote
|
||||
administrators that he has promoted, directly or indirectly (promoted by
|
||||
administrators that were appointed by the user).
|
||||
can_change_info (:obj:`bool`, optional): :obj:`True`, if the user can change
|
||||
the chat title, photo and other settings.
|
||||
can_invite_users (:obj:`bool`, optional): :obj:`True`, if the user can invite
|
||||
new users to the chat.
|
||||
can_pin_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed
|
||||
to pin messages; groups and supergroups only.
|
||||
custom_title (:obj:`str`, optional): Custom title for this user.
|
||||
|
||||
Attributes:
|
||||
status (:obj:`str`): The member's status in the chat,
|
||||
always :attr:`telegram.ChatMember.ADMINISTRATOR`.
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
can_be_edited (:obj:`bool`): Optional. :obj:`True`, if the bot
|
||||
can_be_edited (:obj:`bool`): :obj:`True`, if the bot
|
||||
is allowed to edit administrator privileges of that user.
|
||||
custom_title (:obj:`str`): Optional. Custom title for this user.
|
||||
is_anonymous (:obj:`bool`): Optional. :obj:`True`, if the user's
|
||||
is_anonymous (:obj:`bool`): :obj:`True`, if the user's
|
||||
presence in the chat is hidden.
|
||||
can_manage_chat (:obj:`bool`): Optional. :obj:`True`, if the administrator
|
||||
can_manage_chat (:obj:`bool`): :obj:`True`, if the administrator
|
||||
can access the chat event log, chat statistics, message statistics in
|
||||
channels, see channel members, see anonymous administrators in supergroups
|
||||
and ignore slow mode. Implied by any other administrator privilege.
|
||||
can_delete_messages (:obj:`bool`): :obj:`True`, if the
|
||||
administrator can delete messages of other users.
|
||||
can_manage_voice_chats (:obj:`bool`): :obj:`True`, if the
|
||||
administrator can manage voice chats.
|
||||
can_restrict_members (:obj:`bool`): :obj:`True`, if the
|
||||
administrator can restrict, ban or unban chat members.
|
||||
can_promote_members (:obj:`bool`): :obj:`True`, if the administrator
|
||||
can add new administrators with a subset of his own privileges or demote
|
||||
administrators that he has promoted, directly or indirectly (promoted by
|
||||
administrators that were appointed by the user).
|
||||
can_change_info (:obj:`bool`): :obj:`True`, if the user can change
|
||||
the chat title, photo and other settings.
|
||||
can_invite_users (:obj:`bool`): :obj:`True`, if the user can invite
|
||||
new users to the chat.
|
||||
can_post_messages (:obj:`bool`): Optional. :obj:`True`, if the
|
||||
administrator can post in the channel, channels only.
|
||||
can_edit_messages (:obj:`bool`): Optional. :obj:`True`, if the
|
||||
administrator can edit messages of other users and can pin
|
||||
messages; channels only.
|
||||
can_delete_messages (:obj:`bool`): Optional. :obj:`True`, if the
|
||||
administrator can delete messages of other users.
|
||||
can_manage_voice_chats (:obj:`bool`): Optional. :obj:`True`, if the
|
||||
administrator can manage voice chats.
|
||||
can_restrict_members (:obj:`bool`): Optional. :obj:`True`, if the
|
||||
administrator can restrict, ban or unban chat members.
|
||||
can_promote_members (:obj:`bool`): Optional. :obj:`True`, if the administrator
|
||||
can add new administrators with a subset of his own privileges or demote
|
||||
administrators that he has promoted, directly or indirectly (promoted by
|
||||
administrators that were appointed by the user).
|
||||
can_change_info (:obj:`bool`): Optional. :obj:`True`, if the user can change
|
||||
the chat title, photo and other settings.
|
||||
can_invite_users (:obj:`bool`): Optional. :obj:`True`, if the user can invite
|
||||
new users to the chat.
|
||||
can_pin_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
|
||||
to pin messages; groups and supergroups only.
|
||||
custom_title (:obj:`str`): Optional. Custom title for this user.
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
__slots__ = (
|
||||
'can_be_edited',
|
||||
'is_anonymous',
|
||||
'can_manage_chat',
|
||||
'can_delete_messages',
|
||||
'can_manage_voice_chats',
|
||||
'can_restrict_members',
|
||||
'can_promote_members',
|
||||
'can_change_info',
|
||||
'can_invite_users',
|
||||
'can_post_messages',
|
||||
'can_edit_messages',
|
||||
'can_pin_messages',
|
||||
'custom_title',
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
user: User,
|
||||
can_be_edited: bool = None,
|
||||
custom_title: str = None,
|
||||
is_anonymous: bool = None,
|
||||
can_manage_chat: bool = None,
|
||||
can_be_edited: bool,
|
||||
is_anonymous: bool,
|
||||
can_manage_chat: bool,
|
||||
can_delete_messages: bool,
|
||||
can_manage_voice_chats: bool,
|
||||
can_restrict_members: bool,
|
||||
can_promote_members: bool,
|
||||
can_change_info: bool,
|
||||
can_invite_users: bool,
|
||||
can_post_messages: bool = None,
|
||||
can_edit_messages: bool = None,
|
||||
can_delete_messages: bool = None,
|
||||
can_manage_voice_chats: bool = None,
|
||||
can_restrict_members: bool = None,
|
||||
can_promote_members: bool = None,
|
||||
can_change_info: bool = None,
|
||||
can_invite_users: bool = None,
|
||||
can_pin_messages: bool = None,
|
||||
**_kwargs: Any,
|
||||
custom_title: str = None,
|
||||
**_kwargs: object,
|
||||
):
|
||||
super().__init__(
|
||||
status=ChatMember.ADMINISTRATOR,
|
||||
user=user,
|
||||
can_be_edited=can_be_edited,
|
||||
custom_title=custom_title,
|
||||
is_anonymous=is_anonymous,
|
||||
can_manage_chat=can_manage_chat,
|
||||
can_post_messages=can_post_messages,
|
||||
can_edit_messages=can_edit_messages,
|
||||
can_delete_messages=can_delete_messages,
|
||||
can_manage_voice_chats=can_manage_voice_chats,
|
||||
can_restrict_members=can_restrict_members,
|
||||
can_promote_members=can_promote_members,
|
||||
can_change_info=can_change_info,
|
||||
can_invite_users=can_invite_users,
|
||||
can_pin_messages=can_pin_messages,
|
||||
)
|
||||
super().__init__(status=ChatMember.ADMINISTRATOR, user=user)
|
||||
self.can_be_edited = can_be_edited
|
||||
self.is_anonymous = is_anonymous
|
||||
self.can_manage_chat = can_manage_chat
|
||||
self.can_delete_messages = can_delete_messages
|
||||
self.can_manage_voice_chats = can_manage_voice_chats
|
||||
self.can_restrict_members = can_restrict_members
|
||||
self.can_promote_members = can_promote_members
|
||||
self.can_change_info = can_change_info
|
||||
self.can_invite_users = can_invite_users
|
||||
self.can_post_messages = can_post_messages
|
||||
self.can_edit_messages = can_edit_messages
|
||||
self.can_pin_messages = can_pin_messages
|
||||
self.custom_title = custom_title
|
||||
|
||||
|
||||
class ChatMemberMember(ChatMember):
|
||||
|
@ -562,7 +298,7 @@ class ChatMemberMember(ChatMember):
|
|||
|
||||
__slots__ = ()
|
||||
|
||||
def __init__(self, user: User, **_kwargs: Any):
|
||||
def __init__(self, user: User, **_kwargs: object):
|
||||
super().__init__(status=ChatMember.MEMBER, user=user)
|
||||
|
||||
|
||||
|
@ -575,85 +311,93 @@ class ChatMemberRestricted(ChatMember):
|
|||
|
||||
Args:
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
is_member (:obj:`bool`, optional): :obj:`True`, if the user is a
|
||||
is_member (:obj:`bool`): :obj:`True`, if the user is a
|
||||
member of the chat at the moment of the request.
|
||||
can_change_info (:obj:`bool`, optional): :obj:`True`, if the user can change
|
||||
can_change_info (:obj:`bool`): :obj:`True`, if the user can change
|
||||
the chat title, photo and other settings.
|
||||
can_invite_users (:obj:`bool`, optional): :obj:`True`, if the user can invite
|
||||
can_invite_users (:obj:`bool`): :obj:`True`, if the user can invite
|
||||
new users to the chat.
|
||||
can_pin_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed
|
||||
can_pin_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to pin messages; groups and supergroups only.
|
||||
can_send_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed
|
||||
can_send_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send text messages, contacts, locations and venues.
|
||||
can_send_media_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed
|
||||
can_send_media_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send audios, documents, photos, videos, video notes and voice notes.
|
||||
can_send_polls (:obj:`bool`, optional): :obj:`True`, if the user is allowed
|
||||
can_send_polls (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send polls.
|
||||
can_send_other_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed
|
||||
can_send_other_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send animations, games, stickers and use inline bots.
|
||||
can_add_web_page_previews (:obj:`bool`, optional): :obj:`True`, if the user is
|
||||
can_add_web_page_previews (:obj:`bool`): :obj:`True`, if the user is
|
||||
allowed to add web page previews to their messages.
|
||||
until_date (:class:`datetime.datetime`, optional): Date when restrictions
|
||||
until_date (:class:`datetime.datetime`): Date when restrictions
|
||||
will be lifted for this user.
|
||||
|
||||
Attributes:
|
||||
status (:obj:`str`): The member's status in the chat,
|
||||
always :attr:`telegram.ChatMember.RESTRICTED`.
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
is_member (:obj:`bool`): Optional. :obj:`True`, if the user is a
|
||||
is_member (:obj:`bool`): :obj:`True`, if the user is a
|
||||
member of the chat at the moment of the request.
|
||||
can_change_info (:obj:`bool`): Optional. :obj:`True`, if the user can change
|
||||
can_change_info (:obj:`bool`): :obj:`True`, if the user can change
|
||||
the chat title, photo and other settings.
|
||||
can_invite_users (:obj:`bool`): Optional. :obj:`True`, if the user can invite
|
||||
can_invite_users (:obj:`bool`): :obj:`True`, if the user can invite
|
||||
new users to the chat.
|
||||
can_pin_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
|
||||
can_pin_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to pin messages; groups and supergroups only.
|
||||
can_send_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
|
||||
can_send_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send text messages, contacts, locations and venues.
|
||||
can_send_media_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
|
||||
can_send_media_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send audios, documents, photos, videos, video notes and voice notes.
|
||||
can_send_polls (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
|
||||
can_send_polls (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send polls.
|
||||
can_send_other_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
|
||||
can_send_other_messages (:obj:`bool`): :obj:`True`, if the user is allowed
|
||||
to send animations, games, stickers and use inline bots.
|
||||
can_add_web_page_previews (:obj:`bool`): Optional. :obj:`True`, if the user is
|
||||
can_add_web_page_previews (:obj:`bool`): :obj:`True`, if the user is
|
||||
allowed to add web page previews to their messages.
|
||||
until_date (:class:`datetime.datetime`): Optional. Date when restrictions
|
||||
until_date (:class:`datetime.datetime`): Date when restrictions
|
||||
will be lifted for this user.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
__slots__ = (
|
||||
'is_member',
|
||||
'can_change_info',
|
||||
'can_invite_users',
|
||||
'can_pin_messages',
|
||||
'can_send_messages',
|
||||
'can_send_media_messages',
|
||||
'can_send_polls',
|
||||
'can_send_other_messages',
|
||||
'can_add_web_page_previews',
|
||||
'until_date',
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
user: User,
|
||||
is_member: bool = None,
|
||||
can_change_info: bool = None,
|
||||
can_invite_users: bool = None,
|
||||
can_pin_messages: bool = None,
|
||||
can_send_messages: bool = None,
|
||||
can_send_media_messages: bool = None,
|
||||
can_send_polls: bool = None,
|
||||
can_send_other_messages: bool = None,
|
||||
can_add_web_page_previews: bool = None,
|
||||
until_date: datetime.datetime = None,
|
||||
**_kwargs: Any,
|
||||
is_member: bool,
|
||||
can_change_info: bool,
|
||||
can_invite_users: bool,
|
||||
can_pin_messages: bool,
|
||||
can_send_messages: bool,
|
||||
can_send_media_messages: bool,
|
||||
can_send_polls: bool,
|
||||
can_send_other_messages: bool,
|
||||
can_add_web_page_previews: bool,
|
||||
until_date: datetime.datetime,
|
||||
**_kwargs: object,
|
||||
):
|
||||
super().__init__(
|
||||
status=ChatMember.RESTRICTED,
|
||||
user=user,
|
||||
is_member=is_member,
|
||||
can_change_info=can_change_info,
|
||||
can_invite_users=can_invite_users,
|
||||
can_pin_messages=can_pin_messages,
|
||||
can_send_messages=can_send_messages,
|
||||
can_send_media_messages=can_send_media_messages,
|
||||
can_send_polls=can_send_polls,
|
||||
can_send_other_messages=can_send_other_messages,
|
||||
can_add_web_page_previews=can_add_web_page_previews,
|
||||
until_date=until_date,
|
||||
)
|
||||
super().__init__(status=ChatMember.RESTRICTED, user=user)
|
||||
self.is_member = is_member
|
||||
self.can_change_info = can_change_info
|
||||
self.can_invite_users = can_invite_users
|
||||
self.can_pin_messages = can_pin_messages
|
||||
self.can_send_messages = can_send_messages
|
||||
self.can_send_media_messages = can_send_media_messages
|
||||
self.can_send_polls = can_send_polls
|
||||
self.can_send_other_messages = can_send_other_messages
|
||||
self.can_add_web_page_previews = can_add_web_page_previews
|
||||
self.until_date = until_date
|
||||
|
||||
|
||||
class ChatMemberLeft(ChatMember):
|
||||
|
@ -674,7 +418,7 @@ class ChatMemberLeft(ChatMember):
|
|||
|
||||
__slots__ = ()
|
||||
|
||||
def __init__(self, user: User, **_kwargs: Any):
|
||||
def __init__(self, user: User, **_kwargs: object):
|
||||
super().__init__(status=ChatMember.LEFT, user=user)
|
||||
|
||||
|
||||
|
@ -687,28 +431,20 @@ class ChatMemberBanned(ChatMember):
|
|||
|
||||
Args:
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
until_date (:class:`datetime.datetime`, optional): Date when restrictions
|
||||
until_date (:class:`datetime.datetime`): Date when restrictions
|
||||
will be lifted for this user.
|
||||
|
||||
Attributes:
|
||||
status (:obj:`str`): The member's status in the chat,
|
||||
always :attr:`telegram.ChatMember.KICKED`.
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
until_date (:class:`datetime.datetime`): Optional. Date when restrictions
|
||||
until_date (:class:`datetime.datetime`): Date when restrictions
|
||||
will be lifted for this user.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
__slots__ = ('until_date',)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
user: User,
|
||||
until_date: datetime.datetime = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
super().__init__(
|
||||
status=ChatMember.KICKED,
|
||||
user=user,
|
||||
until_date=until_date,
|
||||
)
|
||||
def __init__(self, user: User, until_date: datetime.datetime, **_kwargs: object):
|
||||
super().__init__(status=ChatMember.KICKED, user=user)
|
||||
self.until_date = until_date
|
||||
|
|
|
@ -33,6 +33,10 @@ class ForceReply(ReplyMarkup):
|
|||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`selective` is equal.
|
||||
|
||||
.. versionchanged:: 14.0
|
||||
The (undocumented) argument ``force_reply`` was removed and instead :attr:`force_reply`
|
||||
is now always set to :obj:`True` as expected by the Bot API.
|
||||
|
||||
Args:
|
||||
selective (:obj:`bool`, optional): Use this parameter if you want to force reply from
|
||||
specific users only. Targets:
|
||||
|
@ -64,14 +68,11 @@ class ForceReply(ReplyMarkup):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
force_reply: bool = True,
|
||||
selective: bool = False,
|
||||
input_field_placeholder: str = None,
|
||||
**_kwargs: Any,
|
||||
):
|
||||
# Required
|
||||
self.force_reply = bool(force_reply)
|
||||
# Optionals
|
||||
self.force_reply = True
|
||||
self.selective = bool(selective)
|
||||
self.input_field_placeholder = input_field_placeholder
|
||||
|
||||
|
|
|
@ -2067,7 +2067,7 @@ class Message(TelegramObject):
|
|||
|
||||
def edit_media(
|
||||
self,
|
||||
media: 'InputMedia' = None,
|
||||
media: 'InputMedia',
|
||||
reply_markup: InlineKeyboardMarkup = None,
|
||||
timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
|
@ -2088,14 +2088,14 @@ class Message(TelegramObject):
|
|||
behaviour is undocumented and might be changed by Telegram.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, if edited message is sent by the bot, the
|
||||
:class:`telegram.Message`: On success, if edited message is not an inline message, the
|
||||
edited Message is returned, otherwise ``True`` is returned.
|
||||
|
||||
"""
|
||||
return self.bot.edit_message_media(
|
||||
media=media,
|
||||
chat_id=self.chat_id,
|
||||
message_id=self.message_id,
|
||||
media=media,
|
||||
reply_markup=reply_markup,
|
||||
timeout=timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
|
|
|
@ -52,6 +52,8 @@ class EncryptedPassportElement(TelegramObject):
|
|||
"identity_card", "internal_passport", "address", "utility_bill", "bank_statement",
|
||||
"rental_agreement", "passport_registration", "temporary_registration", "phone_number",
|
||||
"email".
|
||||
hash (:obj:`str`): Base64-encoded element hash for using in
|
||||
:class:`telegram.PassportElementErrorUnspecified`.
|
||||
data (:class:`telegram.PersonalDetails` | :class:`telegram.IdDocument` | \
|
||||
:class:`telegram.ResidentialAddress` | :obj:`str`, optional):
|
||||
Decrypted or encrypted data, available for "personal_details", "passport",
|
||||
|
@ -77,8 +79,6 @@ class EncryptedPassportElement(TelegramObject):
|
|||
requested for "passport", "driver_license", "identity_card", "internal_passport",
|
||||
"utility_bill", "bank_statement", "rental_agreement", "passport_registration" and
|
||||
"temporary_registration" types.
|
||||
hash (:obj:`str`): Base64-encoded element hash for using in
|
||||
:class:`telegram.PassportElementErrorUnspecified`.
|
||||
bot (:class:`telegram.Bot`, optional): The Bot to use for instance methods.
|
||||
**kwargs (:obj:`dict`): Arbitrary keyword arguments.
|
||||
|
||||
|
@ -87,6 +87,8 @@ class EncryptedPassportElement(TelegramObject):
|
|||
"identity_card", "internal_passport", "address", "utility_bill", "bank_statement",
|
||||
"rental_agreement", "passport_registration", "temporary_registration", "phone_number",
|
||||
"email".
|
||||
hash (:obj:`str`): Base64-encoded element hash for using in
|
||||
:class:`telegram.PassportElementErrorUnspecified`.
|
||||
data (:class:`telegram.PersonalDetails` | :class:`telegram.IdDocument` | \
|
||||
:class:`telegram.ResidentialAddress` | :obj:`str`):
|
||||
Optional. Decrypted or encrypted data, available for "personal_details", "passport",
|
||||
|
@ -112,8 +114,6 @@ class EncryptedPassportElement(TelegramObject):
|
|||
requested for "passport", "driver_license", "identity_card", "internal_passport",
|
||||
"utility_bill", "bank_statement", "rental_agreement", "passport_registration" and
|
||||
"temporary_registration" types.
|
||||
hash (:obj:`str`): Base64-encoded element hash for using in
|
||||
:class:`telegram.PassportElementErrorUnspecified`.
|
||||
bot (:class:`telegram.Bot`): Optional. The Bot to use for instance methods.
|
||||
|
||||
"""
|
||||
|
@ -135,6 +135,7 @@ class EncryptedPassportElement(TelegramObject):
|
|||
def __init__(
|
||||
self,
|
||||
type: str, # pylint: disable=W0622
|
||||
hash: str, # pylint: disable=W0622
|
||||
data: PersonalDetails = None,
|
||||
phone_number: str = None,
|
||||
email: str = None,
|
||||
|
@ -143,7 +144,6 @@ class EncryptedPassportElement(TelegramObject):
|
|||
reverse_side: PassportFile = None,
|
||||
selfie: PassportFile = None,
|
||||
translation: List[PassportFile] = None,
|
||||
hash: str = None, # pylint: disable=W0622
|
||||
bot: 'Bot' = None,
|
||||
credentials: 'Credentials' = None, # pylint: disable=W0613
|
||||
**_kwargs: Any,
|
||||
|
|
|
@ -45,7 +45,6 @@ class PassportElementError(TelegramObject):
|
|||
|
||||
"""
|
||||
|
||||
# All subclasses of this class won't have _id_attrs in slots since it's added here.
|
||||
__slots__ = ('message', 'source', 'type')
|
||||
|
||||
def __init__(self, source: str, type: str, message: str, **_kwargs: Any):
|
||||
|
|
|
@ -72,7 +72,7 @@ class PassportFile(TelegramObject):
|
|||
file_id: str,
|
||||
file_unique_id: str,
|
||||
file_date: int,
|
||||
file_size: int = None,
|
||||
file_size: int,
|
||||
bot: 'Bot' = None,
|
||||
credentials: 'FileCredentials' = None,
|
||||
**_kwargs: Any,
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
"""This module contains objects related to Telegram voice chats."""
|
||||
|
||||
import datetime as dtm
|
||||
from typing import TYPE_CHECKING, Any, Optional, List
|
||||
from typing import TYPE_CHECKING, Optional, List
|
||||
|
||||
from telegram import TelegramObject, User
|
||||
from telegram.utils.helpers import from_timestamp, to_timestamp
|
||||
|
@ -40,7 +40,7 @@ class VoiceChatStarted(TelegramObject):
|
|||
|
||||
__slots__ = ()
|
||||
|
||||
def __init__(self, **_kwargs: Any): # skipcq: PTC-W0049
|
||||
def __init__(self, **_kwargs: object): # skipcq: PTC-W0049
|
||||
pass
|
||||
|
||||
|
||||
|
@ -66,7 +66,7 @@ class VoiceChatEnded(TelegramObject):
|
|||
|
||||
__slots__ = ('duration',)
|
||||
|
||||
def __init__(self, duration: int, **_kwargs: Any) -> None:
|
||||
def __init__(self, duration: int, **_kwargs: object) -> None:
|
||||
self.duration = int(duration) if duration is not None else None
|
||||
self._id_attrs = (self.duration,)
|
||||
|
||||
|
@ -83,25 +83,22 @@ class VoiceChatParticipantsInvited(TelegramObject):
|
|||
.. versionadded:: 13.4
|
||||
|
||||
Args:
|
||||
users (List[:class:`telegram.User`]): New members that
|
||||
users (List[:class:`telegram.User`], optional): New members that
|
||||
were invited to the voice chat.
|
||||
**kwargs (:obj:`dict`): Arbitrary keyword arguments.
|
||||
|
||||
Attributes:
|
||||
users (List[:class:`telegram.User`]): New members that
|
||||
users (List[:class:`telegram.User`]): Optional. New members that
|
||||
were invited to the voice chat.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ('users',)
|
||||
|
||||
def __init__(self, users: List[User], **_kwargs: Any) -> None:
|
||||
def __init__(self, users: List[User] = None, **_kwargs: object) -> None:
|
||||
self.users = users
|
||||
self._id_attrs = (self.users,)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(tuple(self.users))
|
||||
|
||||
@classmethod
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: 'Bot'
|
||||
|
@ -119,9 +116,13 @@ class VoiceChatParticipantsInvited(TelegramObject):
|
|||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
||||
data = super().to_dict()
|
||||
|
||||
data["users"] = [u.to_dict() for u in self.users]
|
||||
if self.users is not None:
|
||||
data["users"] = [u.to_dict() for u in self.users]
|
||||
return data
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(None) if self.users is None else hash(tuple(self.users))
|
||||
|
||||
|
||||
class VoiceChatScheduled(TelegramObject):
|
||||
"""This object represents a service message about a voice chat scheduled in the chat.
|
||||
|
@ -142,7 +143,7 @@ class VoiceChatScheduled(TelegramObject):
|
|||
|
||||
__slots__ = ('start_date',)
|
||||
|
||||
def __init__(self, start_date: dtm.datetime, **_kwargs: Any) -> None:
|
||||
def __init__(self, start_date: dtm.datetime, **_kwargs: object) -> None:
|
||||
self.start_date = start_date
|
||||
|
||||
self._id_attrs = (self.start_date,)
|
||||
|
|
|
@ -1368,7 +1368,7 @@ class TestBot:
|
|||
|
||||
monkeypatch.setattr(bot.request, 'post', assertion)
|
||||
|
||||
assert bot.set_webhook(drop_pending_updates=drop_pending_updates)
|
||||
assert bot.set_webhook('', drop_pending_updates=drop_pending_updates)
|
||||
assert bot.delete_webhook(drop_pending_updates=drop_pending_updates)
|
||||
|
||||
@flaky(3, 1)
|
||||
|
@ -1916,7 +1916,6 @@ class TestBot:
|
|||
def test_set_chat_description(self, bot, channel_id):
|
||||
assert bot.set_chat_description(channel_id, 'Time: ' + str(time.time()))
|
||||
|
||||
# TODO: Add bot to group to test there too
|
||||
@flaky(3, 1)
|
||||
def test_pin_and_unpin_message(self, bot, super_group_id):
|
||||
message1 = bot.send_message(super_group_id, text="test_pin_message_1")
|
||||
|
|
|
@ -34,6 +34,7 @@ def invite_link(creator):
|
|||
return ChatInviteLink(
|
||||
TestChatInviteLink.link,
|
||||
creator,
|
||||
TestChatInviteLink.creates_join_request,
|
||||
TestChatInviteLink.primary,
|
||||
TestChatInviteLink.revoked,
|
||||
expire_date=TestChatInviteLink.expire_date,
|
||||
|
@ -46,6 +47,7 @@ def invite_link(creator):
|
|||
class TestChatInviteLink:
|
||||
|
||||
link = "thisialink"
|
||||
creates_join_request = (False,)
|
||||
primary = True
|
||||
revoked = False
|
||||
expire_date = datetime.datetime.utcnow()
|
||||
|
@ -62,6 +64,7 @@ class TestChatInviteLink:
|
|||
json_dict = {
|
||||
'invite_link': self.link,
|
||||
'creator': creator.to_dict(),
|
||||
'creates_join_request': self.creates_join_request,
|
||||
'is_primary': self.primary,
|
||||
'is_revoked': self.revoked,
|
||||
}
|
||||
|
@ -70,6 +73,7 @@ class TestChatInviteLink:
|
|||
|
||||
assert invite_link.invite_link == self.link
|
||||
assert invite_link.creator == creator
|
||||
assert invite_link.creates_join_request == self.creates_join_request
|
||||
assert invite_link.is_primary == self.primary
|
||||
assert invite_link.is_revoked == self.revoked
|
||||
|
||||
|
@ -77,6 +81,7 @@ class TestChatInviteLink:
|
|||
json_dict = {
|
||||
'invite_link': self.link,
|
||||
'creator': creator.to_dict(),
|
||||
'creates_join_request': self.creates_join_request,
|
||||
'is_primary': self.primary,
|
||||
'is_revoked': self.revoked,
|
||||
'expire_date': to_timestamp(self.expire_date),
|
||||
|
@ -89,6 +94,7 @@ class TestChatInviteLink:
|
|||
|
||||
assert invite_link.invite_link == self.link
|
||||
assert invite_link.creator == creator
|
||||
assert invite_link.creates_join_request == self.creates_join_request
|
||||
assert invite_link.is_primary == self.primary
|
||||
assert invite_link.is_revoked == self.revoked
|
||||
assert pytest.approx(invite_link.expire_date == self.expire_date)
|
||||
|
@ -102,6 +108,7 @@ class TestChatInviteLink:
|
|||
assert isinstance(invite_link_dict, dict)
|
||||
assert invite_link_dict['creator'] == invite_link.creator.to_dict()
|
||||
assert invite_link_dict['invite_link'] == invite_link.invite_link
|
||||
assert invite_link_dict['creates_join_request'] == invite_link.creates_join_request
|
||||
assert invite_link_dict['is_primary'] == self.primary
|
||||
assert invite_link_dict['is_revoked'] == self.revoked
|
||||
assert invite_link_dict['expire_date'] == to_timestamp(self.expire_date)
|
||||
|
@ -110,19 +117,25 @@ class TestChatInviteLink:
|
|||
assert invite_link_dict['pending_join_request_count'] == self.pending_join_request_count
|
||||
|
||||
def test_equality(self):
|
||||
a = ChatInviteLink("link", User(1, '', False), True, True)
|
||||
b = ChatInviteLink("link", User(1, '', False), True, True)
|
||||
d = ChatInviteLink("link", User(2, '', False), False, True)
|
||||
d2 = ChatInviteLink("notalink", User(1, '', False), False, True)
|
||||
d3 = ChatInviteLink("notalink", User(1, '', False), True, True)
|
||||
e = User(1, '', False)
|
||||
a = ChatInviteLink("link", User(1, '', False), True, True, True)
|
||||
b = ChatInviteLink("link", User(1, '', False), True, True, True)
|
||||
c = ChatInviteLink("link", User(2, '', False), True, True, True)
|
||||
d1 = ChatInviteLink("link", User(1, '', False), False, True, True)
|
||||
d2 = ChatInviteLink("link", User(1, '', False), True, False, True)
|
||||
d3 = ChatInviteLink("link", User(1, '', False), True, True, False)
|
||||
e = ChatInviteLink("notalink", User(1, '', False), True, False, True)
|
||||
f = ChatInviteLink("notalink", User(1, '', False), True, True, True)
|
||||
g = User(1, '', False)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
assert a is not b
|
||||
|
||||
assert a != d
|
||||
assert hash(a) != hash(d)
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
||||
|
||||
assert a != d1
|
||||
assert hash(a) != hash(d1)
|
||||
|
||||
assert a != d2
|
||||
assert hash(a) != hash(d2)
|
||||
|
@ -132,3 +145,9 @@ class TestChatInviteLink:
|
|||
|
||||
assert a != e
|
||||
assert hash(a) != hash(e)
|
||||
|
||||
assert a != f
|
||||
assert hash(a) != hash(f)
|
||||
|
||||
assert a != g
|
||||
assert hash(a) != hash(g)
|
||||
|
|
|
@ -50,6 +50,7 @@ class TestChatJoinRequest:
|
|||
invite_link = ChatInviteLink(
|
||||
'https://invite.link',
|
||||
User(42, 'creator', False),
|
||||
creates_join_request=False,
|
||||
name='InviteLink',
|
||||
is_revoked=False,
|
||||
is_primary=False,
|
||||
|
|
|
@ -85,6 +85,7 @@ def chat_join_request(time, bot):
|
|||
invite_link=ChatInviteLink(
|
||||
'https://invite.link',
|
||||
User(42, 'creator', False),
|
||||
creates_join_request=False,
|
||||
name='InviteLink',
|
||||
is_revoked=False,
|
||||
is_primary=False,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
import datetime
|
||||
import inspect
|
||||
from copy import deepcopy
|
||||
|
||||
import pytest
|
||||
|
@ -34,202 +35,197 @@ from telegram import (
|
|||
Dice,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope='class')
|
||||
def user():
|
||||
return User(1, 'First name', False)
|
||||
ignored = ['self', '_kwargs']
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
scope="class",
|
||||
params=[
|
||||
(ChatMemberOwner, ChatMember.CREATOR),
|
||||
(ChatMemberAdministrator, ChatMember.ADMINISTRATOR),
|
||||
(ChatMemberMember, ChatMember.MEMBER),
|
||||
(ChatMemberRestricted, ChatMember.RESTRICTED),
|
||||
(ChatMemberLeft, ChatMember.LEFT),
|
||||
(ChatMemberBanned, ChatMember.KICKED),
|
||||
],
|
||||
ids=[
|
||||
ChatMember.CREATOR,
|
||||
ChatMember.ADMINISTRATOR,
|
||||
ChatMember.MEMBER,
|
||||
ChatMember.RESTRICTED,
|
||||
ChatMember.LEFT,
|
||||
ChatMember.KICKED,
|
||||
class CMDefaults:
|
||||
user = User(1, 'First name', False)
|
||||
custom_title: str = 'PTB'
|
||||
is_anonymous: bool = True
|
||||
until_date: datetime.datetime = to_timestamp(datetime.datetime.utcnow())
|
||||
can_be_edited: bool = False
|
||||
can_change_info: bool = True
|
||||
can_post_messages: bool = True
|
||||
can_edit_messages: bool = True
|
||||
can_delete_messages: bool = True
|
||||
can_invite_users: bool = True
|
||||
can_restrict_members: bool = True
|
||||
can_pin_messages: bool = True
|
||||
can_promote_members: bool = True
|
||||
can_send_messages: bool = True
|
||||
can_send_media_messages: bool = True
|
||||
can_send_polls: bool = True
|
||||
can_send_other_messages: bool = True
|
||||
can_add_web_page_previews: bool = True
|
||||
is_member: bool = True
|
||||
can_manage_chat: bool = True
|
||||
can_manage_voice_chats: bool = True
|
||||
|
||||
|
||||
def chat_member_owner():
|
||||
return ChatMemberOwner(CMDefaults.user, CMDefaults.is_anonymous, CMDefaults.custom_title)
|
||||
|
||||
|
||||
def chat_member_administrator():
|
||||
return ChatMemberAdministrator(
|
||||
CMDefaults.user,
|
||||
CMDefaults.can_be_edited,
|
||||
CMDefaults.is_anonymous,
|
||||
CMDefaults.can_manage_chat,
|
||||
CMDefaults.can_delete_messages,
|
||||
CMDefaults.can_manage_voice_chats,
|
||||
CMDefaults.can_restrict_members,
|
||||
CMDefaults.can_promote_members,
|
||||
CMDefaults.can_change_info,
|
||||
CMDefaults.can_invite_users,
|
||||
CMDefaults.can_post_messages,
|
||||
CMDefaults.can_edit_messages,
|
||||
CMDefaults.can_pin_messages,
|
||||
CMDefaults.custom_title,
|
||||
)
|
||||
|
||||
|
||||
def chat_member_member():
|
||||
return ChatMemberMember(CMDefaults.user)
|
||||
|
||||
|
||||
def chat_member_restricted():
|
||||
return ChatMemberRestricted(
|
||||
CMDefaults.user,
|
||||
CMDefaults.is_member,
|
||||
CMDefaults.can_change_info,
|
||||
CMDefaults.can_invite_users,
|
||||
CMDefaults.can_pin_messages,
|
||||
CMDefaults.can_send_messages,
|
||||
CMDefaults.can_send_media_messages,
|
||||
CMDefaults.can_send_polls,
|
||||
CMDefaults.can_send_other_messages,
|
||||
CMDefaults.can_add_web_page_previews,
|
||||
CMDefaults.until_date,
|
||||
)
|
||||
|
||||
|
||||
def chat_member_left():
|
||||
return ChatMemberLeft(CMDefaults.user)
|
||||
|
||||
|
||||
def chat_member_banned():
|
||||
return ChatMemberBanned(CMDefaults.user, CMDefaults.until_date)
|
||||
|
||||
|
||||
def make_json_dict(instance: ChatMember, include_optional_args: bool = False) -> dict:
|
||||
"""Used to make the json dict which we use for testing de_json. Similar to iter_args()"""
|
||||
json_dict = {'status': instance.status}
|
||||
sig = inspect.signature(instance.__class__.__init__)
|
||||
|
||||
for param in sig.parameters.values():
|
||||
if param.name in ignored: # ignore irrelevant params
|
||||
continue
|
||||
|
||||
val = getattr(instance, param.name)
|
||||
# Compulsory args-
|
||||
if param.default is inspect.Parameter.empty:
|
||||
if hasattr(val, 'to_dict'): # convert the user object or any future ones to dict.
|
||||
val = val.to_dict()
|
||||
json_dict[param.name] = val
|
||||
|
||||
# If we want to test all args (for de_json)-
|
||||
elif param.default is not inspect.Parameter.empty and include_optional_args:
|
||||
json_dict[param.name] = val
|
||||
return json_dict
|
||||
|
||||
|
||||
def iter_args(instance: ChatMember, de_json_inst: ChatMember, include_optional: bool = False):
|
||||
"""
|
||||
We accept both the regular instance and de_json created instance and iterate over them for
|
||||
easy one line testing later one.
|
||||
"""
|
||||
yield instance.status, de_json_inst.status # yield this here cause it's not available in sig.
|
||||
|
||||
sig = inspect.signature(instance.__class__.__init__)
|
||||
for param in sig.parameters.values():
|
||||
if param.name in ignored:
|
||||
continue
|
||||
inst_at, json_at = getattr(instance, param.name), getattr(de_json_inst, param.name)
|
||||
if isinstance(json_at, datetime.datetime): # Convert datetime to int
|
||||
json_at = to_timestamp(json_at)
|
||||
if param.default is not inspect.Parameter.empty and include_optional:
|
||||
yield inst_at, json_at
|
||||
elif param.default is inspect.Parameter.empty:
|
||||
yield inst_at, json_at
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def chat_member_type(request):
|
||||
return request.param()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"chat_member_type",
|
||||
[
|
||||
chat_member_owner,
|
||||
chat_member_administrator,
|
||||
chat_member_member,
|
||||
chat_member_restricted,
|
||||
chat_member_left,
|
||||
chat_member_banned,
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
def chat_member_class_and_status(request):
|
||||
return request.param
|
||||
|
||||
|
||||
@pytest.fixture(scope='class')
|
||||
def chat_member_types(chat_member_class_and_status, user):
|
||||
return chat_member_class_and_status[0](status=chat_member_class_and_status[1], user=user)
|
||||
|
||||
|
||||
class TestChatMember:
|
||||
def test_slot_behaviour(self, chat_member_types, mro_slots):
|
||||
for attr in chat_member_types.__slots__:
|
||||
assert getattr(chat_member_types, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
||||
assert len(mro_slots(chat_member_types)) == len(
|
||||
set(mro_slots(chat_member_types))
|
||||
), "duplicate slot"
|
||||
|
||||
def test_de_json_required_args(self, bot, chat_member_class_and_status, user):
|
||||
cls = chat_member_class_and_status[0]
|
||||
status = chat_member_class_and_status[1]
|
||||
class TestChatMemberTypes:
|
||||
def test_slot_behaviour(self, chat_member_type, mro_slots):
|
||||
inst = chat_member_type
|
||||
for attr in inst.__slots__:
|
||||
assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
||||
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
||||
|
||||
def test_de_json_required_args(self, bot, chat_member_type):
|
||||
cls = chat_member_type.__class__
|
||||
assert cls.de_json({}, bot) is None
|
||||
|
||||
json_dict = {'status': status, 'user': user.to_dict()}
|
||||
chat_member_type = ChatMember.de_json(json_dict, bot)
|
||||
json_dict = make_json_dict(chat_member_type)
|
||||
const_chat_member = ChatMember.de_json(json_dict, bot)
|
||||
|
||||
assert isinstance(chat_member_type, ChatMember)
|
||||
assert isinstance(chat_member_type, cls)
|
||||
assert chat_member_type.status == status
|
||||
assert chat_member_type.user == user
|
||||
assert isinstance(const_chat_member, ChatMember)
|
||||
assert isinstance(const_chat_member, cls)
|
||||
for chat_mem_type_at, const_chat_mem_at in iter_args(chat_member_type, const_chat_member):
|
||||
assert chat_mem_type_at == const_chat_mem_at
|
||||
|
||||
def test_de_json_all_args(self, bot, chat_member_class_and_status, user):
|
||||
cls = chat_member_class_and_status[0]
|
||||
status = chat_member_class_and_status[1]
|
||||
time = datetime.datetime.utcnow()
|
||||
def test_de_json_all_args(self, bot, chat_member_type):
|
||||
json_dict = make_json_dict(chat_member_type, include_optional_args=True)
|
||||
const_chat_member = ChatMember.de_json(json_dict, bot)
|
||||
|
||||
json_dict = {
|
||||
'user': user.to_dict(),
|
||||
'status': status,
|
||||
'custom_title': 'PTB',
|
||||
'is_anonymous': True,
|
||||
'until_date': to_timestamp(time),
|
||||
'can_be_edited': False,
|
||||
'can_change_info': True,
|
||||
'can_post_messages': False,
|
||||
'can_edit_messages': True,
|
||||
'can_delete_messages': True,
|
||||
'can_invite_users': False,
|
||||
'can_restrict_members': True,
|
||||
'can_pin_messages': False,
|
||||
'can_promote_members': True,
|
||||
'can_send_messages': False,
|
||||
'can_send_media_messages': True,
|
||||
'can_send_polls': False,
|
||||
'can_send_other_messages': True,
|
||||
'can_add_web_page_previews': False,
|
||||
'can_manage_chat': True,
|
||||
'can_manage_voice_chats': True,
|
||||
}
|
||||
chat_member_type = ChatMember.de_json(json_dict, bot)
|
||||
assert isinstance(const_chat_member, ChatMember)
|
||||
assert isinstance(const_chat_member, chat_member_type.__class__)
|
||||
for c_mem_type_at, const_c_mem_at in iter_args(chat_member_type, const_chat_member, True):
|
||||
assert c_mem_type_at == const_c_mem_at
|
||||
|
||||
assert isinstance(chat_member_type, ChatMember)
|
||||
assert isinstance(chat_member_type, cls)
|
||||
assert chat_member_type.user == user
|
||||
assert chat_member_type.status == status
|
||||
if chat_member_type.custom_title is not None:
|
||||
assert chat_member_type.custom_title == 'PTB'
|
||||
assert type(chat_member_type) in {ChatMemberOwner, ChatMemberAdministrator}
|
||||
if chat_member_type.is_anonymous is not None:
|
||||
assert chat_member_type.is_anonymous is True
|
||||
assert type(chat_member_type) in {ChatMemberOwner, ChatMemberAdministrator}
|
||||
if chat_member_type.until_date is not None:
|
||||
assert type(chat_member_type) in {ChatMemberBanned, ChatMemberRestricted}
|
||||
if chat_member_type.can_be_edited is not None:
|
||||
assert chat_member_type.can_be_edited is False
|
||||
assert type(chat_member_type) == ChatMemberAdministrator
|
||||
if chat_member_type.can_change_info is not None:
|
||||
assert chat_member_type.can_change_info is True
|
||||
assert type(chat_member_type) in {ChatMemberAdministrator, ChatMemberRestricted}
|
||||
if chat_member_type.can_post_messages is not None:
|
||||
assert chat_member_type.can_post_messages is False
|
||||
assert type(chat_member_type) == ChatMemberAdministrator
|
||||
if chat_member_type.can_edit_messages is not None:
|
||||
assert chat_member_type.can_edit_messages is True
|
||||
assert type(chat_member_type) == ChatMemberAdministrator
|
||||
if chat_member_type.can_delete_messages is not None:
|
||||
assert chat_member_type.can_delete_messages is True
|
||||
assert type(chat_member_type) == ChatMemberAdministrator
|
||||
if chat_member_type.can_invite_users is not None:
|
||||
assert chat_member_type.can_invite_users is False
|
||||
assert type(chat_member_type) in {ChatMemberAdministrator, ChatMemberRestricted}
|
||||
if chat_member_type.can_restrict_members is not None:
|
||||
assert chat_member_type.can_restrict_members is True
|
||||
assert type(chat_member_type) == ChatMemberAdministrator
|
||||
if chat_member_type.can_pin_messages is not None:
|
||||
assert chat_member_type.can_pin_messages is False
|
||||
assert type(chat_member_type) in {ChatMemberAdministrator, ChatMemberRestricted}
|
||||
if chat_member_type.can_promote_members is not None:
|
||||
assert chat_member_type.can_promote_members is True
|
||||
assert type(chat_member_type) == ChatMemberAdministrator
|
||||
if chat_member_type.can_send_messages is not None:
|
||||
assert chat_member_type.can_send_messages is False
|
||||
assert type(chat_member_type) == ChatMemberRestricted
|
||||
if chat_member_type.can_send_media_messages is not None:
|
||||
assert chat_member_type.can_send_media_messages is True
|
||||
assert type(chat_member_type) == ChatMemberRestricted
|
||||
if chat_member_type.can_send_polls is not None:
|
||||
assert chat_member_type.can_send_polls is False
|
||||
assert type(chat_member_type) == ChatMemberRestricted
|
||||
if chat_member_type.can_send_other_messages is not None:
|
||||
assert chat_member_type.can_send_other_messages is True
|
||||
assert type(chat_member_type) == ChatMemberRestricted
|
||||
if chat_member_type.can_add_web_page_previews is not None:
|
||||
assert chat_member_type.can_add_web_page_previews is False
|
||||
assert type(chat_member_type) == ChatMemberRestricted
|
||||
if chat_member_type.can_manage_chat is not None:
|
||||
assert chat_member_type.can_manage_chat is True
|
||||
assert type(chat_member_type) == ChatMemberAdministrator
|
||||
if chat_member_type.can_manage_voice_chats is not None:
|
||||
assert chat_member_type.can_manage_voice_chats is True
|
||||
assert type(chat_member_type) == ChatMemberAdministrator
|
||||
|
||||
def test_de_json_invalid_status(self, bot, user):
|
||||
json_dict = {'status': 'invalid', 'user': user.to_dict()}
|
||||
def test_de_json_invalid_status(self, chat_member_type, bot):
|
||||
json_dict = {'status': 'invalid', 'user': CMDefaults.user.to_dict()}
|
||||
chat_member_type = ChatMember.de_json(json_dict, bot)
|
||||
|
||||
assert type(chat_member_type) is ChatMember
|
||||
assert chat_member_type.status == 'invalid'
|
||||
|
||||
def test_de_json_subclass(self, chat_member_class_and_status, bot, chat_id, user):
|
||||
def test_de_json_subclass(self, chat_member_type, bot, chat_id):
|
||||
"""This makes sure that e.g. ChatMemberAdministrator(data, bot) never returns a
|
||||
ChatMemberKicked instance."""
|
||||
cls = chat_member_class_and_status[0]
|
||||
time = datetime.datetime.utcnow()
|
||||
json_dict = {
|
||||
'user': user.to_dict(),
|
||||
'status': 'status',
|
||||
'custom_title': 'PTB',
|
||||
'is_anonymous': True,
|
||||
'until_date': to_timestamp(time),
|
||||
'can_be_edited': False,
|
||||
'can_change_info': True,
|
||||
'can_post_messages': False,
|
||||
'can_edit_messages': True,
|
||||
'can_delete_messages': True,
|
||||
'can_invite_users': False,
|
||||
'can_restrict_members': True,
|
||||
'can_pin_messages': False,
|
||||
'can_promote_members': True,
|
||||
'can_send_messages': False,
|
||||
'can_send_media_messages': True,
|
||||
'can_send_polls': False,
|
||||
'can_send_other_messages': True,
|
||||
'can_add_web_page_previews': False,
|
||||
'can_manage_chat': True,
|
||||
'can_manage_voice_chats': True,
|
||||
}
|
||||
ChatMemberBanned instance."""
|
||||
cls = chat_member_type.__class__
|
||||
json_dict = make_json_dict(chat_member_type, True)
|
||||
assert type(cls.de_json(json_dict, bot)) is cls
|
||||
|
||||
def test_to_dict(self, chat_member_types, user):
|
||||
chat_member_dict = chat_member_types.to_dict()
|
||||
def test_to_dict(self, chat_member_type):
|
||||
chat_member_dict = chat_member_type.to_dict()
|
||||
|
||||
assert isinstance(chat_member_dict, dict)
|
||||
assert chat_member_dict['status'] == chat_member_types.status
|
||||
assert chat_member_dict['user'] == user.to_dict()
|
||||
assert chat_member_dict['status'] == chat_member_type.status
|
||||
assert chat_member_dict['user'] == chat_member_type.user.to_dict()
|
||||
|
||||
def test_equality(self, chat_member_types, user):
|
||||
a = ChatMember(status='status', user=user)
|
||||
b = ChatMember(status='status', user=user)
|
||||
c = chat_member_types
|
||||
d = deepcopy(chat_member_types)
|
||||
def test_equality(self, chat_member_type):
|
||||
a = ChatMember(status='status', user=CMDefaults.user)
|
||||
b = ChatMember(status='status', user=CMDefaults.user)
|
||||
c = chat_member_type
|
||||
d = deepcopy(chat_member_type)
|
||||
e = Dice(4, 'emoji')
|
||||
|
||||
assert a == b
|
||||
|
|
|
@ -22,7 +22,14 @@ import inspect
|
|||
import pytest
|
||||
import pytz
|
||||
|
||||
from telegram import User, ChatMember, Chat, ChatMemberUpdated, ChatInviteLink
|
||||
from telegram import (
|
||||
User,
|
||||
ChatMember,
|
||||
ChatMemberAdministrator,
|
||||
Chat,
|
||||
ChatMemberUpdated,
|
||||
ChatInviteLink,
|
||||
)
|
||||
from telegram.utils.helpers import to_timestamp
|
||||
|
||||
|
||||
|
@ -43,7 +50,19 @@ def old_chat_member(user):
|
|||
|
||||
@pytest.fixture(scope='class')
|
||||
def new_chat_member(user):
|
||||
return ChatMember(user, TestChatMemberUpdated.new_status)
|
||||
return ChatMemberAdministrator(
|
||||
user,
|
||||
TestChatMemberUpdated.new_status,
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope='class')
|
||||
|
@ -53,7 +72,7 @@ def time():
|
|||
|
||||
@pytest.fixture(scope='class')
|
||||
def invite_link(user):
|
||||
return ChatInviteLink('link', user, True, True)
|
||||
return ChatInviteLink('link', user, False, True, True)
|
||||
|
||||
|
||||
@pytest.fixture(scope='class')
|
||||
|
|
|
@ -26,6 +26,7 @@ from telegram import EncryptedPassportElement, PassportFile, PassportElementErro
|
|||
def encrypted_passport_element():
|
||||
return EncryptedPassportElement(
|
||||
TestEncryptedPassportElement.type_,
|
||||
'this is a hash',
|
||||
data=TestEncryptedPassportElement.data,
|
||||
phone_number=TestEncryptedPassportElement.phone_number,
|
||||
email=TestEncryptedPassportElement.email,
|
||||
|
@ -38,13 +39,14 @@ def encrypted_passport_element():
|
|||
|
||||
class TestEncryptedPassportElement:
|
||||
type_ = 'type'
|
||||
hash = 'this is a hash'
|
||||
data = 'data'
|
||||
phone_number = 'phone_number'
|
||||
email = 'email'
|
||||
files = [PassportFile('file_id', 50, 0)]
|
||||
front_side = PassportFile('file_id', 50, 0)
|
||||
reverse_side = PassportFile('file_id', 50, 0)
|
||||
selfie = PassportFile('file_id', 50, 0)
|
||||
files = [PassportFile('file_id', 50, 0, 25)]
|
||||
front_side = PassportFile('file_id', 50, 0, 25)
|
||||
reverse_side = PassportFile('file_id', 50, 0, 25)
|
||||
selfie = PassportFile('file_id', 50, 0, 25)
|
||||
|
||||
def test_slot_behaviour(self, encrypted_passport_element, mro_slots):
|
||||
inst = encrypted_passport_element
|
||||
|
@ -54,6 +56,7 @@ class TestEncryptedPassportElement:
|
|||
|
||||
def test_expected_values(self, encrypted_passport_element):
|
||||
assert encrypted_passport_element.type == self.type_
|
||||
assert encrypted_passport_element.hash == self.hash
|
||||
assert encrypted_passport_element.data == self.data
|
||||
assert encrypted_passport_element.phone_number == self.phone_number
|
||||
assert encrypted_passport_element.email == self.email
|
||||
|
@ -88,8 +91,8 @@ class TestEncryptedPassportElement:
|
|||
)
|
||||
|
||||
def test_equality(self):
|
||||
a = EncryptedPassportElement(self.type_, data=self.data)
|
||||
b = EncryptedPassportElement(self.type_, data=self.data)
|
||||
a = EncryptedPassportElement(self.type_, self.hash, data=self.data)
|
||||
b = EncryptedPassportElement(self.type_, self.hash, data=self.data)
|
||||
c = EncryptedPassportElement(self.data, '')
|
||||
d = PassportElementError('source', 'type', 'message')
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ from telegram import ForceReply, ReplyKeyboardRemove
|
|||
@pytest.fixture(scope='class')
|
||||
def force_reply():
|
||||
return ForceReply(
|
||||
TestForceReply.force_reply,
|
||||
TestForceReply.selective,
|
||||
TestForceReply.input_field_placeholder,
|
||||
)
|
||||
|
@ -62,16 +61,16 @@ class TestForceReply:
|
|||
assert force_reply_dict['input_field_placeholder'] == force_reply.input_field_placeholder
|
||||
|
||||
def test_equality(self):
|
||||
a = ForceReply(True, False)
|
||||
b = ForceReply(False, False)
|
||||
c = ForceReply(True, True)
|
||||
a = ForceReply(True, 'test')
|
||||
b = ForceReply(False, 'pass')
|
||||
c = ForceReply(True)
|
||||
d = ReplyKeyboardRemove()
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
assert a != b
|
||||
assert hash(a) != hash(b)
|
||||
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
||||
assert a == c
|
||||
assert hash(a) == hash(c)
|
||||
|
||||
assert a != d
|
||||
assert hash(a) != hash(d)
|
||||
|
|
|
@ -643,9 +643,9 @@ class TestSendMediaGroup:
|
|||
message = default_bot.send_photo(chat_id, photo)
|
||||
|
||||
message = default_bot.edit_message_media(
|
||||
build_media(parse_mode=ParseMode.HTML, med_type=media_type),
|
||||
message.chat_id,
|
||||
message.message_id,
|
||||
media=build_media(parse_mode=ParseMode.HTML, med_type=media_type),
|
||||
)
|
||||
assert message.caption == test_caption
|
||||
assert message.caption_entities == test_entities
|
||||
|
@ -654,9 +654,9 @@ class TestSendMediaGroup:
|
|||
message.edit_caption()
|
||||
|
||||
message = default_bot.edit_message_media(
|
||||
build_media(parse_mode=ParseMode.MARKDOWN_V2, med_type=media_type),
|
||||
message.chat_id,
|
||||
message.message_id,
|
||||
media=build_media(parse_mode=ParseMode.MARKDOWN_V2, med_type=media_type),
|
||||
)
|
||||
assert message.caption == test_caption
|
||||
assert message.caption_entities == test_entities
|
||||
|
@ -665,9 +665,9 @@ class TestSendMediaGroup:
|
|||
message.edit_caption()
|
||||
|
||||
message = default_bot.edit_message_media(
|
||||
build_media(parse_mode=None, med_type=media_type),
|
||||
message.chat_id,
|
||||
message.message_id,
|
||||
media=build_media(parse_mode=None, med_type=media_type),
|
||||
)
|
||||
assert message.caption == markdown_caption
|
||||
assert message.caption_entities == []
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
import os
|
||||
import inspect
|
||||
from typing import List
|
||||
|
||||
import certifi
|
||||
import pytest
|
||||
|
@ -40,6 +41,13 @@ IGNORED_PARAMETERS = {
|
|||
'kwargs',
|
||||
}
|
||||
|
||||
ignored_param_requirements = { # Ignore these since there's convenience params in them (eg. Venue)
|
||||
'send_location': {'latitude', 'longitude'},
|
||||
'edit_message_live_location': {'latitude', 'longitude'},
|
||||
'send_venue': {'latitude', 'longitude', 'title', 'address'},
|
||||
'send_contact': {'phone_number', 'first_name'},
|
||||
}
|
||||
|
||||
|
||||
def find_next_sibling_until(tag, name, until):
|
||||
for sibling in tag.next_siblings:
|
||||
|
@ -49,7 +57,8 @@ def find_next_sibling_until(tag, name, until):
|
|||
return sibling
|
||||
|
||||
|
||||
def parse_table(h4):
|
||||
def parse_table(h4) -> List[List[str]]:
|
||||
"""Parses the Telegram doc table and has an output of a 2D list."""
|
||||
table = find_next_sibling_until(h4, 'table', h4.find_next_sibling('h4'))
|
||||
if not table:
|
||||
return []
|
||||
|
@ -60,8 +69,8 @@ def parse_table(h4):
|
|||
|
||||
|
||||
def check_method(h4):
|
||||
name = h4.text
|
||||
method = getattr(telegram.Bot, name)
|
||||
name = h4.text # name of the method in telegram's docs.
|
||||
method = getattr(telegram.Bot, name) # Retrieve our lib method
|
||||
table = parse_table(h4)
|
||||
|
||||
# Check arguments based on source
|
||||
|
@ -71,8 +80,11 @@ def check_method(h4):
|
|||
for parameter in table:
|
||||
param = sig.parameters.get(parameter[0])
|
||||
assert param is not None, f"Parameter {parameter[0]} not found in {method.__name__}"
|
||||
|
||||
# TODO: Check type via docstring
|
||||
# TODO: Check if optional or required
|
||||
assert check_required_param(
|
||||
parameter, param.name, sig, method.__name__
|
||||
), f'Param {param.name!r} of method {method.__name__!r} requirement mismatch!'
|
||||
checked.append(parameter[0])
|
||||
|
||||
ignored = IGNORED_PARAMETERS.copy()
|
||||
|
@ -91,8 +103,6 @@ def check_method(h4):
|
|||
]
|
||||
):
|
||||
ignored |= {'filename'} # Convenience parameter
|
||||
elif name == 'setGameScore':
|
||||
ignored |= {'edit_message'} # TODO: Now deprecated, so no longer in telegrams docs
|
||||
elif name == 'sendContact':
|
||||
ignored |= {'contact'} # Added for ease of use
|
||||
elif name in ['sendLocation', 'editMessageLiveLocation']:
|
||||
|
@ -113,7 +123,7 @@ def check_object(h4):
|
|||
# Check arguments based on source. Makes sure to only check __init__'s signature & nothing else
|
||||
sig = inspect.signature(obj.__init__, follow_wrapped=True)
|
||||
|
||||
checked = []
|
||||
checked = set()
|
||||
for parameter in table:
|
||||
field = parameter[0]
|
||||
if field == 'from':
|
||||
|
@ -124,18 +134,22 @@ def check_object(h4):
|
|||
or name.startswith('BotCommandScope')
|
||||
) and field == 'type':
|
||||
continue
|
||||
elif (name.startswith('ChatMember')) and field == 'status':
|
||||
elif (name.startswith('ChatMember')) and field == 'status': # We autofill the status
|
||||
continue
|
||||
elif (
|
||||
name.startswith('PassportElementError') and field == 'source'
|
||||
) or field == 'remove_keyboard':
|
||||
continue
|
||||
elif name.startswith('ForceReply') and field == 'force_reply': # this param is always True
|
||||
continue
|
||||
|
||||
param = sig.parameters.get(field)
|
||||
assert param is not None, f"Attribute {field} not found in {obj.__name__}"
|
||||
# TODO: Check type via docstring
|
||||
# TODO: Check if optional or required
|
||||
checked.append(field)
|
||||
assert check_required_param(
|
||||
parameter, field, sig, obj.__name__
|
||||
), f"{obj.__name__!r} parameter {param.name!r} requirement mismatch"
|
||||
checked.add(field)
|
||||
|
||||
ignored = IGNORED_PARAMETERS.copy()
|
||||
if name == 'InputFile':
|
||||
|
@ -144,33 +158,8 @@ def check_object(h4):
|
|||
ignored |= {'id', 'type'} # attributes common to all subclasses
|
||||
if name == 'ChatMember':
|
||||
ignored |= {'user', 'status'} # attributes common to all subclasses
|
||||
if name == 'ChatMember':
|
||||
ignored |= {
|
||||
'can_add_web_page_previews', # for backwards compatibility
|
||||
'can_be_edited',
|
||||
'can_change_info',
|
||||
'can_delete_messages',
|
||||
'can_edit_messages',
|
||||
'can_invite_users',
|
||||
'can_manage_chat',
|
||||
'can_manage_voice_chats',
|
||||
'can_pin_messages',
|
||||
'can_post_messages',
|
||||
'can_promote_members',
|
||||
'can_restrict_members',
|
||||
'can_send_media_messages',
|
||||
'can_send_messages',
|
||||
'can_send_other_messages',
|
||||
'can_send_polls',
|
||||
'custom_title',
|
||||
'is_anonymous',
|
||||
'is_member',
|
||||
'until_date',
|
||||
}
|
||||
if name == 'BotCommandScope':
|
||||
ignored |= {'type'} # attributes common to all subclasses
|
||||
elif name == 'User':
|
||||
ignored |= {'type'} # TODO: Deprecation
|
||||
elif name in ('PassportFile', 'EncryptedPassportElement'):
|
||||
ignored |= {'credentials'}
|
||||
elif name == 'PassportElementError':
|
||||
|
@ -181,6 +170,26 @@ def check_object(h4):
|
|||
assert (sig.parameters.keys() ^ checked) - ignored == set()
|
||||
|
||||
|
||||
def check_required_param(
|
||||
param_desc: List[str], param_name: str, sig: inspect.Signature, method_or_obj_name: str
|
||||
) -> bool:
|
||||
"""Checks if the method/class parameter is a required/optional param as per Telegram docs."""
|
||||
if len(param_desc) == 4: # this means that there is a dedicated 'Required' column present.
|
||||
# Handle cases where we provide convenience intentionally-
|
||||
if param_name in ignored_param_requirements.get(method_or_obj_name, {}):
|
||||
return True
|
||||
is_required = True if param_desc[2] in {'Required', 'Yes'} else False
|
||||
is_ours_required = sig.parameters[param_name].default is inspect.Signature.empty
|
||||
return is_required is is_ours_required
|
||||
|
||||
if len(param_desc) == 3: # The docs mention the requirement in the description for classes...
|
||||
if param_name in ignored_param_requirements.get(method_or_obj_name, {}):
|
||||
return True
|
||||
is_required = False if param_desc[2].split('.', 1)[0] == 'Optional' else True
|
||||
is_ours_required = sig.parameters[param_name].default is inspect.Signature.empty
|
||||
return is_required is is_ours_required
|
||||
|
||||
|
||||
argvalues = []
|
||||
names = []
|
||||
http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED', ca_certs=certifi.where())
|
||||
|
|
|
@ -47,9 +47,11 @@ RAW_PASSPORT_DATA = {
|
|||
{
|
||||
'data': 'QRfzWcCN4WncvRO3lASG+d+c5gzqXtoCinQ1PgtYiZMKXCksx9eB9Ic1bOt8C/un9/XaX220PjJSO7Kuba+nXXC51qTsjqP9rnLKygnEIWjKrfiDdklzgcukpRzFSjiOAvhy86xFJZ1PfPSrFATy/Gp1RydLzbrBd2ZWxZqXrxcMoA0Q2UTTFXDoCYerEAiZoD69i79tB/6nkLBcUUvN5d52gKd/GowvxWqAAmdO6l1N7jlo6aWjdYQNBAK1KHbJdbRZMJLxC1MqMuZXAYrPoYBRKr5xAnxDTmPn/LEZKLc3gwwZyEgR5x7e9jp5heM6IEMmsv3O/6SUeEQs7P0iVuRSPLMJLfDdwns8Tl3fF2M4IxKVovjCaOVW+yHKsADDAYQPzzH2RcrWVD0TP5I64mzpK64BbTOq3qm3Hn51SV9uA/+LvdGbCp7VnzHx4EdUizHsVyilJULOBwvklsrDRvXMiWmh34ZSR6zilh051tMEcRf0I+Oe7pIxVJd/KKfYA2Z/eWVQTCn5gMuAInQNXFSqDIeIqBX+wca6kvOCUOXB7J2uRjTpLaC4DM9s/sNjSBvFixcGAngt+9oap6Y45rQc8ZJaNN/ALqEJAmkphW8=',
|
||||
'type': 'personal_details',
|
||||
'hash': 'What to put here?',
|
||||
},
|
||||
{
|
||||
'reverse_side': {
|
||||
'file_size': 32424112,
|
||||
'file_date': 1534074942,
|
||||
'file_id': 'DgADBAADNQQAAtoagFPf4wwmFZdmyQI',
|
||||
'file_unique_id': 'adc3145fd2e84d95b64d68eaa22aa33e',
|
||||
|
@ -82,6 +84,7 @@ RAW_PASSPORT_DATA = {
|
|||
'file_unique_id': 'd4e390cca57b4da5a65322b304762a12',
|
||||
},
|
||||
'data': 'eJUOFuY53QKmGqmBgVWlLBAQCUQJ79n405SX6M5aGFIIodOPQqnLYvMNqTwTrXGDlW+mVLZcbu+y8luLVO8WsJB/0SB7q5WaXn/IMt1G9lz5G/KMLIZG/x9zlnimsaQLg7u8srG6L4KZzv+xkbbHjZdETrxU8j0N/DoS4HvLMRSJAgeFUrY6v2YW9vSRg+fSxIqQy1jR2VKpzAT8OhOz7A==',
|
||||
'hash': 'We seriously need to improve this mess! took so long to debug!',
|
||||
},
|
||||
{
|
||||
'translation': [
|
||||
|
@ -113,12 +116,14 @@ RAW_PASSPORT_DATA = {
|
|||
},
|
||||
],
|
||||
'type': 'utility_bill',
|
||||
'hash': 'Wow over 30 minutes spent debugging passport stuff.',
|
||||
},
|
||||
{
|
||||
'data': 'j9SksVkSj128DBtZA+3aNjSFNirzv+R97guZaMgae4Gi0oDVNAF7twPR7j9VSmPedfJrEwL3O889Ei+a5F1xyLLyEI/qEBljvL70GFIhYGitS0JmNabHPHSZrjOl8b4s/0Z0Px2GpLO5siusTLQonimdUvu4UPjKquYISmlKEKhtmGATy+h+JDjNCYuOkhakeNw0Rk0BHgj0C3fCb7WZNQSyVb+2GTu6caR6eXf/AFwFp0TV3sRz3h0WIVPW8bna',
|
||||
'type': 'address',
|
||||
'hash': 'at least I get the pattern now',
|
||||
},
|
||||
{'email': 'fb3e3i47zt@dispostable.com', 'type': 'email'},
|
||||
{'email': 'fb3e3i47zt@dispostable.com', 'type': 'email', 'hash': 'this should be it.'},
|
||||
],
|
||||
}
|
||||
|
||||
|
@ -126,13 +131,18 @@ RAW_PASSPORT_DATA = {
|
|||
@pytest.fixture(scope='function')
|
||||
def all_passport_data():
|
||||
return [
|
||||
{'type': 'personal_details', 'data': RAW_PASSPORT_DATA['data'][0]['data']},
|
||||
{
|
||||
'type': 'personal_details',
|
||||
'data': RAW_PASSPORT_DATA['data'][0]['data'],
|
||||
'hash': 'what to put here?',
|
||||
},
|
||||
{
|
||||
'type': 'passport',
|
||||
'data': RAW_PASSPORT_DATA['data'][1]['data'],
|
||||
'front_side': RAW_PASSPORT_DATA['data'][1]['front_side'],
|
||||
'selfie': RAW_PASSPORT_DATA['data'][1]['selfie'],
|
||||
'translation': RAW_PASSPORT_DATA['data'][1]['translation'],
|
||||
'hash': 'more data arghh',
|
||||
},
|
||||
{
|
||||
'type': 'internal_passport',
|
||||
|
@ -140,6 +150,7 @@ def all_passport_data():
|
|||
'front_side': RAW_PASSPORT_DATA['data'][1]['front_side'],
|
||||
'selfie': RAW_PASSPORT_DATA['data'][1]['selfie'],
|
||||
'translation': RAW_PASSPORT_DATA['data'][1]['translation'],
|
||||
'hash': 'more data arghh',
|
||||
},
|
||||
{
|
||||
'type': 'driver_license',
|
||||
|
@ -148,6 +159,7 @@ def all_passport_data():
|
|||
'reverse_side': RAW_PASSPORT_DATA['data'][1]['reverse_side'],
|
||||
'selfie': RAW_PASSPORT_DATA['data'][1]['selfie'],
|
||||
'translation': RAW_PASSPORT_DATA['data'][1]['translation'],
|
||||
'hash': 'more data arghh',
|
||||
},
|
||||
{
|
||||
'type': 'identity_card',
|
||||
|
@ -156,35 +168,49 @@ def all_passport_data():
|
|||
'reverse_side': RAW_PASSPORT_DATA['data'][1]['reverse_side'],
|
||||
'selfie': RAW_PASSPORT_DATA['data'][1]['selfie'],
|
||||
'translation': RAW_PASSPORT_DATA['data'][1]['translation'],
|
||||
'hash': 'more data arghh',
|
||||
},
|
||||
{
|
||||
'type': 'utility_bill',
|
||||
'files': RAW_PASSPORT_DATA['data'][2]['files'],
|
||||
'translation': RAW_PASSPORT_DATA['data'][2]['translation'],
|
||||
'hash': 'more data arghh',
|
||||
},
|
||||
{
|
||||
'type': 'bank_statement',
|
||||
'files': RAW_PASSPORT_DATA['data'][2]['files'],
|
||||
'translation': RAW_PASSPORT_DATA['data'][2]['translation'],
|
||||
'hash': 'more data arghh',
|
||||
},
|
||||
{
|
||||
'type': 'rental_agreement',
|
||||
'files': RAW_PASSPORT_DATA['data'][2]['files'],
|
||||
'translation': RAW_PASSPORT_DATA['data'][2]['translation'],
|
||||
'hash': 'more data arghh',
|
||||
},
|
||||
{
|
||||
'type': 'passport_registration',
|
||||
'files': RAW_PASSPORT_DATA['data'][2]['files'],
|
||||
'translation': RAW_PASSPORT_DATA['data'][2]['translation'],
|
||||
'hash': 'more data arghh',
|
||||
},
|
||||
{
|
||||
'type': 'temporary_registration',
|
||||
'files': RAW_PASSPORT_DATA['data'][2]['files'],
|
||||
'translation': RAW_PASSPORT_DATA['data'][2]['translation'],
|
||||
'hash': 'more data arghh',
|
||||
},
|
||||
{
|
||||
'type': 'address',
|
||||
'data': RAW_PASSPORT_DATA['data'][3]['data'],
|
||||
'hash': 'more data arghh',
|
||||
},
|
||||
{'type': 'email', 'email': 'fb3e3i47zt@dispostable.com', 'hash': 'more data arghh'},
|
||||
{
|
||||
'type': 'phone_number',
|
||||
'phone_number': 'fb3e3i47zt@dispostable.com',
|
||||
'hash': 'more data arghh',
|
||||
},
|
||||
{'type': 'address', 'data': RAW_PASSPORT_DATA['data'][3]['data']},
|
||||
{'type': 'email', 'email': 'fb3e3i47zt@dispostable.com'},
|
||||
{'type': 'phone_number', 'phone_number': 'fb3e3i47zt@dispostable.com'},
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ from telegram import (
|
|||
Poll,
|
||||
PollOption,
|
||||
ChatMemberUpdated,
|
||||
ChatMember,
|
||||
ChatMemberOwner,
|
||||
ChatJoinRequest,
|
||||
)
|
||||
from telegram.poll import PollAnswer
|
||||
|
@ -44,8 +44,8 @@ chat_member_updated = ChatMemberUpdated(
|
|||
Chat(1, 'chat'),
|
||||
User(1, '', False),
|
||||
from_timestamp(int(time.time())),
|
||||
ChatMember(User(1, '', False), ChatMember.CREATOR),
|
||||
ChatMember(User(1, '', False), ChatMember.CREATOR),
|
||||
ChatMemberOwner(User(1, '', False), True),
|
||||
ChatMemberOwner(User(1, '', False), True),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ class TestVoiceChatEnded:
|
|||
|
||||
|
||||
class TestVoiceChatParticipantsInvited:
|
||||
def test_slot_behaviour(self, mro_slots):
|
||||
def test_slot_behaviour(self, mro_slots, user1):
|
||||
action = VoiceChatParticipantsInvited([user1])
|
||||
for attr in action.__slots__:
|
||||
assert getattr(action, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
||||
|
@ -124,7 +124,7 @@ class TestVoiceChatParticipantsInvited:
|
|||
a = VoiceChatParticipantsInvited([user1])
|
||||
b = VoiceChatParticipantsInvited([user1])
|
||||
c = VoiceChatParticipantsInvited([user1, user2])
|
||||
d = VoiceChatParticipantsInvited([user2])
|
||||
d = VoiceChatParticipantsInvited(None)
|
||||
e = VoiceChatStarted()
|
||||
|
||||
assert a == b
|
||||
|
|
Loading…
Add table
Reference in a new issue