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>
This commit is contained in:
DevOps117 2022-05-14 12:28:30 +05:30 committed by GitHub
parent 8961da7a2c
commit 6e1425ada3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 48 additions and 50 deletions

View File

@ -45,9 +45,9 @@ class DeleteContacts:
await app.delete_contacts(user_id) await app.delete_contacts(user_id)
await app.delete_contacts([user_id1, user_id2, user_id3]) 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] user_ids = [user_ids]
r = await self.invoke( r = await self.invoke(
@ -61,7 +61,4 @@ class DeleteContacts:
users = types.List([types.User._parse(self, i) for i in r.users]) users = types.List([types.User._parse(self, i) for i in r.users])
if is_user_ids_list: return users if is_list else users[0]
return users
else:
return users[0]

View File

@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union, Iterable from typing import Union, List
import pyrogram import pyrogram
from pyrogram import raw from pyrogram import raw
@ -26,9 +26,9 @@ class DeleteMessages:
async def delete_messages( async def delete_messages(
self: "pyrogram.Client", self: "pyrogram.Client",
chat_id: Union[int, str], chat_id: Union[int, str],
message_ids: Union[int, Iterable[int]], message_ids: Union[int, List[int]],
revoke: bool = True revoke: bool = True
) -> bool: ) -> int:
"""Delete messages, including service messages. """Delete messages, including service messages.
Parameters: Parameters:
@ -37,9 +37,8 @@ class DeleteMessages:
For your personal cloud (Saved Messages) you can simply use "me" or "self". 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). 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. A list of Message identifiers to delete (integers) or a single message id.
Iterators and Generators are also accepted.
revoke (``bool``, *optional*): revoke (``bool``, *optional*):
Deletes messages on both parts. Deletes messages on both parts.
@ -48,7 +47,7 @@ class DeleteMessages:
Defaults to True. Defaults to True.
Returns: Returns:
``bool``: True on success, False otherwise. ``int``: Amount of affected messages
Example: Example:
.. code-block:: python .. code-block:: python
@ -63,7 +62,9 @@ class DeleteMessages:
await app.delete_messages(chat_id, message_id, revoke=False) await app.delete_messages(chat_id, message_id, revoke=False)
""" """
peer = await self.resolve_peer(chat_id) 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): if isinstance(peer, raw.types.InputPeerChannel):
r = await self.invoke( r = await self.invoke(
@ -76,10 +77,10 @@ class DeleteMessages:
r = await self.invoke( r = await self.invoke(
raw.functions.messages.DeleteMessages( raw.functions.messages.DeleteMessages(
id=message_ids, 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. # Check for pts_count, which is 0 in case deletes fail.
return bool(r.pts_count) return r.pts_count

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime from datetime import datetime
from typing import Union, Iterable, List from typing import Union, List
import pyrogram import pyrogram
from pyrogram import raw, utils from pyrogram import raw, utils
@ -29,7 +29,7 @@ class ForwardMessages:
self: "pyrogram.Client", self: "pyrogram.Client",
chat_id: Union[int, str], chat_id: Union[int, str],
from_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, disable_notification: bool = None,
schedule_date: datetime = None, schedule_date: datetime = None,
protect_content: bool = None protect_content: bool = None
@ -49,7 +49,6 @@ class ForwardMessages:
message_ids (``int`` | List of ``int``): message_ids (``int`` | List of ``int``):
A list of Message identifiers in the chat specified in *from_chat_id* or a single message id. 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*): disable_notification (``bool``, *optional*):
Sends the message silently. Sends the message silently.
@ -62,9 +61,8 @@ class ForwardMessages:
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
Returns: Returns:
:obj:`~pyrogram.types.Message` | List of :obj:`~pyrogram.types.Message`: In case *message_ids* was an :obj:`~pyrogram.types.Message` | List of :obj:`~pyrogram.types.Message`: In case *message_ids* was not
integer, the single forwarded message is returned, otherwise, in case *message_ids* was an iterable, a list, a single message is returned, otherwise a list of messages is returned.
the returned value will be a list of messages, even if such iterable contained just a single element.
Example: Example:
.. code-block:: python .. code-block:: python
@ -76,8 +74,9 @@ class ForwardMessages:
await app.forward_messages(to_chat, from_chat, [1, 2, 3]) await app.forward_messages(to_chat, from_chat, [1, 2, 3])
""" """
is_iterable = not isinstance(message_ids, int) is_list = isinstance(message_ids, list)
message_ids = list(message_ids) if is_iterable else [message_ids] if not is_list:
message_ids = [message_ids]
r = await self.invoke( r = await self.invoke(
raw.functions.messages.ForwardMessages( 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]

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
import logging import logging
from typing import Union, Iterable, List from typing import Union, List
import pyrogram import pyrogram
from pyrogram import raw from pyrogram import raw
@ -34,8 +34,8 @@ class GetMessages:
async def get_messages( async def get_messages(
self: "pyrogram.Client", self: "pyrogram.Client",
chat_id: Union[int, str], chat_id: Union[int, str],
message_ids: Union[int, Iterable[int]] = None, message_ids: Union[int, List[int]] = None,
reply_to_message_ids: Union[int, Iterable[int]] = None, reply_to_message_ids: Union[int, List[int]] = None,
replies: int = 1 replies: int = 1
) -> Union["types.Message", List["types.Message"]]: ) -> Union["types.Message", List["types.Message"]]:
"""Get one or more messages from a chat by using message identifiers. """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 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). 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 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 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. If *message_ids* is set, this argument will be ignored.
replies (``int``, *optional*): replies (``int``, *optional*):
@ -63,9 +63,8 @@ class GetMessages:
Defaults to 1. Defaults to 1.
Returns: Returns:
:obj:`~pyrogram.types.Message` | List of :obj:`~pyrogram.types.Message`: In case *message_ids* was an :obj:`~pyrogram.types.Message` | List of :obj:`~pyrogram.types.Message`: In case *message_ids* was not
integer, the single requested message is returned, otherwise, in case *message_ids* was an iterable, the a list, a single message is returned, otherwise a list of messages is returned.
returned value will be a list of messages, even if such iterable contained just a single element.
Example: Example:
.. code-block:: python .. code-block:: python
@ -99,8 +98,10 @@ class GetMessages:
peer = await self.resolve_peer(chat_id) peer = await self.resolve_peer(chat_id)
is_iterable = not isinstance(ids, int) is_list = isinstance(ids, list)
ids = list(ids) if is_iterable else [ids] if not is_list:
ids = [ids]
ids = [ids_type(id=i) for i in ids] ids = [ids_type(id=i) for i in ids]
if replies < 0: if replies < 0:
@ -115,4 +116,4 @@ class GetMessages:
messages = await utils.parse_messages(self, r, replies=replies) 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]

View File

@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union from typing import Union, List
import pyrogram import pyrogram
from pyrogram import raw from pyrogram import raw
@ -27,7 +27,7 @@ class GetCommonChats:
async def get_common_chats( async def get_common_chats(
self: "pyrogram.Client", self: "pyrogram.Client",
user_id: Union[int, str] user_id: Union[int, str]
) -> list: ) -> List["types.Chat"]:
"""Get the common chats you have with a user. """Get the common chats you have with a user.
Parameters: Parameters:

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
import asyncio import asyncio
from typing import Iterable, Union, List from typing import Union, List
import pyrogram import pyrogram
from pyrogram import raw from pyrogram import raw
@ -27,21 +27,19 @@ from pyrogram import types
class GetUsers: class GetUsers:
async def get_users( async def get_users(
self: "pyrogram.Client", 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"]]: ) -> Union["types.User", List["types.User"]]:
"""Get information about a user. """Get information about a user.
You can retrieve up to 200 users at once. You can retrieve up to 200 users at once.
Parameters: 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. 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). For a contact that exists in your Telegram address book you can use his phone number (str).
Iterators and Generators are also accepted.
Returns: Returns:
:obj:`~pyrogram.types.User` | List of :obj:`~pyrogram.types.User`: In case *user_ids* was an integer or :obj:`~pyrogram.types.User` | List of :obj:`~pyrogram.types.User`: In case *user_ids* was not a list,
string the single requested user is returned, otherwise, in case *user_ids* was an iterable a list of users a single user is returned, otherwise a list of users is returned.
is returned, even if the iterable contained one item only.
Example: Example:
.. code-block:: python .. code-block:: python
@ -52,8 +50,10 @@ class GetUsers:
# Get information about multiple users at once # Get information about multiple users at once
await app.get_users([user_id1, user_id2, user_id3]) await app.get_users([user_id1, user_id2, user_id3])
""" """
is_iterable = not isinstance(user_ids, (int, str)) is_list = isinstance(user_ids, list)
user_ids = list(user_ids) if is_iterable else [user_ids] if not is_list:
user_ids = [user_ids]
user_ids = await asyncio.gather(*[self.resolve_peer(i) for i in user_ids]) user_ids = await asyncio.gather(*[self.resolve_peer(i) for i in user_ids])
r = await self.invoke( r = await self.invoke(
@ -67,4 +67,4 @@ class GetUsers:
for i in r: for i in r:
users.append(types.User._parse(self, i)) users.append(types.User._parse(self, i))
return users if is_iterable else users[0] return users if is_list else users[0]