mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2024-11-24 16:17:37 +01:00
API 7.1 (#4118)
Co-authored-by: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com> Co-authored-by: Harshil <37377066+harshil21@users.noreply.github.com>
This commit is contained in:
parent
26f943771b
commit
099ab5d9fa
29 changed files with 580 additions and 98 deletions
7
.github/workflows/docs.yml
vendored
7
.github/workflows/docs.yml
vendored
|
@ -1,13 +1,12 @@
|
|||
name: Test Documentation Build
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- doc-fixes
|
||||
paths:
|
||||
- telegram/**
|
||||
- docs/**
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- doc-fixes
|
||||
|
||||
jobs:
|
||||
test-sphinx-build:
|
||||
|
|
5
.github/workflows/test_official.yml
vendored
5
.github/workflows/test_official.yml
vendored
|
@ -1,8 +1,9 @@
|
|||
name: Bot API Tests
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- telegram/**
|
||||
- tests/**
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
|
4
.github/workflows/type_completeness.yml
vendored
4
.github/workflows/type_completeness.yml
vendored
|
@ -1,8 +1,8 @@
|
|||
name: Check Type Completeness
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- telegram/**
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
|
7
.github/workflows/unit_tests.yml
vendored
7
.github/workflows/unit_tests.yml
vendored
|
@ -1,13 +1,12 @@
|
|||
name: Unit Tests
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
paths:
|
||||
- telegram/**
|
||||
- tests/**
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
schedule:
|
||||
# Run monday and friday morning at 03:07 - odd time to spread load on GitHub Actions
|
||||
- cron: '7 3 * * 1,5'
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
:target: https://pypi.org/project/python-telegram-bot/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-7.0-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-7.1-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API versions
|
||||
|
||||
|
@ -93,7 +93,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju
|
|||
Telegram API support
|
||||
====================
|
||||
|
||||
All types and methods of the Telegram Bot API **7.0** are supported.
|
||||
All types and methods of the Telegram Bot API **7.1** are supported.
|
||||
|
||||
Installing
|
||||
==========
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
:target: https://pypi.org/project/python-telegram-bot-raw/
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-7.0-blue?logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Bot%20API-7.1-blue?logo=telegram
|
||||
:target: https://core.telegram.org/bots/api-changelog
|
||||
:alt: Supported Bot API versions
|
||||
|
||||
|
@ -89,7 +89,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju
|
|||
Telegram API support
|
||||
====================
|
||||
|
||||
All types and methods of the Telegram Bot API **7.0** are supported.
|
||||
All types and methods of the Telegram Bot API **7.1** are supported.
|
||||
|
||||
Installing
|
||||
==========
|
||||
|
|
|
@ -22,6 +22,7 @@ Available Types
|
|||
telegram.chat
|
||||
telegram.chatadministratorrights
|
||||
telegram.chatboost
|
||||
telegram.chatboostadded
|
||||
telegram.chatboostremoved
|
||||
telegram.chatboostsource
|
||||
telegram.chatboostsourcegiftcode
|
||||
|
|
6
docs/source/telegram.chatboostadded.rst
Normal file
6
docs/source/telegram.chatboostadded.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
ChatBoostAdded
|
||||
==============
|
||||
|
||||
.. autoclass:: telegram.ChatBoostAdded
|
||||
:members:
|
||||
:show-inheritance:
|
|
@ -77,3 +77,5 @@
|
|||
.. |reply_quote| replace:: If set to :obj:`True`, the reply is sent as an actual reply to this message. If ``reply_to_message_id`` is passed, this parameter will be ignored. Default: :obj:`True` in group chats and :obj:`False` in private chats.
|
||||
|
||||
.. |do_quote| replace:: If set to :obj:`True`, the replied message is quoted. For a dict, it must be the output of :meth:`~telegram.Message.build_reply_arguments` to specify exact ``reply_parameters``. If ``reply_to_message_id`` or ``reply_parameters`` are passed, this parameter will be ignored. Default: :obj:`True` in group chats and :obj:`False` in private chats.
|
||||
|
||||
.. |non_optional_story_argument| replace:: As of this version, this argument is now required. In accordance with our `stability policy <https://docs.python-telegram-bot.org/en/stable/stability_policy.html>`__, the signature will be kept as optional for now, though they are mandatory and an error will be raised if you don't pass it.
|
||||
|
|
|
@ -40,6 +40,7 @@ __all__ = (
|
|||
"Chat",
|
||||
"ChatAdministratorRights",
|
||||
"ChatBoost",
|
||||
"ChatBoostAdded",
|
||||
"ChatBoostRemoved",
|
||||
"ChatBoostSource",
|
||||
"ChatBoostSourceGiftCode",
|
||||
|
@ -242,6 +243,7 @@ from ._chat import Chat
|
|||
from ._chatadministratorrights import ChatAdministratorRights
|
||||
from ._chatboost import (
|
||||
ChatBoost,
|
||||
ChatBoostAdded,
|
||||
ChatBoostRemoved,
|
||||
ChatBoostSource,
|
||||
ChatBoostSourceGiftCode,
|
||||
|
|
|
@ -5250,10 +5250,10 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
user_id (:obj:`int`): Unique identifier of the target user.
|
||||
is_anonymous (:obj:`bool`, optional): Pass :obj:`True`, if the administrator's presence
|
||||
in the chat is hidden.
|
||||
can_manage_chat (:obj:`bool`, optional): Pass :obj:`True`, if the administrator can
|
||||
access the chat event log, chat statistics, boost list in channels, see channel
|
||||
members, report spam messages, see anonymous administrators in supergroups and
|
||||
ignore slow mode. Implied by any other administrator privilege.
|
||||
can_manage_chat (:obj:`bool`, optional): Pass :obj:`True`, if the administrator can
|
||||
access the chat event log, get boost list, see hidden supergroup and channel
|
||||
members, report spam messages and ignore slow mode. Implied by any other
|
||||
administrator privilege.
|
||||
|
||||
.. versionadded:: 13.4
|
||||
|
||||
|
@ -5285,15 +5285,15 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
|||
|
||||
.. versionadded:: 20.0
|
||||
can_post_stories (:obj:`bool`, optional): Pass :obj:`True`, if the administrator can
|
||||
post stories in the channel; channels only.
|
||||
post stories to the chat.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_edit_stories (:obj:`bool`, optional): Pass :obj:`True`, if the administrator can
|
||||
edit stories posted by other users; channels only.
|
||||
edit stories posted by other users.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_delete_stories (:obj:`bool`, optional): Pass :obj:`True`, if the administrator can
|
||||
delete stories posted by other users; channels only.
|
||||
delete stories posted by other users.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
|
||||
|
|
|
@ -219,6 +219,16 @@ class Chat(TelegramObject):
|
|||
:meth:`telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
unrestrict_boost_count (:obj:`int`, optional): For supergroups, the minimum number of
|
||||
boosts that a non-administrator user needs to add in order to ignore slow mode and chat
|
||||
permissions. Returned only in :meth:`telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
custom_emoji_sticker_set_name (:obj:`str`, optional): For supergroups, the name of the
|
||||
group's custom emoji sticker set. Custom emoji from this set can be used by all users
|
||||
and bots in the group. Returned only in :meth:`telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
id (:obj:`int`): Unique identifier for this chat. This number may be greater than 32 bits
|
||||
|
@ -352,6 +362,16 @@ class Chat(TelegramObject):
|
|||
:meth:`telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
unrestrict_boost_count (:obj:`int`): Optional. For supergroups, the minimum number of
|
||||
boosts that a non-administrator user needs to add in order to ignore slow mode and chat
|
||||
permissions. Returned only in :meth:`telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
custom_emoji_sticker_set_name (:obj:`str`): Optional. For supergroups, the name of the
|
||||
group's custom emoji sticker set. Custom emoji from this set can be used by all users
|
||||
and bots in the group. Returned only in :meth:`telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
.. _topics: https://telegram.org/blog/topics-in-groups-collectible-usernames#topics-in-groups
|
||||
.. _accent colors: https://core.telegram.org/bots/api#accent-colors
|
||||
|
@ -364,6 +384,7 @@ class Chat(TelegramObject):
|
|||
"background_custom_emoji_id",
|
||||
"bio",
|
||||
"can_set_sticker_set",
|
||||
"custom_emoji_sticker_set_name",
|
||||
"description",
|
||||
"emoji_status_custom_emoji_id",
|
||||
"emoji_status_expiration_date",
|
||||
|
@ -392,6 +413,7 @@ class Chat(TelegramObject):
|
|||
"sticker_set_name",
|
||||
"title",
|
||||
"type",
|
||||
"unrestrict_boost_count",
|
||||
"username",
|
||||
)
|
||||
|
||||
|
@ -446,6 +468,8 @@ class Chat(TelegramObject):
|
|||
profile_accent_color_id: Optional[int] = None,
|
||||
profile_background_custom_emoji_id: Optional[str] = None,
|
||||
has_visible_history: Optional[bool] = None,
|
||||
unrestrict_boost_count: Optional[int] = None,
|
||||
custom_emoji_sticker_set_name: Optional[str] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
|
@ -493,6 +517,8 @@ class Chat(TelegramObject):
|
|||
self.background_custom_emoji_id: Optional[str] = background_custom_emoji_id
|
||||
self.profile_accent_color_id: Optional[int] = profile_accent_color_id
|
||||
self.profile_background_custom_emoji_id: Optional[str] = profile_background_custom_emoji_id
|
||||
self.unrestrict_boost_count: Optional[int] = unrestrict_boost_count
|
||||
self.custom_emoji_sticker_set_name: Optional[str] = custom_emoji_sticker_set_name
|
||||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
|
|
|
@ -47,9 +47,8 @@ class ChatAdministratorRights(TelegramObject):
|
|||
Args:
|
||||
is_anonymous (:obj:`bool`): :obj:`True`, if the user's presence in the chat is hidden.
|
||||
can_manage_chat (:obj:`bool`): :obj:`True`, if the administrator can access the chat event
|
||||
log, chat statistics, boost list in channels, see channel members, report spam
|
||||
messages, see anonymous administrators in supergroups and ignore slow mode.
|
||||
Implied by any other administrator privilege.
|
||||
log, get boost list, see hidden supergroup and channel members, report spam messages
|
||||
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_video_chats (:obj:`bool`): :obj:`True`, if the administrator can manage video
|
||||
|
@ -70,18 +69,24 @@ class ChatAdministratorRights(TelegramObject):
|
|||
messages of other users.
|
||||
can_pin_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed to pin
|
||||
messages; groups and supergroups only.
|
||||
can_post_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can post
|
||||
stories in the channel; channels only.
|
||||
can_post_stories (:obj:`bool`): :obj:`True`, if the administrator can post
|
||||
stories to the chat.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_edit_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can edit
|
||||
stories posted by other users; channels only.
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
|non_optional_story_argument|
|
||||
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit
|
||||
stories posted by other users.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_delete_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can delete
|
||||
stories posted by other users; channels only.
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
|non_optional_story_argument|
|
||||
can_delete_stories (:obj:`bool`): :obj:`True`, if the administrator can delete
|
||||
stories posted by other users.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
|non_optional_story_argument|
|
||||
can_manage_topics (:obj:`bool`, optional): :obj:`True`, if the user is allowed
|
||||
to create, rename, close, and reopen forum topics; supergroups only.
|
||||
|
||||
|
@ -90,9 +95,8 @@ class ChatAdministratorRights(TelegramObject):
|
|||
Attributes:
|
||||
is_anonymous (:obj:`bool`): :obj:`True`, if the user's presence in the chat is hidden.
|
||||
can_manage_chat (:obj:`bool`): :obj:`True`, if the administrator can access the chat event
|
||||
log, chat statistics, boost list in channels, see channel members, report spam
|
||||
messages, see anonymous administrators in supergroups and ignore slow mode.
|
||||
Implied by any other administrator privilege.
|
||||
log, get boost list, see hidden supergroup and channel members, report spam messages
|
||||
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_video_chats (:obj:`bool`): :obj:`True`, if the administrator can manage video
|
||||
|
@ -113,18 +117,24 @@ class ChatAdministratorRights(TelegramObject):
|
|||
messages of other users.
|
||||
can_pin_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed to pin
|
||||
messages; groups and supergroups only.
|
||||
can_post_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can post
|
||||
stories in the channel; channels only.
|
||||
can_post_stories (:obj:`bool`): :obj:`True`, if the administrator can post
|
||||
stories to the chat.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_edit_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can edit
|
||||
stories posted by other users; channels only.
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
|non_optional_story_argument|
|
||||
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit
|
||||
stories posted by other users.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_delete_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can delete
|
||||
stories posted by other users; channels only.
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
|non_optional_story_argument|
|
||||
can_delete_stories (:obj:`bool`): :obj:`True`, if the administrator can delete
|
||||
stories posted by other users.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
|non_optional_story_argument|
|
||||
can_manage_topics (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
|
||||
to create, rename, close, and reopen forum topics; supergroups only.
|
||||
|
||||
|
@ -179,13 +189,19 @@ class ChatAdministratorRights(TelegramObject):
|
|||
self.can_promote_members: bool = can_promote_members
|
||||
self.can_change_info: bool = can_change_info
|
||||
self.can_invite_users: bool = can_invite_users
|
||||
# Not actually optionals but because of backwards compatability we pretend they are
|
||||
if can_post_stories is None or can_edit_stories is None or can_delete_stories is None:
|
||||
raise TypeError(
|
||||
"As of vNEXT.VERSION can_post_stories, can_edit_stories and can_delete_stories"
|
||||
" must be set in order to create this object."
|
||||
)
|
||||
self.can_post_stories: bool = can_post_stories
|
||||
self.can_edit_stories: bool = can_edit_stories
|
||||
self.can_delete_stories: bool = can_delete_stories
|
||||
# Optionals
|
||||
self.can_post_messages: Optional[bool] = can_post_messages
|
||||
self.can_edit_messages: Optional[bool] = can_edit_messages
|
||||
self.can_pin_messages: Optional[bool] = can_pin_messages
|
||||
self.can_post_stories: Optional[bool] = can_post_stories
|
||||
self.can_edit_stories: Optional[bool] = can_edit_stories
|
||||
self.can_delete_stories: Optional[bool] = can_delete_stories
|
||||
self.can_manage_topics: Optional[bool] = can_manage_topics
|
||||
|
||||
self._id_attrs = (
|
||||
|
|
|
@ -34,6 +34,39 @@ if TYPE_CHECKING:
|
|||
from telegram import Bot
|
||||
|
||||
|
||||
class ChatBoostAdded(TelegramObject):
|
||||
"""
|
||||
This object represents a service message about a user boosting a chat.
|
||||
|
||||
Objects of this class are comparable in terms of equality.
|
||||
Two objects of this class are considered equal, if their
|
||||
:attr:`boost_count` are equal.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Args:
|
||||
boost_count (:obj:`int`): Number of boosts added by the user.
|
||||
|
||||
Attributes:
|
||||
boost_count (:obj:`int`): Number of boosts added by the user.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("boost_count",)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
boost_count: int,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> None:
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.boost_count: int = boost_count
|
||||
self._id_attrs = (self.boost_count,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
|
||||
class ChatBoostSource(TelegramObject):
|
||||
"""
|
||||
Base class for Telegram ChatBoostSource objects. It can be one of:
|
||||
|
|
|
@ -197,9 +197,8 @@ class ChatMemberAdministrator(ChatMember):
|
|||
is allowed to edit administrator privileges of that user.
|
||||
is_anonymous (:obj:`bool`): :obj:`True`, if the user's
|
||||
presence in the chat is hidden.
|
||||
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
|
||||
can_manage_chat (:obj:`bool`): :obj:`True`, if the administrator can access the chat event
|
||||
log, get boost list, see hidden supergroup and channel members, report spam messages
|
||||
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.
|
||||
|
@ -225,18 +224,24 @@ class ChatMemberAdministrator(ChatMember):
|
|||
messages; channels only.
|
||||
can_pin_messages (:obj:`bool`, optional): :obj:`True`, if the user is allowed
|
||||
to pin messages; groups and supergroups only.
|
||||
can_post_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can post
|
||||
stories in the channel; channels only.
|
||||
can_post_stories (:obj:`bool`): :obj:`True`, if the administrator can post
|
||||
stories to the chat.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_edit_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can edit
|
||||
stories posted by other users; channels only.
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
|non_optional_story_argument|
|
||||
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit
|
||||
stories posted by other users.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_delete_stories (:obj:`bool`, optional): :obj:`True`, if the administrator can delete
|
||||
stories posted by other users; channels only.
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
|non_optional_story_argument|
|
||||
can_delete_stories (:obj:`bool`): :obj:`True`, if the administrator can delete
|
||||
stories posted by other users.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
|non_optional_story_argument|
|
||||
can_manage_topics (:obj:`bool`, optional): :obj:`True`, if the user is allowed
|
||||
to create, rename, close, and reopen forum topics; supergroups only.
|
||||
|
||||
|
@ -252,9 +257,8 @@ class ChatMemberAdministrator(ChatMember):
|
|||
is_anonymous (:obj:`bool`): :obj:`True`, if the user's
|
||||
presence in the chat is hidden.
|
||||
can_manage_chat (:obj:`bool`): :obj:`True`, if the administrator can access the chat event
|
||||
log, chat statistics, boost list in channels, see channel members, report spam
|
||||
messages, see anonymous administrators in supergroups and ignore slow mode.
|
||||
Implied by any other administrator privilege.
|
||||
log, get boost list, see hidden supergroup and channel members, report spam messages
|
||||
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_video_chats (:obj:`bool`): :obj:`True`, if the
|
||||
|
@ -279,18 +283,24 @@ class ChatMemberAdministrator(ChatMember):
|
|||
messages; channels only.
|
||||
can_pin_messages (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
|
||||
to pin messages; groups and supergroups only.
|
||||
can_post_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can post
|
||||
stories in the channel; channels only.
|
||||
can_post_stories (:obj:`bool`): :obj:`True`, if the administrator can post
|
||||
stories to the chat.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_edit_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can edit
|
||||
stories posted by other users; channels only.
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
|non_optional_story_argument|
|
||||
can_edit_stories (:obj:`bool`): :obj:`True`, if the administrator can edit
|
||||
stories posted by other users.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
can_delete_stories (:obj:`bool`): Optional. :obj:`True`, if the administrator can delete
|
||||
stories posted by other users; channels only.
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
|non_optional_story_argument|
|
||||
can_delete_stories (:obj:`bool`): :obj:`True`, if the administrator can delete
|
||||
stories posted by other users.
|
||||
|
||||
.. versionadded:: 20.6
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
|non_optional_story_argument|
|
||||
can_manage_topics (:obj:`bool`): Optional. :obj:`True`, if the user is allowed
|
||||
to create, rename, close, and reopen forum topics; supergroups only
|
||||
|
||||
|
@ -352,14 +362,21 @@ class ChatMemberAdministrator(ChatMember):
|
|||
self.can_promote_members: bool = can_promote_members
|
||||
self.can_change_info: bool = can_change_info
|
||||
self.can_invite_users: bool = can_invite_users
|
||||
# Not actually optionals but because of backwards compatability we pretend they are
|
||||
if can_post_stories is None or can_edit_stories is None or can_delete_stories is None:
|
||||
raise TypeError(
|
||||
"As of NEXT.VERSION can_post_stories, can_edit_stories and can_delete_stories "
|
||||
"must be set in order to create this object."
|
||||
)
|
||||
self.can_post_stories: bool = can_post_stories
|
||||
self.can_edit_stories: bool = can_edit_stories
|
||||
self.can_delete_stories: bool = can_delete_stories
|
||||
# Optionals
|
||||
self.can_post_messages: Optional[bool] = can_post_messages
|
||||
self.can_edit_messages: Optional[bool] = can_edit_messages
|
||||
self.can_pin_messages: Optional[bool] = can_pin_messages
|
||||
self.can_manage_topics: Optional[bool] = can_manage_topics
|
||||
self.custom_title: Optional[str] = custom_title
|
||||
self.can_post_stories: Optional[bool] = can_post_stories
|
||||
self.can_edit_stories: Optional[bool] = can_edit_stories
|
||||
self.can_delete_stories: Optional[bool] = can_delete_stories
|
||||
|
||||
|
||||
class ChatMemberMember(ChatMember):
|
||||
|
|
|
@ -24,6 +24,7 @@ from html import escape
|
|||
from typing import TYPE_CHECKING, Dict, List, Optional, Sequence, Tuple, TypedDict, Union
|
||||
|
||||
from telegram._chat import Chat
|
||||
from telegram._chatboost import ChatBoostAdded
|
||||
from telegram._dice import Dice
|
||||
from telegram._files.animation import Animation
|
||||
from telegram._files.audio import Audio
|
||||
|
@ -521,6 +522,18 @@ class Message(MaybeInaccessibleMessage):
|
|||
message for forwarded messages
|
||||
|
||||
.. versionadded:: 20.8
|
||||
reply_to_story (:class:`telegram.Story`, optional): For replies to a story, the original
|
||||
story.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
boost_added (:class:`telegram.ChatBoostAdded`, optional): Service message: user boosted
|
||||
the chat.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
sender_boost_count (:obj:`int`, optional): If the sender of the
|
||||
message boosted the chat, the number of boosts added by the user.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
Attributes:
|
||||
message_id (:obj:`int`): Unique message identifier inside this chat.
|
||||
|
@ -787,10 +800,22 @@ class Message(MaybeInaccessibleMessage):
|
|||
message, the quoted part of the message.
|
||||
|
||||
.. versionadded:: 20.8
|
||||
forward_origin (:class:`telegram.MessageOrigin`, optional): Information about the original
|
||||
forward_origin (:class:`telegram.MessageOrigin`): Optional. Information about the original
|
||||
message for forwarded messages
|
||||
|
||||
.. versionadded:: 20.8
|
||||
reply_to_story (:class:`telegram.Story`): Optional. For replies to a story, the original
|
||||
story.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
boost_added (:class:`telegram.ChatBoostAdded`): Optional. Service message: user boosted
|
||||
the chat.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
sender_boost_count (:obj:`int`): Optional. If the sender of the
|
||||
message boosted the chat, the number of boosts added by the user.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
|
||||
.. |custom_emoji_no_md1_support| replace:: Since custom emoji entities are not supported by
|
||||
:attr:`~telegram.constants.ParseMode.MARKDOWN`, this method now raises a
|
||||
|
@ -807,6 +832,7 @@ class Message(MaybeInaccessibleMessage):
|
|||
"animation",
|
||||
"audio",
|
||||
"author_signature",
|
||||
"boost_added",
|
||||
"caption",
|
||||
"caption_entities",
|
||||
"channel_chat_created",
|
||||
|
@ -857,6 +883,8 @@ class Message(MaybeInaccessibleMessage):
|
|||
"quote",
|
||||
"reply_markup",
|
||||
"reply_to_message",
|
||||
"reply_to_story",
|
||||
"sender_boost_count",
|
||||
"sender_chat",
|
||||
"sticker",
|
||||
"story",
|
||||
|
@ -953,6 +981,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
external_reply: Optional["ExternalReplyInfo"] = None,
|
||||
quote: Optional["TextQuote"] = None,
|
||||
forward_origin: Optional["MessageOrigin"] = None,
|
||||
reply_to_story: Optional[Story] = None,
|
||||
boost_added: Optional[ChatBoostAdded] = None,
|
||||
sender_boost_count: Optional[int] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
|
@ -1045,6 +1076,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
self.external_reply: Optional[ExternalReplyInfo] = external_reply
|
||||
self.quote: Optional[TextQuote] = quote
|
||||
self.forward_origin: Optional[MessageOrigin] = forward_origin
|
||||
self.reply_to_story: Optional[Story] = reply_to_story
|
||||
self.boost_added: Optional[ChatBoostAdded] = boost_added
|
||||
self.sender_boost_count: Optional[int] = sender_boost_count
|
||||
|
||||
self._effective_attachment = DEFAULT_NONE
|
||||
|
||||
|
@ -1185,6 +1219,8 @@ class Message(MaybeInaccessibleMessage):
|
|||
data["external_reply"] = ExternalReplyInfo.de_json(data.get("external_reply"), bot)
|
||||
data["quote"] = TextQuote.de_json(data.get("quote"), bot)
|
||||
data["forward_origin"] = MessageOrigin.de_json(data.get("forward_origin"), bot)
|
||||
data["reply_to_story"] = Story.de_json(data.get("reply_to_story"), bot)
|
||||
data["boost_added"] = ChatBoostAdded.de_json(data.get("boost_added"), bot)
|
||||
|
||||
api_kwargs = {}
|
||||
# This is a deprecated field that TG still returns for backwards compatibility
|
||||
|
|
|
@ -18,24 +18,65 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object related to a Telegram Story."""
|
||||
|
||||
from typing import Optional
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._chat import Chat
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class Story(TelegramObject):
|
||||
"""
|
||||
This object represents a message about a forwarded story in the chat. Currently holds no
|
||||
information.
|
||||
This object represents a story.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`chat` and :attr:`id` are equal.
|
||||
|
||||
.. versionadded:: 20.5
|
||||
|
||||
.. versionchanged:: NEXT.VERSION
|
||||
Added attributes :attr:`chat` and :attr:`id` and equality based on them.
|
||||
|
||||
Args:
|
||||
chat (:class:`telegram.Chat`): Chat that posted the story.
|
||||
id (:obj:`int`): Unique identifier for the story in the chat.
|
||||
|
||||
Attributes:
|
||||
chat (:class:`telegram.Chat`): Chat that posted the story.
|
||||
id (:obj:`int`): Unique identifier for the story in the chat.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
__slots__ = (
|
||||
"chat",
|
||||
"id",
|
||||
)
|
||||
|
||||
def __init__(self, *, api_kwargs: Optional[JSONDict] = None) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
chat: Chat,
|
||||
id: int, # pylint: disable=redefined-builtin
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> None:
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.chat: Chat = chat
|
||||
self.id: int = id
|
||||
|
||||
self._id_attrs = (self.chat, self.id)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["Story"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data["chat"] = Chat.de_json(data.get("chat", {}), bot)
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
|
|
@ -142,7 +142,7 @@ class _AccentColor(NamedTuple):
|
|||
#: :data:`telegram.__bot_api_version_info__`.
|
||||
#:
|
||||
#: .. versionadded:: 20.0
|
||||
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=7, minor=0)
|
||||
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=7, minor=1)
|
||||
#: :obj:`str`: Telegram Bot API
|
||||
#: version supported by this version of `python-telegram-bot`. Also available as
|
||||
#: :data:`telegram.__bot_api_version__`.
|
||||
|
@ -1705,6 +1705,11 @@ class MessageType(StringEnum):
|
|||
""":obj:`str`: Messages with :attr:`telegram.Message.animation`."""
|
||||
AUDIO = "audio"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.audio`."""
|
||||
BOOST_ADDED = "boost_added"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.boost_added`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
CHANNEL_CHAT_CREATED = "channel_chat_created"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.channel_chat_created`."""
|
||||
CHAT_SHARED = "chat_shared"
|
||||
|
@ -1802,6 +1807,16 @@ class MessageType(StringEnum):
|
|||
""":obj:`str`: Messages with :attr:`telegram.Message.poll`."""
|
||||
PROXIMITY_ALERT_TRIGGERED = "proximity_alert_triggered"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.proximity_alert_triggered`."""
|
||||
REPLY_TO_STORY = "reply_to_story"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.reply_to_story`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
SENDER_BOOST_COUNT = "sender_boost_count"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.sender_boost_count`.
|
||||
|
||||
.. versionadded:: NEXT.VERSION
|
||||
"""
|
||||
STICKER = "sticker"
|
||||
""":obj:`str`: Messages with :attr:`telegram.Message.sticker`."""
|
||||
STORY = "story"
|
||||
|
|
|
@ -41,6 +41,7 @@ __all__ = (
|
|||
"ANIMATION",
|
||||
"ATTACHMENT",
|
||||
"AUDIO",
|
||||
"BOOST_ADDED",
|
||||
"CAPTION",
|
||||
"CHAT",
|
||||
"COMMAND",
|
||||
|
@ -60,6 +61,8 @@ __all__ = (
|
|||
"POLL",
|
||||
"PREMIUM_USER",
|
||||
"REPLY",
|
||||
"REPLY_TO_STORY",
|
||||
"SENDER_BOOST_COUNT",
|
||||
"STORY",
|
||||
"SUCCESSFUL_PAYMENT",
|
||||
"TEXT",
|
||||
|
@ -2789,3 +2792,36 @@ class _Voice(MessageFilter):
|
|||
|
||||
VOICE = _Voice("filters.VOICE")
|
||||
"""Messages that contain :attr:`telegram.Message.voice`."""
|
||||
|
||||
|
||||
class _ReplyToStory(MessageFilter):
|
||||
__slots__ = ()
|
||||
|
||||
def filter(self, message: Message) -> bool:
|
||||
return bool(message.reply_to_story)
|
||||
|
||||
|
||||
REPLY_TO_STORY = _ReplyToStory(name="filters.REPLY_TO_STORY")
|
||||
"""Messages that contain :attr:`telegram.Message.reply_to_story`."""
|
||||
|
||||
|
||||
class _BoostAdded(MessageFilter):
|
||||
__slots__ = ()
|
||||
|
||||
def filter(self, message: Message) -> bool:
|
||||
return bool(message.boost_added)
|
||||
|
||||
|
||||
BOOST_ADDED = _BoostAdded(name="filters.BOOST_ADDED")
|
||||
"""Messages that contain :attr:`telegram.Message.boost_added`."""
|
||||
|
||||
|
||||
class _SenderBoostCount(MessageFilter):
|
||||
__slots__ = ()
|
||||
|
||||
def filter(self, message: Message) -> bool:
|
||||
return bool(message.sender_boost_count)
|
||||
|
||||
|
||||
SENDER_BOOST_COUNT = _SenderBoostCount(name="filters.SENDER_BOOST_COUNT")
|
||||
"""Messages that contain :attr:`telegram.Message.sender_boost_count`."""
|
||||
|
|
|
@ -2700,3 +2700,24 @@ class TestFilters:
|
|||
update.message.giveaway_winners = "test"
|
||||
assert filters.GIVEAWAY_WINNERS.check_update(update)
|
||||
assert str(filters.GIVEAWAY_WINNERS) == "filters.GIVEAWAY_WINNERS"
|
||||
|
||||
def test_filters_reply_to_story(self, update):
|
||||
assert not filters.REPLY_TO_STORY.check_update(update)
|
||||
|
||||
update.message.reply_to_story = "test"
|
||||
assert filters.REPLY_TO_STORY.check_update(update)
|
||||
assert str(filters.REPLY_TO_STORY) == "filters.REPLY_TO_STORY"
|
||||
|
||||
def test_filters_boost_added(self, update):
|
||||
assert not filters.BOOST_ADDED.check_update(update)
|
||||
|
||||
update.message.boost_added = "test"
|
||||
assert filters.BOOST_ADDED.check_update(update)
|
||||
assert str(filters.BOOST_ADDED) == "filters.BOOST_ADDED"
|
||||
|
||||
def test_filters_sender_boost_count(self, update):
|
||||
assert not filters.SENDER_BOOST_COUNT.check_update(update)
|
||||
|
||||
update.message.sender_boost_count = "test"
|
||||
assert filters.SENDER_BOOST_COUNT.check_update(update)
|
||||
assert str(filters.SENDER_BOOST_COUNT) == "filters.SENDER_BOOST_COUNT"
|
||||
|
|
|
@ -72,6 +72,8 @@ def chat(bot):
|
|||
background_custom_emoji_id=TestChatBase.background_custom_emoji_id,
|
||||
profile_accent_color_id=TestChatBase.profile_accent_color_id,
|
||||
profile_background_custom_emoji_id=TestChatBase.profile_background_custom_emoji_id,
|
||||
unrestrict_boost_count=TestChatBase.unrestrict_boost_count,
|
||||
custom_emoji_sticker_set_name=TestChatBase.custom_emoji_sticker_set_name,
|
||||
)
|
||||
chat.set_bot(bot)
|
||||
chat._unfreeze()
|
||||
|
@ -115,6 +117,8 @@ class TestChatBase:
|
|||
background_custom_emoji_id = "background_custom_emoji_id"
|
||||
profile_accent_color_id = 2
|
||||
profile_background_custom_emoji_id = "profile_background_custom_emoji_id"
|
||||
unrestrict_boost_count = 100
|
||||
custom_emoji_sticker_set_name = "custom_emoji_sticker_set_name"
|
||||
|
||||
|
||||
class TestChatWithoutRequest(TestChatBase):
|
||||
|
@ -156,6 +160,8 @@ class TestChatWithoutRequest(TestChatBase):
|
|||
"background_custom_emoji_id": self.background_custom_emoji_id,
|
||||
"profile_accent_color_id": self.profile_accent_color_id,
|
||||
"profile_background_custom_emoji_id": self.profile_background_custom_emoji_id,
|
||||
"unrestrict_boost_count": self.unrestrict_boost_count,
|
||||
"custom_emoji_sticker_set_name": self.custom_emoji_sticker_set_name,
|
||||
}
|
||||
chat = Chat.de_json(json_dict, bot)
|
||||
|
||||
|
@ -194,6 +200,8 @@ class TestChatWithoutRequest(TestChatBase):
|
|||
assert chat.background_custom_emoji_id == self.background_custom_emoji_id
|
||||
assert chat.profile_accent_color_id == self.profile_accent_color_id
|
||||
assert chat.profile_background_custom_emoji_id == self.profile_background_custom_emoji_id
|
||||
assert chat.unrestrict_boost_count == self.unrestrict_boost_count
|
||||
assert chat.custom_emoji_sticker_set_name == self.custom_emoji_sticker_set_name
|
||||
|
||||
def test_de_json_localization(self, bot, raw_bot, tz_bot):
|
||||
json_dict = {
|
||||
|
@ -257,6 +265,8 @@ class TestChatWithoutRequest(TestChatBase):
|
|||
chat_dict["profile_background_custom_emoji_id"]
|
||||
== chat.profile_background_custom_emoji_id
|
||||
)
|
||||
assert chat_dict["custom_emoji_sticker_set_name"] == chat.custom_emoji_sticker_set_name
|
||||
assert chat_dict["unrestrict_boost_count"] == chat.unrestrict_boost_count
|
||||
|
||||
def test_always_tuples_attributes(self):
|
||||
chat = Chat(
|
||||
|
|
|
@ -95,11 +95,42 @@ class TestChatAdministratorRightsWithoutRequest:
|
|||
assert admin_rights_dict["can_delete_stories"] == car.can_delete_stories
|
||||
|
||||
def test_equality(self):
|
||||
a = ChatAdministratorRights(True, *((False,) * 11))
|
||||
b = ChatAdministratorRights(True, *((False,) * 11))
|
||||
c = ChatAdministratorRights(*(False,) * 12)
|
||||
d = ChatAdministratorRights(True, True, *((False,) * 10))
|
||||
e = ChatAdministratorRights(True, True, *((False,) * 10))
|
||||
a = ChatAdministratorRights(
|
||||
True,
|
||||
*((False,) * 11),
|
||||
can_post_stories=False,
|
||||
can_edit_stories=False,
|
||||
can_delete_stories=False,
|
||||
)
|
||||
b = ChatAdministratorRights(
|
||||
True,
|
||||
*((False,) * 11),
|
||||
can_post_stories=False,
|
||||
can_edit_stories=False,
|
||||
can_delete_stories=False,
|
||||
)
|
||||
c = ChatAdministratorRights(
|
||||
*(False,) * 12,
|
||||
can_post_stories=False,
|
||||
can_edit_stories=False,
|
||||
can_delete_stories=False,
|
||||
)
|
||||
d = ChatAdministratorRights(
|
||||
True,
|
||||
True,
|
||||
*((False,) * 10),
|
||||
can_post_stories=False,
|
||||
can_edit_stories=False,
|
||||
can_delete_stories=False,
|
||||
)
|
||||
e = ChatAdministratorRights(
|
||||
True,
|
||||
True,
|
||||
*((False,) * 10),
|
||||
can_post_stories=False,
|
||||
can_edit_stories=False,
|
||||
can_delete_stories=False,
|
||||
)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
@ -115,7 +146,20 @@ class TestChatAdministratorRightsWithoutRequest:
|
|||
assert hash(d) == hash(e)
|
||||
|
||||
def test_all_rights(self):
|
||||
f = ChatAdministratorRights(True, True, True, True, True, True, True, True, True)
|
||||
f = ChatAdministratorRights(
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
True,
|
||||
can_post_stories=True,
|
||||
can_edit_stories=True,
|
||||
can_delete_stories=True,
|
||||
)
|
||||
t = ChatAdministratorRights.all_rights()
|
||||
# if the dirs are the same, the attributes will all be there
|
||||
assert dir(f) == dir(t)
|
||||
|
@ -127,7 +171,20 @@ class TestChatAdministratorRightsWithoutRequest:
|
|||
assert f != t
|
||||
|
||||
def test_no_rights(self):
|
||||
f = ChatAdministratorRights(False, False, False, False, False, False, False, False, False)
|
||||
f = ChatAdministratorRights(
|
||||
False,
|
||||
False,
|
||||
False,
|
||||
False,
|
||||
False,
|
||||
False,
|
||||
False,
|
||||
False,
|
||||
False,
|
||||
can_post_stories=False,
|
||||
can_edit_stories=False,
|
||||
can_delete_stories=False,
|
||||
)
|
||||
t = ChatAdministratorRights.no_rights()
|
||||
# if the dirs are the same, the attributes will all be there
|
||||
assert dir(f) == dir(t)
|
||||
|
@ -137,3 +194,19 @@ class TestChatAdministratorRightsWithoutRequest:
|
|||
assert t[key] is False
|
||||
# and as a finisher, make sure the default is different.
|
||||
assert f != t
|
||||
|
||||
def test_depreciation_typeerror(self):
|
||||
with pytest.raises(TypeError, match="must be set in order"):
|
||||
ChatAdministratorRights(
|
||||
*(False,) * 12,
|
||||
)
|
||||
with pytest.raises(TypeError, match="must be set in order"):
|
||||
ChatAdministratorRights(*(False,) * 12, can_edit_stories=True)
|
||||
with pytest.raises(TypeError, match="must be set in order"):
|
||||
ChatAdministratorRights(*(False,) * 12, can_post_stories=True)
|
||||
with pytest.raises(TypeError, match="must be set in order"):
|
||||
ChatAdministratorRights(*(False,) * 12, can_delete_stories=True)
|
||||
with pytest.raises(TypeError, match="must be set in order"):
|
||||
ChatAdministratorRights(*(False,) * 12, can_edit_stories=True, can_post_stories=True)
|
||||
with pytest.raises(TypeError, match="must be set in order"):
|
||||
ChatAdministratorRights(*(False,) * 12, can_delete_stories=True, can_post_stories=True)
|
||||
|
|
|
@ -24,6 +24,7 @@ import pytest
|
|||
from telegram import (
|
||||
Chat,
|
||||
ChatBoost,
|
||||
ChatBoostAdded,
|
||||
ChatBoostRemoved,
|
||||
ChatBoostSource,
|
||||
ChatBoostSourceGiftCode,
|
||||
|
@ -542,3 +543,42 @@ class TestUserChatBoostsWithRequest(ChatBoostDefaults):
|
|||
async def test_get_user_chat_boosts(self, bot, channel_id, chat_id):
|
||||
chat_boosts = await bot.get_user_chat_boosts(channel_id, chat_id)
|
||||
assert isinstance(chat_boosts, UserChatBoosts)
|
||||
|
||||
|
||||
class TestChatBoostAddedWithoutRequest:
|
||||
boost_count = 100
|
||||
|
||||
def test_slot_behaviour(self):
|
||||
action = ChatBoostAdded(8)
|
||||
for attr in action.__slots__:
|
||||
assert getattr(action, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||
assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot"
|
||||
|
||||
def test_de_json(self):
|
||||
json_dict = {"boost_count": self.boost_count}
|
||||
chat_boost_added = ChatBoostAdded.de_json(json_dict, None)
|
||||
assert chat_boost_added.api_kwargs == {}
|
||||
|
||||
assert chat_boost_added.boost_count == self.boost_count
|
||||
|
||||
def test_to_dict(self):
|
||||
chat_boost_added = ChatBoostAdded(self.boost_count)
|
||||
chat_boost_added_dict = chat_boost_added.to_dict()
|
||||
|
||||
assert isinstance(chat_boost_added_dict, dict)
|
||||
assert chat_boost_added_dict["boost_count"] == self.boost_count
|
||||
|
||||
def test_equality(self):
|
||||
a = ChatBoostAdded(100)
|
||||
b = ChatBoostAdded(100)
|
||||
c = ChatBoostAdded(50)
|
||||
d = Chat(1, "")
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
||||
|
||||
assert a != d
|
||||
assert hash(a) != hash(d)
|
||||
|
|
|
@ -150,8 +150,13 @@ def make_json_dict(instance: ChatMember, include_optional_args: bool = False) ->
|
|||
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:
|
||||
# If we want to test all args (for de_json)
|
||||
# or if the param is optional but for backwards compatability
|
||||
elif (
|
||||
param.default is not inspect.Parameter.empty
|
||||
and include_optional_args
|
||||
or param.name in ["can_delete_stories", "can_post_stories", "can_edit_stories"]
|
||||
):
|
||||
json_dict[param.name] = val
|
||||
return json_dict
|
||||
|
||||
|
@ -297,3 +302,19 @@ class TestChatMemberTypesWithoutRequest:
|
|||
|
||||
assert c != e
|
||||
assert hash(c) != hash(e)
|
||||
|
||||
def test_deprecation_typeerror(self, chat_member_type):
|
||||
with pytest.raises(TypeError, match="must be set in order"):
|
||||
ChatMemberAdministrator(
|
||||
*(False,) * 12,
|
||||
)
|
||||
with pytest.raises(TypeError, match="must be set in order"):
|
||||
ChatMemberAdministrator(*(False,) * 12, can_edit_stories=True)
|
||||
with pytest.raises(TypeError, match="must be set in order"):
|
||||
ChatMemberAdministrator(*(False,) * 12, can_post_stories=True)
|
||||
with pytest.raises(TypeError, match="must be set in order"):
|
||||
ChatMemberAdministrator(*(False,) * 12, can_delete_stories=True)
|
||||
with pytest.raises(TypeError, match="must be set in order"):
|
||||
ChatMemberAdministrator(*(False,) * 12, can_edit_stories=True, can_post_stories=True)
|
||||
with pytest.raises(TypeError, match="must be set in order"):
|
||||
ChatMemberAdministrator(*(False,) * 12, can_delete_stories=True, can_post_stories=True)
|
||||
|
|
|
@ -64,6 +64,9 @@ def new_chat_member(user):
|
|||
True,
|
||||
True,
|
||||
True,
|
||||
can_post_stories=True,
|
||||
can_edit_stories=True,
|
||||
can_delete_stories=True,
|
||||
)
|
||||
|
||||
|
||||
|
@ -264,10 +267,19 @@ class TestChatMemberUpdatedWithoutRequest(TestChatMemberUpdatedBase):
|
|||
@pytest.mark.parametrize(
|
||||
"optional_attribute",
|
||||
# This gives the names of all optional arguments of ChatMember
|
||||
# skipping stories names because they aren't optional even though we pretend they are
|
||||
[
|
||||
name
|
||||
for name, param in inspect.signature(ChatMemberAdministrator).parameters.items()
|
||||
if name not in ["self", "api_kwargs"] and param.default != inspect.Parameter.empty
|
||||
if name
|
||||
not in [
|
||||
"self",
|
||||
"api_kwargs",
|
||||
"can_delete_stories",
|
||||
"can_post_stories",
|
||||
"can_edit_stories",
|
||||
]
|
||||
and param.default != inspect.Parameter.empty
|
||||
],
|
||||
)
|
||||
def test_difference_optionals(self, optional_attribute, user, chat):
|
||||
|
@ -276,8 +288,22 @@ class TestChatMemberUpdatedWithoutRequest(TestChatMemberUpdatedBase):
|
|||
old_value = "old_value"
|
||||
new_value = "new_value"
|
||||
trues = tuple(True for _ in range(9))
|
||||
old_chat_member = ChatMemberAdministrator(user, *trues, **{optional_attribute: old_value})
|
||||
new_chat_member = ChatMemberAdministrator(user, *trues, **{optional_attribute: new_value})
|
||||
old_chat_member = ChatMemberAdministrator(
|
||||
user,
|
||||
*trues,
|
||||
**{optional_attribute: old_value},
|
||||
can_delete_stories=True,
|
||||
can_edit_stories=True,
|
||||
can_post_stories=True,
|
||||
)
|
||||
new_chat_member = ChatMemberAdministrator(
|
||||
user,
|
||||
*trues,
|
||||
**{optional_attribute: new_value},
|
||||
can_delete_stories=True,
|
||||
can_edit_stories=True,
|
||||
can_post_stories=True,
|
||||
)
|
||||
chat_member_updated = ChatMemberUpdated(
|
||||
chat, user, datetime.datetime.utcnow(), old_chat_member, new_chat_member
|
||||
)
|
||||
|
|
|
@ -106,10 +106,30 @@ class TestKeyboardButtonRequestChatBase:
|
|||
chat_has_username = True
|
||||
chat_is_created = False
|
||||
user_administrator_rights = ChatAdministratorRights(
|
||||
True, False, True, False, True, False, True, False
|
||||
True,
|
||||
False,
|
||||
True,
|
||||
False,
|
||||
True,
|
||||
False,
|
||||
True,
|
||||
False,
|
||||
can_post_stories=False,
|
||||
can_edit_stories=False,
|
||||
can_delete_stories=False,
|
||||
)
|
||||
bot_administrator_rights = ChatAdministratorRights(
|
||||
True, False, True, False, True, False, True, False
|
||||
True,
|
||||
False,
|
||||
True,
|
||||
False,
|
||||
True,
|
||||
False,
|
||||
True,
|
||||
False,
|
||||
can_post_stories=False,
|
||||
can_edit_stories=False,
|
||||
can_delete_stories=False,
|
||||
)
|
||||
bot_is_member = True
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ from telegram import (
|
|||
Audio,
|
||||
Bot,
|
||||
Chat,
|
||||
ChatBoostAdded,
|
||||
ChatShared,
|
||||
Contact,
|
||||
Dice,
|
||||
|
@ -129,7 +130,7 @@ def message(bot):
|
|||
},
|
||||
{"photo": [PhotoSize("photo_id", "unique_id", 50, 50)], "caption": "photo_file"},
|
||||
{"sticker": Sticker("sticker_id", "unique_id", 50, 50, True, False, Sticker.REGULAR)},
|
||||
{"story": Story()},
|
||||
{"story": Story(Chat(1, Chat.PRIVATE), 0)},
|
||||
{"video": Video("video_id", "unique_id", 12, 12, 12), "caption": "video_file"},
|
||||
{"voice": Voice("voice_id", "unique_id", 5)},
|
||||
{"video_note": VideoNote("video_note_id", "unique_id", 20, 12)},
|
||||
|
@ -259,6 +260,9 @@ def message(bot):
|
|||
},
|
||||
{"quote": TextQuote("a text quote", 1)},
|
||||
{"forward_origin": MessageOriginChat(datetime.utcnow(), Chat(1, Chat.PRIVATE))},
|
||||
{"reply_to_story": Story(Chat(1, Chat.PRIVATE), 0)},
|
||||
{"boost_added": ChatBoostAdded(100)},
|
||||
{"sender_boost_count": 1},
|
||||
],
|
||||
ids=[
|
||||
"reply",
|
||||
|
@ -321,6 +325,9 @@ def message(bot):
|
|||
"external_reply",
|
||||
"quote",
|
||||
"forward_origin",
|
||||
"reply_to_story",
|
||||
"boost_added",
|
||||
"sender_boost_count",
|
||||
],
|
||||
)
|
||||
def message_params(bot, request):
|
||||
|
|
|
@ -132,6 +132,9 @@ def ptb_extra_params(object_name: str) -> set[str]:
|
|||
# Mostly due to the value being fixed anyway
|
||||
PTB_IGNORED_PARAMS = {
|
||||
r"InlineQueryResult\w+": {"type"},
|
||||
# TODO: Remove this in vNEXT.VERSION (API 7.1) when this can stop being optional
|
||||
r"ChatAdministratorRights": {"can_post_stories", "can_edit_stories", "can_delete_stories"},
|
||||
r"ChatMemberAdministrator": {"can_post_stories", "can_edit_stories", "can_delete_stories"},
|
||||
r"ChatMember\w+": {"status"},
|
||||
r"PassportElementError\w+": {"source"},
|
||||
"ForceReply": {"force_reply"},
|
||||
|
@ -166,7 +169,11 @@ def ignored_param_requirements(object_name: str) -> set[str]:
|
|||
|
||||
|
||||
# Arguments that are optional arguments for now for backwards compatibility
|
||||
BACKWARDS_COMPAT_KWARGS: dict[str, set[str]] = {}
|
||||
BACKWARDS_COMPAT_KWARGS: dict[str, set[str]] = {
|
||||
# TODO: Remove this in vNEXT.VERSION (API 7.1) when this can stop being optional
|
||||
r"ChatAdministratorRights": {"can_post_stories", "can_edit_stories", "can_delete_stories"},
|
||||
r"ChatMemberAdministrator": {"can_post_stories", "can_edit_stories", "can_delete_stories"},
|
||||
}
|
||||
|
||||
|
||||
def backwards_compat_kwargs(object_name: str) -> set[str]:
|
||||
|
|
|
@ -18,28 +18,55 @@
|
|||
|
||||
import pytest
|
||||
|
||||
from telegram import Story
|
||||
from telegram import Chat, Story
|
||||
from tests.auxil.slots import mro_slots
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def story():
|
||||
return Story()
|
||||
return Story(TestStoryBase.chat, TestStoryBase.id)
|
||||
|
||||
|
||||
class TestStoryWithoutRequest:
|
||||
def test_slot_behaviour(self):
|
||||
story = Story()
|
||||
class TestStoryBase:
|
||||
chat = Chat(1, "")
|
||||
id = 0
|
||||
|
||||
|
||||
class TestStoryWithoutRequest(TestStoryBase):
|
||||
def test_slot_behaviour(self, story):
|
||||
for attr in story.__slots__:
|
||||
assert getattr(story, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||
assert len(mro_slots(story)) == len(set(mro_slots(story))), "duplicate slot"
|
||||
|
||||
def test_de_json(self):
|
||||
story = Story.de_json({}, None)
|
||||
def test_de_json(self, bot):
|
||||
json_dict = {"chat": self.chat.to_dict(), "id": self.id}
|
||||
story = Story.de_json(json_dict, bot)
|
||||
assert story.api_kwargs == {}
|
||||
assert story.chat == self.chat
|
||||
assert story.id == self.id
|
||||
assert isinstance(story, Story)
|
||||
assert Story.de_json(None, bot) is None
|
||||
|
||||
def test_to_dict(self):
|
||||
story = Story()
|
||||
def test_to_dict(self, story):
|
||||
story_dict = story.to_dict()
|
||||
assert story_dict == {}
|
||||
assert story_dict["chat"] == self.chat.to_dict()
|
||||
assert story_dict["id"] == self.id
|
||||
|
||||
def test_equality(self):
|
||||
a = Story(Chat(1, ""), 0)
|
||||
b = Story(Chat(1, ""), 0)
|
||||
c = Story(Chat(1, ""), 1)
|
||||
d = Story(Chat(2, ""), 0)
|
||||
e = Chat(1, "")
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
||||
|
||||
assert a != d
|
||||
assert hash(a) != hash(d)
|
||||
|
||||
assert a != e
|
||||
assert hash(a) != hash(e)
|
||||
|
|
Loading…
Reference in a new issue