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

View File

@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
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

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
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]

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
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]

View File

@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
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:

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
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]