From 6e1425ada3790b3ade70bacf21d968582d3882bf Mon Sep 17 00:00:00 2001 From: DevOps117 <55235206+devops117@users.noreply.github.com> Date: Sat, 14 May 2022 12:28:30 +0530 Subject: [PATCH] Drop support for iterators where they are not needed (#969) * delete_messages: Drop support for generators Since we used a list there anyway, this approach will lead to more localized errors and can reduce function overhead. Signed-off-by: devops117 <55235206+devops117@users.noreply.github.com> * delete_messages: Return pts_count:int An example usecase would be for a normal bot which uses range based on message ids instead of keeping a track of messages and using the DeletedMessagesHandler. Signed-off-by: devops117 <55235206+devops117@users.noreply.github.com> * Drop support for Iterators and update docstrings and some cleanups. Signed-off-by: devops117 <55235206+devops117@users.noreply.github.com> * Update get_users.py * Update get_messages.py * Update delete_messages.py * Update forward_messages.py * Update get_messages.py Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com> --- pyrogram/methods/contacts/delete_contacts.py | 9 +++---- pyrogram/methods/messages/delete_messages.py | 21 ++++++++------- pyrogram/methods/messages/forward_messages.py | 17 ++++++------ pyrogram/methods/messages/get_messages.py | 27 ++++++++++--------- pyrogram/methods/users/get_common_chats.py | 4 +-- pyrogram/methods/users/get_users.py | 20 +++++++------- 6 files changed, 48 insertions(+), 50 deletions(-) diff --git a/pyrogram/methods/contacts/delete_contacts.py b/pyrogram/methods/contacts/delete_contacts.py index 31d2bcbe..448e849a 100644 --- a/pyrogram/methods/contacts/delete_contacts.py +++ b/pyrogram/methods/contacts/delete_contacts.py @@ -45,9 +45,9 @@ class DeleteContacts: await app.delete_contacts(user_id) await app.delete_contacts([user_id1, user_id2, user_id3]) """ - is_user_ids_list = isinstance(user_ids, list) + is_list = isinstance(user_ids, list) - if not is_user_ids_list: + if not is_list: user_ids = [user_ids] r = await self.invoke( @@ -61,7 +61,4 @@ class DeleteContacts: users = types.List([types.User._parse(self, i) for i in r.users]) - if is_user_ids_list: - return users - else: - return users[0] + return users if is_list else users[0] diff --git a/pyrogram/methods/messages/delete_messages.py b/pyrogram/methods/messages/delete_messages.py index b25c0ad4..a07b36dd 100644 --- a/pyrogram/methods/messages/delete_messages.py +++ b/pyrogram/methods/messages/delete_messages.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from typing import Union, Iterable +from typing import Union, List import pyrogram from pyrogram import raw @@ -26,9 +26,9 @@ class DeleteMessages: async def delete_messages( self: "pyrogram.Client", chat_id: Union[int, str], - message_ids: Union[int, Iterable[int]], + message_ids: Union[int, List[int]], revoke: bool = True - ) -> bool: + ) -> int: """Delete messages, including service messages. Parameters: @@ -37,9 +37,8 @@ class DeleteMessages: For your personal cloud (Saved Messages) you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). - message_ids (``int`` | ``Iterable[int]``): + message_ids (``int`` | List of ``int``): A list of Message identifiers to delete (integers) or a single message id. - Iterators and Generators are also accepted. revoke (``bool``, *optional*): Deletes messages on both parts. @@ -48,7 +47,7 @@ class DeleteMessages: Defaults to True. Returns: - ``bool``: True on success, False otherwise. + ``int``: Amount of affected messages Example: .. code-block:: python @@ -63,7 +62,9 @@ class DeleteMessages: await app.delete_messages(chat_id, message_id, revoke=False) """ peer = await self.resolve_peer(chat_id) - message_ids = list(message_ids) if not isinstance(message_ids, int) else [message_ids] + # Follow type annotation of the raw function "DeleteMessage". + if not isinstance(message_ids, list): + message_ids = [message_ids] if isinstance(peer, raw.types.InputPeerChannel): r = await self.invoke( @@ -76,10 +77,10 @@ class DeleteMessages: r = await self.invoke( raw.functions.messages.DeleteMessages( id=message_ids, - revoke=revoke or None + revoke=revoke or None # Follow the type annotation. ) ) - # Deleting messages you don't have right onto, won't raise any error. + # Deleting messages you don't have right onto won't raise any error. # Check for pts_count, which is 0 in case deletes fail. - return bool(r.pts_count) + return r.pts_count diff --git a/pyrogram/methods/messages/forward_messages.py b/pyrogram/methods/messages/forward_messages.py index 6ee84922..2e288253 100644 --- a/pyrogram/methods/messages/forward_messages.py +++ b/pyrogram/methods/messages/forward_messages.py @@ -17,7 +17,7 @@ # along with Pyrogram. If not, see . from datetime import datetime -from typing import Union, Iterable, List +from typing import Union, List import pyrogram from pyrogram import raw, utils @@ -29,7 +29,7 @@ class ForwardMessages: self: "pyrogram.Client", chat_id: Union[int, str], from_chat_id: Union[int, str], - message_ids: Union[int, Iterable[int]], + message_ids: Union[int, List[int]], disable_notification: bool = None, schedule_date: datetime = None, protect_content: bool = None @@ -49,7 +49,6 @@ class ForwardMessages: message_ids (``int`` | List of ``int``): A list of Message identifiers in the chat specified in *from_chat_id* or a single message id. - Iterators and Generators are also accepted. disable_notification (``bool``, *optional*): Sends the message silently. @@ -62,9 +61,8 @@ class ForwardMessages: Protects the contents of the sent message from forwarding and saving. Returns: - :obj:`~pyrogram.types.Message` | List of :obj:`~pyrogram.types.Message`: In case *message_ids* was an - integer, the single forwarded message is returned, otherwise, in case *message_ids* was an iterable, - the returned value will be a list of messages, even if such iterable contained just a single element. + :obj:`~pyrogram.types.Message` | List of :obj:`~pyrogram.types.Message`: In case *message_ids* was not + a list, a single message is returned, otherwise a list of messages is returned. Example: .. code-block:: python @@ -76,8 +74,9 @@ class ForwardMessages: await app.forward_messages(to_chat, from_chat, [1, 2, 3]) """ - is_iterable = not isinstance(message_ids, int) - message_ids = list(message_ids) if is_iterable else [message_ids] + is_list = isinstance(message_ids, list) + if not is_list: + message_ids = [message_ids] r = await self.invoke( raw.functions.messages.ForwardMessages( @@ -107,4 +106,4 @@ class ForwardMessages: ) ) - return types.List(forwarded_messages) if is_iterable else forwarded_messages[0] + return types.List(forwarded_messages) if is_list else forwarded_messages[0] diff --git a/pyrogram/methods/messages/get_messages.py b/pyrogram/methods/messages/get_messages.py index 8db24dd9..ce38b232 100644 --- a/pyrogram/methods/messages/get_messages.py +++ b/pyrogram/methods/messages/get_messages.py @@ -17,7 +17,7 @@ # along with Pyrogram. If not, see . import logging -from typing import Union, Iterable, List +from typing import Union, List import pyrogram from pyrogram import raw @@ -34,8 +34,8 @@ class GetMessages: async def get_messages( self: "pyrogram.Client", chat_id: Union[int, str], - message_ids: Union[int, Iterable[int]] = None, - reply_to_message_ids: Union[int, Iterable[int]] = None, + message_ids: Union[int, List[int]] = None, + reply_to_message_ids: Union[int, List[int]] = None, replies: int = 1 ) -> Union["types.Message", List["types.Message"]]: """Get one or more messages from a chat by using message identifiers. @@ -48,13 +48,13 @@ class GetMessages: For your personal cloud (Saved Messages) you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). - message_ids (``iterable``, *optional*): + message_ids (``int`` | List of ``int``, *optional*): Pass a single message identifier or a list of message ids (as integers) to get the content of the - message themselves. Iterators and Generators are also accepted. + message themselves. - reply_to_message_ids (``iterable``, *optional*): + reply_to_message_ids (``int`` | List of ``int``, *optional*): Pass a single message identifier or a list of message ids (as integers) to get the content of - the previous message you replied to using this message. Iterators and Generators are also accepted. + the previous message you replied to using this message. If *message_ids* is set, this argument will be ignored. replies (``int``, *optional*): @@ -63,9 +63,8 @@ class GetMessages: Defaults to 1. Returns: - :obj:`~pyrogram.types.Message` | List of :obj:`~pyrogram.types.Message`: In case *message_ids* was an - integer, the single requested message is returned, otherwise, in case *message_ids* was an iterable, the - returned value will be a list of messages, even if such iterable contained just a single element. + :obj:`~pyrogram.types.Message` | List of :obj:`~pyrogram.types.Message`: In case *message_ids* was not + a list, a single message is returned, otherwise a list of messages is returned. Example: .. code-block:: python @@ -99,8 +98,10 @@ class GetMessages: peer = await self.resolve_peer(chat_id) - is_iterable = not isinstance(ids, int) - ids = list(ids) if is_iterable else [ids] + is_list = isinstance(ids, list) + if not is_list: + ids = [ids] + ids = [ids_type(id=i) for i in ids] if replies < 0: @@ -115,4 +116,4 @@ class GetMessages: messages = await utils.parse_messages(self, r, replies=replies) - return messages if is_iterable else messages[0] if messages else None + return messages if is_list else messages[0] diff --git a/pyrogram/methods/users/get_common_chats.py b/pyrogram/methods/users/get_common_chats.py index 7269a81e..a45bda6f 100644 --- a/pyrogram/methods/users/get_common_chats.py +++ b/pyrogram/methods/users/get_common_chats.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from typing import Union +from typing import Union, List import pyrogram from pyrogram import raw @@ -27,7 +27,7 @@ class GetCommonChats: async def get_common_chats( self: "pyrogram.Client", user_id: Union[int, str] - ) -> list: + ) -> List["types.Chat"]: """Get the common chats you have with a user. Parameters: diff --git a/pyrogram/methods/users/get_users.py b/pyrogram/methods/users/get_users.py index caef7966..c3f93d98 100644 --- a/pyrogram/methods/users/get_users.py +++ b/pyrogram/methods/users/get_users.py @@ -17,7 +17,7 @@ # along with Pyrogram. If not, see . import asyncio -from typing import Iterable, Union, List +from typing import Union, List import pyrogram from pyrogram import raw @@ -27,21 +27,19 @@ from pyrogram import types class GetUsers: async def get_users( self: "pyrogram.Client", - user_ids: Union[Iterable[Union[int, str]], int, str] + user_ids: Union[int, str, List[Union[int, str]]] ) -> Union["types.User", List["types.User"]]: """Get information about a user. You can retrieve up to 200 users at once. Parameters: - user_ids (``iterable``): + user_ids (``int`` | ``str`` | List of ``int`` or ``str``): A list of User identifiers (id or username) or a single user id/username. For a contact that exists in your Telegram address book you can use his phone number (str). - Iterators and Generators are also accepted. Returns: - :obj:`~pyrogram.types.User` | List of :obj:`~pyrogram.types.User`: In case *user_ids* was an integer or - string the single requested user is returned, otherwise, in case *user_ids* was an iterable a list of users - is returned, even if the iterable contained one item only. + :obj:`~pyrogram.types.User` | List of :obj:`~pyrogram.types.User`: In case *user_ids* was not a list, + a single user is returned, otherwise a list of users is returned. Example: .. code-block:: python @@ -52,8 +50,10 @@ class GetUsers: # Get information about multiple users at once await app.get_users([user_id1, user_id2, user_id3]) """ - is_iterable = not isinstance(user_ids, (int, str)) - user_ids = list(user_ids) if is_iterable else [user_ids] + is_list = isinstance(user_ids, list) + if not is_list: + user_ids = [user_ids] + user_ids = await asyncio.gather(*[self.resolve_peer(i) for i in user_ids]) r = await self.invoke( @@ -67,4 +67,4 @@ class GetUsers: for i in r: users.append(types.User._parse(self, i)) - return users if is_iterable else users[0] + return users if is_list else users[0]