2
0
mirror of https://github.com/pyrogram/pyrogram synced 2025-08-29 13:27:47 +00:00

Merge pull request #230 from pyrogram/__slots__

Make use of __slots__ for efficiency
This commit is contained in:
Dan 2019-03-16 19:13:31 +01:00 committed by GitHub
commit bdb03957db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
73 changed files with 760 additions and 532 deletions

View File

@ -287,9 +287,11 @@ def start():
sorted_args = sort_args(c.args) sorted_args = sort_args(c.args)
arguments = ", " + ", ".join( arguments = (
[get_argument_type(i) for i in sorted_args if i != ("flags", "#")] ", "
) if c.args else "" + ("*, " if c.args else "")
+ (", ".join([get_argument_type(i) for i in sorted_args if i != ("flags", "#")]) if c.args else "")
)
fields = "\n ".join( fields = "\n ".join(
["self.{0} = {0} # {1}".format(i[0], i[1]) for i in c.args if i != ("flags", "#")] ["self.{0} = {0} # {1}".format(i[0], i[1]) for i in c.args if i != ("flags", "#")]
@ -456,7 +458,11 @@ def start():
fields=fields, fields=fields,
read_types=read_types, read_types=read_types,
write_types=write_types, write_types=write_types,
return_arguments=", ".join([i[0] for i in sorted_args if i != ("flags", "#")]) return_arguments=", ".join(
["{0}={0}".format(i[0]) for i in sorted_args if i != ("flags", "#")]
),
slots=", ".join(['"{}"'.format(i[0]) for i in sorted_args if i != ("flags", "#")]),
qualname="{}{}".format("{}.".format(c.namespace) if c.namespace else "", c.name)
) )
) )

View File

@ -9,7 +9,10 @@ class {class_name}(Object):
"""{docstring_args} """{docstring_args}
""" """
__slots__ = [{slots}]
ID = {object_id} ID = {object_id}
QUALNAME = "{qualname}"
def __init__(self{arguments}): def __init__(self{arguments}):
{fields} {fields}

View File

@ -19,14 +19,16 @@
from collections import OrderedDict from collections import OrderedDict
from datetime import datetime from datetime import datetime
from io import BytesIO from io import BytesIO
from json import JSONEncoder, dumps from json import dumps
from ..all import objects
class Object: class Object:
all = {} all = {}
__slots__ = []
QUALNAME = "Base"
@staticmethod @staticmethod
def read(b: BytesIO, *args): def read(b: BytesIO, *args):
return Object.all[int.from_bytes(b.read(4), "little")].read(b, *args) return Object.all[int.from_bytes(b.read(4), "little")].read(b, *args)
@ -35,7 +37,7 @@ class Object:
pass pass
def __str__(self) -> str: def __str__(self) -> str:
return dumps(self, cls=Encoder, indent=4) return dumps(self, indent=4, default=default, ensure_ascii=False)
def __bool__(self) -> bool: def __bool__(self) -> bool:
return True return True
@ -62,29 +64,18 @@ def remove_none(obj):
return obj return obj
class Encoder(JSONEncoder): def default(o: "Object"):
def default(self, o: Object): try:
try: content = {i: getattr(o, i) for i in o.__slots__}
content = o.__dict__
except AttributeError:
if isinstance(o, datetime):
return o.strftime("%d-%b-%Y %H:%M:%S")
else:
return repr(o)
name = o.__class__.__name__ return remove_none(
o = objects.get(getattr(o, "ID", None), None) OrderedDict(
[("_", o.QUALNAME)]
if o is not None: + [i for i in content.items()]
if o.startswith("pyrogram.client"): )
r = remove_none(OrderedDict([("_", "pyrogram:" + name)] + [i for i in content.items()])) )
r.pop("_client", None) except AttributeError:
if isinstance(o, datetime):
return r return o.strftime("%d-%b-%Y %H:%M:%S")
else:
return OrderedDict(
[("_", o.replace("pyrogram.api.types.", "telegram:"))]
+ [i for i in content.items()]
)
else: else:
return None return repr(o)

View File

@ -627,9 +627,9 @@ class Client(Methods, BaseClient):
try: try:
r = self.send( r = self.send(
functions.auth.SignIn( functions.auth.SignIn(
self.phone_number, phone_number=self.phone_number,
phone_code_hash, phone_code_hash=phone_code_hash,
self.phone_code phone_code=self.phone_code
) )
) )
except PhoneNumberUnoccupied: except PhoneNumberUnoccupied:
@ -640,11 +640,11 @@ class Client(Methods, BaseClient):
try: try:
r = self.send( r = self.send(
functions.auth.SignUp( functions.auth.SignUp(
self.phone_number, phone_number=self.phone_number,
phone_code_hash, phone_code_hash=phone_code_hash,
self.phone_code, phone_code=self.phone_code,
self.first_name, first_name=self.first_name,
self.last_name last_name=self.last_name
) )
) )
except PhoneNumberOccupied: except PhoneNumberOccupied:
@ -738,7 +738,11 @@ class Client(Methods, BaseClient):
break break
if terms_of_service: if terms_of_service:
assert self.send(functions.help.AcceptTermsOfService(terms_of_service.id)) assert self.send(
functions.help.AcceptTermsOfService(
id=terms_of_service.id
)
)
self.password = None self.password = None
self.user_id = r.user.id self.user_id = r.user.id
@ -1036,10 +1040,10 @@ class Client(Methods, BaseClient):
raise ConnectionError("Client has not been started") raise ConnectionError("Client has not been started")
if self.no_updates: if self.no_updates:
data = functions.InvokeWithoutUpdates(data) data = functions.InvokeWithoutUpdates(query=data)
if self.takeout_id: if self.takeout_id:
data = functions.InvokeWithTakeout(self.takeout_id, data) data = functions.InvokeWithTakeout(takeout_id=self.takeout_id, query=data)
r = self.session.send(data, retries, timeout) r = self.session.send(data, retries, timeout)
@ -1353,7 +1357,7 @@ class Client(Methods, BaseClient):
self.fetch_peers( self.fetch_peers(
self.send( self.send(
functions.users.GetUsers( functions.users.GetUsers(
id=[types.InputUser(peer_id, 0)] id=[types.InputUser(user_id=peer_id, access_hash=0)]
) )
) )
) )
@ -1361,7 +1365,7 @@ class Client(Methods, BaseClient):
if str(peer_id).startswith("-100"): if str(peer_id).startswith("-100"):
self.send( self.send(
functions.channels.GetChannels( functions.channels.GetChannels(
id=[types.InputChannel(int(str(peer_id)[4:]), 0)] id=[types.InputChannel(channel_id=int(str(peer_id)[4:]), access_hash=0)]
) )
) )
else: else:
@ -1668,8 +1672,8 @@ class Client(Methods, BaseClient):
hashes = session.send( hashes = session.send(
functions.upload.GetCdnFileHashes( functions.upload.GetCdnFileHashes(
r.file_token, file_token=r.file_token,
offset offset=offset
) )
) )

View File

@ -67,10 +67,10 @@ def get_peer_id(input_peer) -> int:
def get_input_peer(peer_id: int, access_hash: int): def get_input_peer(peer_id: int, access_hash: int):
return ( return (
types.InputPeerUser(peer_id, access_hash) if peer_id > 0 types.InputPeerUser(user_id=peer_id, access_hash=access_hash) if peer_id > 0
else types.InputPeerChannel(int(str(peer_id)[4:]), access_hash) else types.InputPeerChannel(channel_id=int(str(peer_id)[4:]), access_hash=access_hash)
if (str(peer_id).startswith("-100") and access_hash) if (str(peer_id).startswith("-100") and access_hash)
else types.InputPeerChat(-peer_id) else types.InputPeerChat(chat_id=-peer_id)
) )

View File

@ -45,7 +45,7 @@ class ExportChatInviteLink(BaseClient):
if isinstance(peer, types.InputPeerChat): if isinstance(peer, types.InputPeerChat):
return self.send( return self.send(
functions.messages.ExportChatInvite( functions.messages.ExportChatInvite(
chat_id=peer.chat_id peer=peer.chat_id
) )
).link ).link
elif isinstance(peer, types.InputPeerChannel): elif isinstance(peer, types.InputPeerChannel):

View File

@ -67,10 +67,10 @@ class GetChat(BaseClient):
peer = self.resolve_peer(chat_id) peer = self.resolve_peer(chat_id)
if isinstance(peer, types.InputPeerChannel): if isinstance(peer, types.InputPeerChannel):
r = self.send(functions.channels.GetFullChannel(peer)) r = self.send(functions.channels.GetFullChannel(channel=peer))
elif isinstance(peer, (types.InputPeerUser, types.InputPeerSelf)): elif isinstance(peer, (types.InputPeerUser, types.InputPeerSelf)):
r = self.send(functions.users.GetFullUser(peer)) r = self.send(functions.users.GetFullUser(id=peer))
else: else:
r = self.send(functions.messages.GetFullChat(peer.chat_id)) r = self.send(functions.messages.GetFullChat(chat_id=peer.chat_id))
return pyrogram.Chat._parse_full(self, r) return pyrogram.Chat._parse_full(self, r)

View File

@ -92,7 +92,7 @@ class GetChatMembers(BaseClient):
self, self,
self.send( self.send(
functions.messages.GetFullChat( functions.messages.GetFullChat(
peer.chat_id chat_id=peer.chat_id
) )
) )
) )

View File

@ -39,7 +39,7 @@ class GetContacts(BaseClient):
""" """
while True: while True:
try: try:
contacts = self.send(functions.contacts.GetContacts(0)) contacts = self.send(functions.contacts.GetContacts(hash=0))
except FloodWait as e: except FloodWait as e:
log.warning("get_contacts flood: waiting {} seconds".format(e.x)) log.warning("get_contacts flood: waiting {} seconds".format(e.x))
time.sleep(e.x) time.sleep(e.x)

View File

@ -131,7 +131,9 @@ class EditMessageMedia(BaseClient):
w=media.width, w=media.width,
h=media.height h=media.height
), ),
types.DocumentAttributeFilename(os.path.basename(media.media)) types.DocumentAttributeFilename(
file_name=os.path.basename(media.media)
)
] ]
) )
) )
@ -187,7 +189,9 @@ class EditMessageMedia(BaseClient):
performer=media.performer, performer=media.performer,
title=media.title title=media.title
), ),
types.DocumentAttributeFilename(os.path.basename(media.media)) types.DocumentAttributeFilename(
file_name=os.path.basename(media.media)
)
] ]
) )
) )
@ -244,7 +248,9 @@ class EditMessageMedia(BaseClient):
w=media.width, w=media.width,
h=media.height h=media.height
), ),
types.DocumentAttributeFilename(os.path.basename(media.media)), types.DocumentAttributeFilename(
file_name=os.path.basename(media.media)
),
types.DocumentAttributeAnimated() types.DocumentAttributeAnimated()
] ]
) )
@ -296,7 +302,9 @@ class EditMessageMedia(BaseClient):
thumb=None if media.thumb is None else self.save_file(media.thumb), thumb=None if media.thumb is None else self.save_file(media.thumb),
file=self.save_file(media.media), file=self.save_file(media.media),
attributes=[ attributes=[
types.DocumentAttributeFilename(os.path.basename(media.media)) types.DocumentAttributeFilename(
file_name=os.path.basename(media.media)
)
] ]
) )
) )

View File

@ -76,7 +76,7 @@ class GetMessages(BaseClient):
is_iterable = not isinstance(ids, int) is_iterable = not isinstance(ids, int)
ids = list(ids) if is_iterable else [ids] ids = list(ids) if is_iterable else [ids]
ids = [ids_type(i) for i in ids] ids = [ids_type(id=i) for i in ids]
if isinstance(peer, types.InputPeerChannel): if isinstance(peer, types.InputPeerChannel):
rpc = functions.channels.GetMessages(channel=peer, id=ids) rpc = functions.channels.GetMessages(channel=peer, id=ids)

View File

@ -141,7 +141,7 @@ class SendAnimation(BaseClient):
w=width, w=width,
h=height h=height
), ),
types.DocumentAttributeFilename(os.path.basename(animation)), types.DocumentAttributeFilename(file_name=os.path.basename(animation)),
types.DocumentAttributeAnimated() types.DocumentAttributeAnimated()
] ]
) )

View File

@ -142,7 +142,7 @@ class SendAudio(BaseClient):
performer=performer, performer=performer,
title=title title=title
), ),
types.DocumentAttributeFilename(os.path.basename(audio)) types.DocumentAttributeFilename(file_name=os.path.basename(audio))
] ]
) )
elif audio.startswith("http"): elif audio.startswith("http"):

View File

@ -123,7 +123,7 @@ class SendDocument(BaseClient):
file=file, file=file,
thumb=thumb, thumb=thumb,
attributes=[ attributes=[
types.DocumentAttributeFilename(os.path.basename(document)) types.DocumentAttributeFilename(file_name=os.path.basename(document))
] ]
) )
elif document.startswith("http"): elif document.startswith("http"):

View File

@ -69,9 +69,9 @@ class SendLocation(BaseClient):
functions.messages.SendMedia( functions.messages.SendMedia(
peer=self.resolve_peer(chat_id), peer=self.resolve_peer(chat_id),
media=types.InputMediaGeoPoint( media=types.InputMediaGeoPoint(
types.InputGeoPoint( geo_point=types.InputGeoPoint(
latitude, lat=latitude,
longitude long=longitude
) )
), ),
message="", message="",

View File

@ -137,7 +137,7 @@ class SendMediaGroup(BaseClient):
w=i.width, w=i.width,
h=i.height h=i.height
), ),
types.DocumentAttributeFilename(os.path.basename(i.media)) types.DocumentAttributeFilename(file_name=os.path.basename(i.media))
] ]
) )
) )

View File

@ -103,7 +103,7 @@ class SendSticker(BaseClient):
mime_type="image/webp", mime_type="image/webp",
file=file, file=file,
attributes=[ attributes=[
types.DocumentAttributeFilename(os.path.basename(sticker)) types.DocumentAttributeFilename(file_name=os.path.basename(sticker))
] ]
) )
elif sticker.startswith("http"): elif sticker.startswith("http"):

View File

@ -145,7 +145,7 @@ class SendVideo(BaseClient):
w=width, w=width,
h=height h=height
), ),
types.DocumentAttributeFilename(os.path.basename(video)) types.DocumentAttributeFilename(file_name=os.path.basename(video))
] ]
) )
elif video.startswith("http"): elif video.startswith("http"):

View File

@ -101,4 +101,4 @@ def compute_check(r: types.account.Password, password: str) -> types.InputCheckP
+ K_bytes + K_bytes
) )
return types.InputCheckPasswordSRP(srp_id, A_bytes, M1_bytes) return types.InputCheckPasswordSRP(srp_id=srp_id, A=A_bytes, M1=M1_bytes)

View File

@ -35,7 +35,7 @@ class GetMe(BaseClient):
self, self,
self.send( self.send(
functions.users.GetFullUser( functions.users.GetFullUser(
types.InputPeerSelf() id=types.InputPeerSelf()
) )
).user ).user
) )

View File

@ -43,7 +43,7 @@ class SetUserProfilePhoto(BaseClient):
return bool( return bool(
self.send( self.send(
functions.photos.UploadProfilePhoto( functions.photos.UploadProfilePhoto(
self.save_file(photo) file=self.save_file(photo)
) )
) )
) )

View File

@ -55,20 +55,20 @@ class HTML:
input_user = self.peers_by_id.get(user_id, None) input_user = self.peers_by_id.get(user_id, None)
entity = ( entity = (
Mention(start, len(body), input_user) Mention(offset=start, length=len(body), user_id=input_user)
if input_user else MentionInvalid(start, len(body), user_id) if input_user else MentionInvalid(offset=start, length=len(body), user_id=user_id)
) )
else: else:
entity = Url(start, len(body), url) entity = Url(offset=start, length=len(body), url=url)
else: else:
if style == "b" or style == "strong": if style == "b" or style == "strong":
entity = Bold(start, len(body)) entity = Bold(offset=start, length=len(body))
elif style == "i" or style == "em": elif style == "i" or style == "em":
entity = Italic(start, len(body)) entity = Italic(offset=start, length=len(body))
elif style == "code": elif style == "code":
entity = Code(start, len(body)) entity = Code(offset=start, length=len(body))
elif style == "pre": elif style == "pre":
entity = Pre(start, len(body), "") entity = Pre(offset=start, length=len(body), language="")
else: else:
continue continue

View File

@ -72,24 +72,24 @@ class Markdown:
input_user = self.peers_by_id.get(user_id, None) input_user = self.peers_by_id.get(user_id, None)
entity = ( entity = (
Mention(start, len(text), input_user) Mention(offset=start, length=len(text), user_id=input_user)
if input_user if input_user
else MentionInvalid(start, len(text), user_id) else MentionInvalid(offset=start, length=len(text), user_id=user_id)
) )
else: else:
entity = Url(start, len(text), url) entity = Url(offset=start, length=len(text), url=url)
body = text body = text
offset += len(url) + 4 offset += len(url) + 4
else: else:
if style == self.BOLD_DELIMITER: if style == self.BOLD_DELIMITER:
entity = Bold(start, len(body)) entity = Bold(offset=start, length=len(body))
elif style == self.ITALIC_DELIMITER: elif style == self.ITALIC_DELIMITER:
entity = Italic(start, len(body)) entity = Italic(offset=start, length=len(body))
elif style == self.CODE_DELIMITER: elif style == self.CODE_DELIMITER:
entity = Code(start, len(body)) entity = Code(offset=start, length=len(body))
elif style == self.PRE_DELIMITER: elif style == self.PRE_DELIMITER:
entity = Pre(start, len(body), "") entity = Pre(offset=start, length=len(body), language="")
else: else:
continue continue

View File

@ -25,5 +25,7 @@ class CallbackGame(PyrogramType):
Use BotFather to set up your game. Use BotFather to set up your game.
""" """
__slots__ = []
def __init__(self): def __init__(self):
super().__init__(None) super().__init__(None)

View File

@ -58,16 +58,20 @@ class CallbackQuery(PyrogramType, Update):
""" """
def __init__(self, __slots__ = ["id", "from_user", "chat_instance", "message", "inline_message_id", "data", "game_short_name"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
id: str, self,
from_user: User, *,
chat_instance: str, client: "pyrogram.client.ext.BaseClient",
message: "pyrogram.Message" = None, id: str,
inline_message_id: str = None, from_user: User,
data: bytes = None, chat_instance: str,
game_short_name: str = None): message: "pyrogram.Message" = None,
inline_message_id: str = None,
data: bytes = None,
game_short_name: str = None
):
super().__init__(client) super().__init__(client)
self.id = id self.id = id

View File

@ -33,8 +33,12 @@ class ForceReply(PyrogramType):
2) if the bot's message is a reply (has reply_to_message_id), sender of the original message. 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message.
""" """
def __init__(self, __slots__ = ["selective"]
selective: bool = None):
def __init__(
self,
selective: bool = None
):
super().__init__(None) super().__init__(None)
self.selective = selective self.selective = selective

View File

@ -37,12 +37,16 @@ class GameHighScore(PyrogramType):
Position in high score table for the game. Position in high score table for the game.
""" """
def __init__(self, __slots__ = ["user", "score", "position"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
user: User, self,
score: int, *,
position: int = None): client: "pyrogram.client.ext.BaseClient",
user: User,
score: int,
position: int = None
):
super().__init__(client) super().__init__(client)
self.user = user self.user = user

View File

@ -35,11 +35,15 @@ class GameHighScores(PyrogramType):
Game scores. Game scores.
""" """
def __init__(self, __slots__ = ["total_count", "game_high_scores"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
total_count: int, self,
game_high_scores: List[GameHighScore]): *,
client: "pyrogram.client.ext.BaseClient",
total_count: int,
game_high_scores: List[GameHighScore]
):
super().__init__(client) super().__init__(client)
self.total_count = total_count self.total_count = total_count

View File

@ -54,13 +54,19 @@ class InlineKeyboardButton(PyrogramType):
# TODO: Add callback_game and pay fields # TODO: Add callback_game and pay fields
def __init__(self, __slots__ = [
text: str, "text", "url", "callback_data", "switch_inline_query", "switch_inline_query_current_chat", "callback_game"
callback_data: bytes = None, ]
url: str = None,
switch_inline_query: str = None, def __init__(
switch_inline_query_current_chat: str = None, self,
callback_game: CallbackGame = None): text: str,
callback_data: bytes = None,
url: str = None,
switch_inline_query: str = None,
switch_inline_query_current_chat: str = None,
callback_game: CallbackGame = None
):
super().__init__(None) super().__init__(None)
self.text = str(text) self.text = str(text)
@ -105,16 +111,20 @@ class InlineKeyboardButton(PyrogramType):
def write(self): def write(self):
if self.callback_data: if self.callback_data:
return KeyboardButtonCallback(self.text, self.callback_data) return KeyboardButtonCallback(text=self.text, data=self.callback_data)
if self.url: if self.url:
return KeyboardButtonUrl(self.text, self.url) return KeyboardButtonUrl(text=self.text, url=self.url)
if self.switch_inline_query: if self.switch_inline_query:
return KeyboardButtonSwitchInline(self.text, self.switch_inline_query) return KeyboardButtonSwitchInline(text=self.text, query=self.switch_inline_query)
if self.switch_inline_query_current_chat: if self.switch_inline_query_current_chat:
return KeyboardButtonSwitchInline(self.text, self.switch_inline_query_current_chat, same_peer=True) return KeyboardButtonSwitchInline(
text=self.text,
query=self.switch_inline_query_current_chat,
same_peer=True
)
if self.callback_game: if self.callback_game:
return KeyboardButtonGame(self.text) return KeyboardButtonGame(text=self.text)

View File

@ -31,8 +31,12 @@ class InlineKeyboardMarkup(PyrogramType):
List of button rows, each represented by a List of InlineKeyboardButton objects. List of button rows, each represented by a List of InlineKeyboardButton objects.
""" """
def __init__(self, __slots__ = ["inline_keyboard"]
inline_keyboard: List[List[InlineKeyboardButton]]):
def __init__(
self,
inline_keyboard: List[List[InlineKeyboardButton]]
):
super().__init__(None) super().__init__(None)
self.inline_keyboard = inline_keyboard self.inline_keyboard = inline_keyboard
@ -55,7 +59,7 @@ class InlineKeyboardMarkup(PyrogramType):
def write(self): def write(self):
return ReplyInlineMarkup( return ReplyInlineMarkup(
[KeyboardButtonRow( rows=[KeyboardButtonRow(
[j.write() for j in i] buttons=[j.write() for j in i]
) for i in self.inline_keyboard] ) for i in self.inline_keyboard]
) )

View File

@ -40,10 +40,14 @@ class KeyboardButton(PyrogramType):
Available in private chats only. Available in private chats only.
""" """
def __init__(self, __slots__ = ["text", "request_contact", "request_location"]
text: str,
request_contact: bool = None, def __init__(
request_location: bool = None): self,
text: str,
request_contact: bool = None,
request_location: bool = None
):
super().__init__(None) super().__init__(None)
self.text = str(text) self.text = str(text)
@ -71,8 +75,8 @@ class KeyboardButton(PyrogramType):
# TODO: Enforce optional args mutual exclusiveness # TODO: Enforce optional args mutual exclusiveness
if self.request_contact: if self.request_contact:
return KeyboardButtonRequestPhone(self.text) return KeyboardButtonRequestPhone(text=self.text)
elif self.request_location: elif self.request_location:
return KeyboardButtonRequestGeoLocation(self.text) return KeyboardButtonRequestGeoLocation(text=self.text)
else: else:
return RawKeyboardButton(self.text) return RawKeyboardButton(text=self.text)

View File

@ -49,11 +49,15 @@ class ReplyKeyboardMarkup(PyrogramType):
select the new language. Other users in the group don't see the keyboard. select the new language. Other users in the group don't see the keyboard.
""" """
def __init__(self, __slots__ = ["keyboard", "resize_keyboard", "one_time_keyboard", "selective"]
keyboard: List[List[Union[KeyboardButton, str]]],
resize_keyboard: bool = None, def __init__(
one_time_keyboard: bool = None, self,
selective: bool = None): keyboard: List[List[Union[KeyboardButton, str]]],
resize_keyboard: bool = None,
one_time_keyboard: bool = None,
selective: bool = None
):
super().__init__(None) super().__init__(None)
self.keyboard = keyboard self.keyboard = keyboard
@ -83,9 +87,11 @@ class ReplyKeyboardMarkup(PyrogramType):
def write(self): def write(self):
return RawReplyKeyboardMarkup( return RawReplyKeyboardMarkup(
rows=[KeyboardButtonRow( rows=[KeyboardButtonRow(
[KeyboardButton(j).write() buttons=[
if isinstance(j, str) else j.write() KeyboardButton(j).write()
for j in i] if isinstance(j, str) else j.write()
for j in i
]
) for i in self.keyboard], ) for i in self.keyboard],
resize=self.resize_keyboard or None, resize=self.resize_keyboard or None,
single_use=self.one_time_keyboard or None, single_use=self.one_time_keyboard or None,

View File

@ -35,8 +35,12 @@ class ReplyKeyboardRemove(PyrogramType):
keyboard for that user, while still showing the keyboard with poll options to users who haven't voted yet. keyboard for that user, while still showing the keyboard with poll options to users who haven't voted yet.
""" """
def __init__(self, __slots__ = ["selective"]
selective: bool = None):
def __init__(
self,
selective: bool = None
):
super().__init__(None) super().__init__(None)
self.selective = selective self.selective = selective

View File

@ -18,10 +18,14 @@
class InputMedia: class InputMedia:
def __init__(self, __slots__ = ["media", "caption", "parse_mode"]
media: str,
caption: str, def __init__(
parse_mode: str): self,
media: str,
caption: str,
parse_mode: str
):
self.media = media self.media = media
self.caption = caption self.caption = caption
self.parse_mode = parse_mode self.parse_mode = parse_mode

View File

@ -52,14 +52,18 @@ class InputMediaAnimation(InputMedia):
Animation duration. Animation duration.
""" """
def __init__(self, __slots__ = ["thumb", "width", "height", "duration"]
media: str,
thumb: str = None, def __init__(
caption: str = "", self,
parse_mode: str = "", media: str,
width: int = 0, thumb: str = None,
height: int = 0, caption: str = "",
duration: int = 0): parse_mode: str = "",
width: int = 0,
height: int = 0,
duration: int = 0
):
super().__init__(media, caption, parse_mode) super().__init__(media, caption, parse_mode)
self.thumb = thumb self.thumb = thumb

View File

@ -53,14 +53,18 @@ class InputMediaAudio(InputMedia):
Title of the audio Title of the audio
""" """
def __init__(self, __slots__ = ["thumb", "duration", "performer", "title"]
media: str,
thumb: str = None, def __init__(
caption: str = "", self,
parse_mode: str = "", media: str,
duration: int = 0, thumb: str = None,
performer: int = "", caption: str = "",
title: str = ""): parse_mode: str = "",
duration: int = 0,
performer: int = "",
title: str = ""
):
super().__init__(media, caption, parse_mode) super().__init__(media, caption, parse_mode)
self.thumb = thumb self.thumb = thumb

View File

@ -43,11 +43,15 @@ class InputMediaDocument(InputMedia):
Defaults to Markdown. Defaults to Markdown.
""" """
def __init__(self, __slots__ = ["thumb"]
media: str,
thumb: str = None, def __init__(
caption: str = "", self,
parse_mode: str = ""): media: str,
thumb: str = None,
caption: str = "",
parse_mode: str = ""
):
super().__init__(media, caption, parse_mode) super().__init__(media, caption, parse_mode)
self.thumb = thumb self.thumb = thumb

View File

@ -39,8 +39,12 @@ class InputMediaPhoto(InputMedia):
Defaults to Markdown. Defaults to Markdown.
""" """
def __init__(self, __slots__ = []
media: str,
caption: str = "", def __init__(
parse_mode: str = ""): self,
media: str,
caption: str = "",
parse_mode: str = ""
):
super().__init__(media, caption, parse_mode) super().__init__(media, caption, parse_mode)

View File

@ -57,15 +57,19 @@ class InputMediaVideo(InputMedia):
Pass True, if the uploaded video is suitable for streaming. Pass True, if the uploaded video is suitable for streaming.
""" """
def __init__(self, __slots__ = ["thumb", "width", "height", "duration", "supports_streaming"]
media: str,
thumb: str = None, def __init__(
caption: str = "", self,
parse_mode: str = "", media: str,
width: int = 0, thumb: str = None,
height: int = 0, caption: str = "",
duration: int = 0, parse_mode: str = "",
supports_streaming: bool = True): width: int = 0,
height: int = 0,
duration: int = 0,
supports_streaming: bool = True
):
super().__init__(media, caption, parse_mode) super().__init__(media, caption, parse_mode)
self.thumb = thumb self.thumb = thumb

View File

@ -35,10 +35,14 @@ class InputPhoneContact:
Contact's last name Contact's last name
""" """
def __init__(self, __slots__ = []
phone: str,
first_name: str, def __init__(
last_name: str = ""): self,
phone: str,
first_name: str,
last_name: str = ""
):
pass pass
def __new__(cls, def __new__(cls,

View File

@ -57,18 +57,22 @@ class Animation(PyrogramType):
Date the animation was sent in Unix time. Date the animation was sent in Unix time.
""" """
def __init__(self, __slots__ = ["file_id", "thumb", "file_name", "mime_type", "file_size", "date", "width", "height", "duration"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
file_id: str, self,
width: int, *,
height: int, client: "pyrogram.client.ext.BaseClient",
duration: int, file_id: str,
thumb: PhotoSize = None, width: int,
file_name: str = None, height: int,
mime_type: str = None, duration: int,
file_size: int = None, thumb: PhotoSize = None,
date: int = None): file_name: str = None,
mime_type: str = None,
file_size: int = None,
date: int = None
):
super().__init__(client) super().__init__(client)
self.file_id = file_id self.file_id = file_id

View File

@ -57,18 +57,22 @@ class Audio(PyrogramType):
Title of the audio as defined by sender or by audio tags. Title of the audio as defined by sender or by audio tags.
""" """
def __init__(self, __slots__ = ["file_id", "thumb", "file_name", "mime_type", "file_size", "date", "duration", "performer", "title"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
file_id: str, self,
duration: int, *,
thumb: PhotoSize = None, client: "pyrogram.client.ext.BaseClient",
file_name: str = None, file_id: str,
mime_type: str = None, duration: int,
file_size: int = None, thumb: PhotoSize = None,
date: int = None, file_name: str = None,
performer: str = None, mime_type: str = None,
title: str = None): file_size: int = None,
date: int = None,
performer: str = None,
title: str = None
):
super().__init__(client) super().__init__(client)
self.file_id = file_id self.file_id = file_id

View File

@ -42,14 +42,18 @@ class Contact(PyrogramType):
Additional data about the contact in the form of a vCard. Additional data about the contact in the form of a vCard.
""" """
def __init__(self, __slots__ = ["phone_number", "first_name", "last_name", "user_id", "vcard"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
phone_number: str, self,
first_name: str, *,
last_name: str = None, client: "pyrogram.client.ext.BaseClient",
user_id: int = None, phone_number: str,
vcard: str = None): first_name: str,
last_name: str = None,
user_id: int = None,
vcard: str = None
):
super().__init__(client) super().__init__(client)
self.phone_number = phone_number self.phone_number = phone_number

View File

@ -48,15 +48,19 @@ class Document(PyrogramType):
Date the document was sent in Unix time. Date the document was sent in Unix time.
""" """
def __init__(self, __slots__ = ["file_id", "thumb", "file_name", "mime_type", "file_size", "date"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
file_id: str, self,
thumb: PhotoSize = None, *,
file_name: str = None, client: "pyrogram.client.ext.BaseClient",
mime_type: str = None, file_id: str,
file_size: int = None, thumb: PhotoSize = None,
date: int = None): file_name: str = None,
mime_type: str = None,
file_size: int = None,
date: int = None
):
super().__init__(client) super().__init__(client)
self.file_id = file_id self.file_id = file_id

View File

@ -48,15 +48,19 @@ class Game(PyrogramType):
Upload via BotFather. Upload via BotFather.
""" """
def __init__(self, __slots__ = ["id", "title", "short_name", "description", "photo", "animation"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
id: int, self,
title: str, *,
short_name: str, client: "pyrogram.client.ext.BaseClient",
description: str, id: int,
photo: Photo, title: str,
animation: Animation = None): short_name: str,
description: str,
photo: Photo,
animation: Animation = None
):
super().__init__(client) super().__init__(client)
self.id = id self.id = id

View File

@ -33,11 +33,15 @@ class Location(PyrogramType):
Latitude as defined by sender. Latitude as defined by sender.
""" """
def __init__(self, __slots__ = ["longitude", "latitude"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
longitude: float, self,
latitude: float): *,
client: "pyrogram.client.ext.BaseClient",
longitude: float,
latitude: float
):
super().__init__(client) super().__init__(client)
self.longitude = longitude self.longitude = longitude

View File

@ -234,65 +234,80 @@ class Message(PyrogramType, Update):
# TODO: Add game missing field. Also invoice, successful_payment, connected_website # TODO: Add game missing field. Also invoice, successful_payment, connected_website
def __init__(self, __slots__ = [
*, "message_id", "date", "chat", "from_user", "forward_from", "forward_from_chat", "forward_from_message_id",
client: "pyrogram.client.ext.BaseClient", "forward_signature", "forward_date", "reply_to_message", "mentioned", "empty", "service", "media", "edit_date",
message_id: int, "media_group_id", "author_signature", "text", "entities", "caption_entities", "audio", "document", "photo",
date: int = None, "sticker", "animation", "game", "video", "voice", "video_note", "caption", "contact", "location", "venue",
chat: Chat = None, "web_page", "poll", "new_chat_members", "left_chat_member", "new_chat_title", "new_chat_photo",
from_user: User = None, "delete_chat_photo", "group_chat_created", "supergroup_chat_created", "channel_chat_created",
forward_from: User = None, "migrate_to_chat_id", "migrate_from_chat_id", "pinned_message", "game_high_score", "views", "via_bot",
forward_from_chat: Chat = None, "outgoing", "matches", "command", "reply_markup"
forward_from_message_id: int = None, ]
forward_signature: str = None,
forward_date: int = None, def __init__(
reply_to_message: "Message" = None, self,
mentioned: bool = None, *,
empty: bool = None, client: "pyrogram.client.ext.BaseClient",
service: bool = None, message_id: int,
media: bool = None, date: int = None,
edit_date: int = None, chat: Chat = None,
media_group_id: str = None, from_user: User = None,
author_signature: str = None, forward_from: User = None,
text: str = None, forward_from_chat: Chat = None,
entities: List["pyrogram.MessageEntity"] = None, forward_from_message_id: int = None,
caption_entities: List["pyrogram.MessageEntity"] = None, forward_signature: str = None,
audio: "pyrogram.Audio" = None, forward_date: int = None,
document: "pyrogram.Document" = None, reply_to_message: "Message" = None,
photo: "pyrogram.Photo" = None, mentioned: bool = None,
sticker: "pyrogram.Sticker" = None, empty: bool = None,
animation: "pyrogram.Animation" = None, service: bool = None,
game: "pyrogram.Game" = None, media: bool = None,
video: "pyrogram.Video" = None, edit_date: int = None,
voice: "pyrogram.Voice" = None, media_group_id: str = None,
video_note: "pyrogram.VideoNote" = None, author_signature: str = None,
caption: str = None, text: str = None,
contact: "pyrogram.Contact" = None, entities: List["pyrogram.MessageEntity"] = None,
location: "pyrogram.Location" = None, caption_entities: List["pyrogram.MessageEntity"] = None,
venue: "pyrogram.Venue" = None, audio: "pyrogram.Audio" = None,
web_page: bool = None, document: "pyrogram.Document" = None,
poll: "pyrogram.Poll" = None, photo: "pyrogram.Photo" = None,
new_chat_members: List[User] = None, sticker: "pyrogram.Sticker" = None,
left_chat_member: User = None, animation: "pyrogram.Animation" = None,
new_chat_title: str = None, game: "pyrogram.Game" = None,
new_chat_photo: "pyrogram.Photo" = None, video: "pyrogram.Video" = None,
delete_chat_photo: bool = None, voice: "pyrogram.Voice" = None,
group_chat_created: bool = None, video_note: "pyrogram.VideoNote" = None,
supergroup_chat_created: bool = None, caption: str = None,
channel_chat_created: bool = None, contact: "pyrogram.Contact" = None,
migrate_to_chat_id: int = None, location: "pyrogram.Location" = None,
migrate_from_chat_id: int = None, venue: "pyrogram.Venue" = None,
pinned_message: "Message" = None, web_page: bool = None,
game_high_score: int = None, poll: "pyrogram.Poll" = None,
views: int = None, new_chat_members: List[User] = None,
via_bot: User = None, left_chat_member: User = None,
outgoing: bool = None, new_chat_title: str = None,
matches: List[Match] = None, new_chat_photo: "pyrogram.Photo" = None,
command: List[str] = None, delete_chat_photo: bool = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup", group_chat_created: bool = None,
"pyrogram.ReplyKeyboardMarkup", supergroup_chat_created: bool = None,
"pyrogram.ReplyKeyboardRemove", channel_chat_created: bool = None,
"pyrogram.ForceReply"] = None): migrate_to_chat_id: int = None,
migrate_from_chat_id: int = None,
pinned_message: "Message" = None,
game_high_score: int = None,
views: int = None,
via_bot: User = None,
outgoing: bool = None,
matches: List[Match] = None,
command: List[str] = None,
reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"
] = None
):
super().__init__(client) super().__init__(client)
self.message_id = message_id self.message_id = message_id

View File

@ -47,6 +47,8 @@ class MessageEntity(PyrogramType):
For "text_mention" only, the mentioned user. For "text_mention" only, the mentioned user.
""" """
__slots__ = ["type", "offset", "length", "url", "user"]
ENTITIES = { ENTITIES = {
types.MessageEntityMention.ID: "mention", types.MessageEntityMention.ID: "mention",
types.MessageEntityHashtag.ID: "hashtag", types.MessageEntityHashtag.ID: "hashtag",
@ -63,14 +65,16 @@ class MessageEntity(PyrogramType):
types.MessageEntityPhone.ID: "phone_number" types.MessageEntityPhone.ID: "phone_number"
} }
def __init__(self, def __init__(
*, self,
client: "pyrogram.client.ext.BaseClient", *,
type: str, client: "pyrogram.client.ext.BaseClient",
offset: int, type: str,
length: int, offset: int,
url: str = None, length: int,
user: User = None): url: str = None,
user: User = None
):
super().__init__(client) super().__init__(client)
self.type = type self.type = type

View File

@ -37,11 +37,15 @@ class Messages(PyrogramType, Update):
Requested messages. Requested messages.
""" """
def __init__(self, __slots__ = ["total_count", "messages"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
total_count: int, self,
messages: List[Message]): *,
client: "pyrogram.client.ext.BaseClient",
total_count: int,
messages: List[Message]
):
super().__init__(client) super().__init__(client)
self.total_count = total_count self.total_count = total_count

View File

@ -41,12 +41,16 @@ class Photo(PyrogramType):
Available sizes of this photo. Available sizes of this photo.
""" """
def __init__(self, __slots__ = ["id", "date", "sizes"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
id: str, self,
date: int, *,
sizes: List[PhotoSize]): client: "pyrogram.client.ext.BaseClient",
id: str,
date: int,
sizes: List[PhotoSize]
):
super().__init__(client) super().__init__(client)
self.id = id self.id = id

View File

@ -42,13 +42,17 @@ class PhotoSize(PyrogramType):
File size. File size.
""" """
def __init__(self, __slots__ = ["file_id", "width", "height", "file_size"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
file_id: str, self,
width: int, *,
height: int, client: "pyrogram.client.ext.BaseClient",
file_size: int): file_id: str,
width: int,
height: int,
file_size: int
):
super().__init__(client) super().__init__(client)
self.file_id = file_id self.file_id = file_id

View File

@ -47,15 +47,19 @@ class Poll(PyrogramType):
The index of your chosen option (in case you voted already), None otherwise. The index of your chosen option (in case you voted already), None otherwise.
""" """
def __init__(self, __slots__ = ["id", "closed", "question", "options", "total_voters", "option_chosen"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
id: int, self,
closed: bool, *,
question: str, client: "pyrogram.client.ext.BaseClient",
options: List[PollOption], id: int,
total_voters: int, closed: bool,
option_chosen: int = None): question: str,
options: List[PollOption],
total_voters: int,
option_chosen: int = None
):
super().__init__(client) super().__init__(client)
self.id = id self.id = id

View File

@ -34,12 +34,16 @@ class PollOption(PyrogramType):
Unique data that identifies this option among all the other options in a poll. Unique data that identifies this option among all the other options in a poll.
""" """
def __init__(self, __slots__ = ["text", "voters", "data"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
text: str, self,
voters: int, *,
data: bytes): client: "pyrogram.client.ext.BaseClient",
text: str,
voters: int,
data: bytes
):
super().__init__(client) super().__init__(client)
self.text = text self.text = text

View File

@ -64,19 +64,25 @@ class Sticker(PyrogramType):
# TODO: Add mask position # TODO: Add mask position
def __init__(self, __slots__ = [
*, "file_id", "thumb", "file_name", "mime_type", "file_size", "date", "width", "height", "emoji", "set_name"
client: "pyrogram.client.ext.BaseClient", ]
file_id: str,
width: int, def __init__(
height: int, self,
thumb: PhotoSize = None, *,
file_name: str = None, client: "pyrogram.client.ext.BaseClient",
mime_type: str = None, file_id: str,
file_size: int = None, width: int,
date: int = None, height: int,
emoji: str = None, thumb: PhotoSize = None,
set_name: str = None): file_name: str = None,
mime_type: str = None,
file_size: int = None,
date: int = None,
emoji: str = None,
set_name: str = None
):
super().__init__(client) super().__init__(client)
self.file_id = file_id self.file_id = file_id
@ -97,7 +103,10 @@ class Sticker(PyrogramType):
try: try:
return send( return send(
functions.messages.GetStickerSet( functions.messages.GetStickerSet(
types.InputStickerSetID(*input_sticker_set_id) stickerset=types.InputStickerSetID(
id=input_sticker_set_id[0],
access_hash=input_sticker_set_id[1]
)
) )
).set.short_name ).set.short_name
except StickersetInvalid: except StickersetInvalid:

View File

@ -34,11 +34,15 @@ class UserProfilePhotos(PyrogramType):
Requested profile pictures. Requested profile pictures.
""" """
def __init__(self, __slots__ = ["total_count", "photos"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
total_count: int, self,
photos: List[Photo]): *,
client: "pyrogram.client.ext.BaseClient",
total_count: int,
photos: List[Photo]
):
super().__init__(client) super().__init__(client)
self.total_count = total_count self.total_count = total_count

View File

@ -44,14 +44,18 @@ class Venue(PyrogramType):
""" """
def __init__(self, __slots__ = ["location", "title", "address", "foursquare_id", "foursquare_type"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
location: Location, self,
title: str, *,
address: str, client: "pyrogram.client.ext.BaseClient",
foursquare_id: str = None, location: Location,
foursquare_type: str = None): title: str,
address: str,
foursquare_id: str = None,
foursquare_type: str = None
):
super().__init__(client) super().__init__(client)
self.location = location self.location = location

View File

@ -57,18 +57,22 @@ class Video(PyrogramType):
Date the video was sent in Unix time. Date the video was sent in Unix time.
""" """
def __init__(self, __slots__ = ["file_id", "thumb", "file_name", "mime_type", "file_size", "date", "width", "height", "duration"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
file_id: str, self,
width: int, *,
height: int, client: "pyrogram.client.ext.BaseClient",
duration: int, file_id: str,
thumb: PhotoSize = None, width: int,
file_name: str = None, height: int,
mime_type: str = None, duration: int,
file_size: int = None, thumb: PhotoSize = None,
date: int = None): file_name: str = None,
mime_type: str = None,
file_size: int = None,
date: int = None
):
super().__init__(client) super().__init__(client)
self.file_id = file_id self.file_id = file_id

View File

@ -51,16 +51,20 @@ class VideoNote(PyrogramType):
Date the video note was sent in Unix time. Date the video note was sent in Unix time.
""" """
def __init__(self, __slots__ = ["file_id", "thumb", "mime_type", "file_size", "date", "length", "duration"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
file_id: str, self,
length: int, *,
duration: int, client: "pyrogram.client.ext.BaseClient",
thumb: PhotoSize = None, file_id: str,
mime_type: str = None, length: int,
file_size: int = None, duration: int,
date: int = None): thumb: PhotoSize = None,
mime_type: str = None,
file_size: int = None,
date: int = None
):
super().__init__(client) super().__init__(client)
self.file_id = file_id self.file_id = file_id

View File

@ -47,15 +47,19 @@ class Voice(PyrogramType):
Date the voice was sent in Unix time. Date the voice was sent in Unix time.
""" """
def __init__(self, __slots__ = ["file_id", "duration", "waveform", "mime_type", "file_size", "date"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
file_id: str, self,
duration: int, *,
waveform: bytes = None, client: "pyrogram.client.ext.BaseClient",
mime_type: str = None, file_id: str,
file_size: int = None, duration: int,
date: int = None): waveform: bytes = None,
mime_type: str = None,
file_size: int = None,
date: int = None
):
super().__init__(client) super().__init__(client)
self.file_id = file_id self.file_id = file_id

View File

@ -17,15 +17,17 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from collections import OrderedDict from collections import OrderedDict
from json import dumps, JSONEncoder from json import dumps
class PyrogramType: class PyrogramType:
__slots__ = ["_client"]
def __init__(self, client): def __init__(self, client):
self._client = client self._client = client
def __str__(self): def __str__(self):
return dumps(self, cls=Encoder, indent=4) return dumps(self, indent=4, default=default, ensure_ascii=False)
def __getitem__(self, item): def __getitem__(self, item):
return getattr(self, item) return getattr(self, item)
@ -40,15 +42,9 @@ def remove_none(obj):
return obj return obj
class Encoder(JSONEncoder): def default(o: PyrogramType):
def default(self, o: PyrogramType): try:
try: content = {i: getattr(o, i) for i in o.__slots__}
content = {
i: getattr(o, i)
for i in filter(lambda x: not x.startswith("_"), o.__dict__)
}
except AttributeError:
return repr(o)
return remove_none( return remove_none(
OrderedDict( OrderedDict(
@ -56,3 +52,5 @@ class Encoder(JSONEncoder):
+ [i for i in content.items()] + [i for i in content.items()]
) )
) )
except AttributeError:
return repr(o)

View File

@ -26,6 +26,8 @@ class ContinuePropagation(StopIteration):
class Update: class Update:
__slots__ = []
def stop_propagation(self): def stop_propagation(self):
raise StopPropagation raise StopPropagation

View File

@ -80,24 +80,32 @@ class Chat(PyrogramType):
Information about the chat default permissions. Information about the chat default permissions.
""" """
def __init__(self, __slots__ = [
*, "id", "type", "title", "username", "first_name", "last_name", "photo", "description", "invite_link",
client: "pyrogram.client.ext.BaseClient", "pinned_message", "sticker_set_name", "can_set_sticker_set", "members_count", "restriction_reason",
id: int, "permissions"
type: str, ]
title: str = None,
username: str = None, def __init__(
first_name: str = None, self,
last_name: str = None, *,
photo: ChatPhoto = None, client: "pyrogram.client.ext.BaseClient",
description: str = None, id: int,
invite_link: str = None, type: str,
pinned_message=None, title: str = None,
sticker_set_name: str = None, username: str = None,
can_set_sticker_set: bool = None, first_name: str = None,
members_count: int = None, last_name: str = None,
restriction_reason: str = None, photo: ChatPhoto = None,
permissions: "pyrogram.ChatPermissions" = None): description: str = None,
invite_link: str = None,
pinned_message=None,
sticker_set_name: str = None,
can_set_sticker_set: bool = None,
members_count: int = None,
restriction_reason: str = None,
permissions: "pyrogram.ChatPermissions" = None
):
super().__init__(client) super().__init__(client)
self.id = id self.id = id

View File

@ -51,16 +51,20 @@ class ChatMember(PyrogramType):
Information about the member permissions. Information about the member permissions.
""" """
def __init__(self, __slots__ = ["user", "status", "date", "invited_by", "promoted_by", "restricted_by", "permissions"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
user: "pyrogram.User", self,
status: str, *,
date: int = None, client: "pyrogram.client.ext.BaseClient",
invited_by: "pyrogram.User" = None, user: "pyrogram.User",
promoted_by: "pyrogram.User" = None, status: str,
restricted_by: "pyrogram.User" = None, date: int = None,
permissions: "pyrogram.ChatPermissions" = None): invited_by: "pyrogram.User" = None,
promoted_by: "pyrogram.User" = None,
restricted_by: "pyrogram.User" = None,
permissions: "pyrogram.ChatPermissions" = None
):
super().__init__(client) super().__init__(client)
self.user = user self.user = user

View File

@ -35,11 +35,15 @@ class ChatMembers(PyrogramType):
Requested chat members. Requested chat members.
""" """
def __init__(self, __slots__ = ["total_count", "chat_members"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
total_count: int, self,
chat_members: List[ChatMember]): *,
client: "pyrogram.client.ext.BaseClient",
total_count: int,
chat_members: List[ChatMember]
):
super().__init__(client) super().__init__(client)
self.total_count = total_count self.total_count = total_count

View File

@ -94,6 +94,13 @@ class ChatPermissions(PyrogramType):
True, if polls can be sent, implies can_send_media_messages. True, if polls can be sent, implies can_send_media_messages.
""" """
__slots__ = [
"until_date", "can_be_edited", "can_change_info", "can_post_messages", "can_edit_messages",
"can_delete_messages", "can_restrict_members", "can_invite_users", "can_pin_messages", "can_promote_members",
"can_send_messages", "can_send_media_messages", "can_send_other_messages", "can_add_web_page_previews",
"can_send_polls"
]
def __init__( def __init__(
self, self,
*, *,

View File

@ -35,11 +35,15 @@ class ChatPhoto(PyrogramType):
Unique file identifier of big (640x640) chat photo. This file_id can be used only for photo download. Unique file identifier of big (640x640) chat photo. This file_id can be used only for photo download.
""" """
def __init__(self, __slots__ = ["small_file_id", "big_file_id"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
small_file_id: str, self,
big_file_id: str): *,
client: "pyrogram.client.ext.BaseClient",
small_file_id: str,
big_file_id: str
):
super().__init__(client) super().__init__(client)
self.small_file_id = small_file_id self.small_file_id = small_file_id

View File

@ -45,14 +45,18 @@ class ChatPreview(PyrogramType):
Preview of some of the chat members. Preview of some of the chat members.
""" """
def __init__(self, __slots__ = ["title", "photo", "type", "members_count", "members"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
title: str, self,
photo: ChatPhoto, *,
type: str, client: "pyrogram.client.ext.BaseClient",
members_count: int, title: str,
members: List[User] = None): photo: ChatPhoto,
type: str,
members_count: int,
members: List[User] = None
):
super().__init__(client) super().__init__(client)
self.title = title self.title = title

View File

@ -46,15 +46,19 @@ class Dialog(PyrogramType):
True, if the dialog is pinned. True, if the dialog is pinned.
""" """
def __init__(self, __slots__ = ["chat", "top_message", "unread_messages_count", "unread_mentions_count", "unread_mark", "is_pinned"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
chat: Chat, self,
top_message: "pyrogram.Message", *,
unread_messages_count: int, client: "pyrogram.client.ext.BaseClient",
unread_mentions_count: int, chat: Chat,
unread_mark: bool, top_message: "pyrogram.Message",
is_pinned: bool): unread_messages_count: int,
unread_mentions_count: int,
unread_mark: bool,
is_pinned: bool
):
super().__init__(client) super().__init__(client)
self.chat = chat self.chat = chat

View File

@ -36,11 +36,15 @@ class Dialogs(PyrogramType):
Requested dialogs. Requested dialogs.
""" """
def __init__(self, __slots__ = ["total_count", "dialogs"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
total_count: int, self,
dialogs: List[Dialog]): *,
client: "pyrogram.client.ext.BaseClient",
total_count: int,
dialogs: List[Dialog]
):
super().__init__(client) super().__init__(client)
self.total_count = total_count self.total_count = total_count

View File

@ -70,23 +70,30 @@ class User(PyrogramType):
The reason why this bot might be unavailable to some users. The reason why this bot might be unavailable to some users.
""" """
def __init__(self, __slots__ = [
*, "id", "is_self", "is_contact", "is_mutual_contact", "is_deleted", "is_bot", "first_name", "last_name", "status",
client: "pyrogram.client.ext.BaseClient", "username", "language_code", "phone_number", "photo", "restriction_reason"
id: int, ]
is_self: bool,
is_contact: bool, def __init__(
is_mutual_contact: bool, self,
is_deleted: bool, *,
is_bot: bool, client: "pyrogram.client.ext.BaseClient",
first_name: str, id: int,
last_name: str = None, is_self: bool,
status: UserStatus = None, is_contact: bool,
username: str = None, is_mutual_contact: bool,
language_code: str = None, is_deleted: bool,
phone_number: str = None, is_bot: bool,
photo: ChatPhoto = None, first_name: str,
restriction_reason: str = None): last_name: str = None,
status: UserStatus = None,
username: str = None,
language_code: str = None,
phone_number: str = None,
photo: ChatPhoto = None,
restriction_reason: str = None
):
super().__init__(client) super().__init__(client)
self.id = id self.id = id

View File

@ -65,17 +65,21 @@ class UserStatus(PyrogramType, Update):
always shown to blocked users), None otherwise. always shown to blocked users), None otherwise.
""" """
def __init__(self, __slots__ = ["user_id", "online", "offline", "date", "recently", "within_week", "within_month", "long_time_ago"]
*,
client: "pyrogram.client.ext.BaseClient", def __init__(
user_id: int, self,
online: bool = None, *,
offline: bool = None, client: "pyrogram.client.ext.BaseClient",
date: int = None, user_id: int,
recently: bool = None, online: bool = None,
within_week: bool = None, offline: bool = None,
within_month: bool = None, date: int = None,
long_time_ago: bool = None): recently: bool = None,
within_week: bool = None,
within_month: bool = None,
long_time_ago: bool = None
):
super().__init__(client) super().__init__(client)
self.user_id = user_id self.user_id = user_id

View File

@ -45,10 +45,10 @@ class Auth:
@staticmethod @staticmethod
def pack(data: Object) -> bytes: def pack(data: Object) -> bytes:
return ( return (
bytes(8) bytes(8)
+ Long(MsgId()) + Long(MsgId())
+ Int(len(data.write())) + Int(len(data.write()))
+ data.write() + data.write()
) )
@staticmethod @staticmethod
@ -83,7 +83,7 @@ class Auth:
# Step 1; Step 2 # Step 1; Step 2
nonce = int.from_bytes(urandom(16), "little", signed=True) nonce = int.from_bytes(urandom(16), "little", signed=True)
log.debug("Send req_pq: {}".format(nonce)) log.debug("Send req_pq: {}".format(nonce))
res_pq = self.send(functions.ReqPqMulti(nonce)) res_pq = self.send(functions.ReqPqMulti(nonce=nonce))
log.debug("Got ResPq: {}".format(res_pq.server_nonce)) log.debug("Got ResPq: {}".format(res_pq.server_nonce))
log.debug("Server public key fingerprints: {}".format(res_pq.server_public_key_fingerprints)) log.debug("Server public key fingerprints: {}".format(res_pq.server_public_key_fingerprints))
@ -110,12 +110,12 @@ class Auth:
new_nonce = int.from_bytes(urandom(32), "little", signed=True) new_nonce = int.from_bytes(urandom(32), "little", signed=True)
data = types.PQInnerData( data = types.PQInnerData(
res_pq.pq, pq=res_pq.pq,
p.to_bytes(4, "big"), p=p.to_bytes(4, "big"),
q.to_bytes(4, "big"), q=q.to_bytes(4, "big"),
nonce, nonce=nonce,
server_nonce, server_nonce=server_nonce,
new_nonce, new_nonce=new_nonce,
).write() ).write()
sha = sha1(data).digest() sha = sha1(data).digest()
@ -129,12 +129,12 @@ class Auth:
log.debug("Send req_DH_params") log.debug("Send req_DH_params")
server_dh_params = self.send( server_dh_params = self.send(
functions.ReqDHParams( functions.ReqDHParams(
nonce, nonce=nonce,
server_nonce, server_nonce=server_nonce,
p.to_bytes(4, "big"), p=p.to_bytes(4, "big"),
q.to_bytes(4, "big"), q=q.to_bytes(4, "big"),
public_key_fingerprint, public_key_fingerprint=public_key_fingerprint,
encrypted_data encrypted_data=encrypted_data
) )
) )
@ -144,13 +144,13 @@ class Auth:
new_nonce = new_nonce.to_bytes(32, "little", signed=True) new_nonce = new_nonce.to_bytes(32, "little", signed=True)
tmp_aes_key = ( tmp_aes_key = (
sha1(new_nonce + server_nonce).digest() sha1(new_nonce + server_nonce).digest()
+ sha1(server_nonce + new_nonce).digest()[:12] + sha1(server_nonce + new_nonce).digest()[:12]
) )
tmp_aes_iv = ( tmp_aes_iv = (
sha1(server_nonce + new_nonce).digest()[12:] sha1(server_nonce + new_nonce).digest()[12:]
+ sha1(new_nonce + new_nonce).digest() + new_nonce[:4] + sha1(new_nonce + new_nonce).digest() + new_nonce[:4]
) )
server_nonce = int.from_bytes(server_nonce, "little", signed=True) server_nonce = int.from_bytes(server_nonce, "little", signed=True)
@ -175,10 +175,10 @@ class Auth:
retry_id = 0 retry_id = 0
data = types.ClientDHInnerData( data = types.ClientDHInnerData(
nonce, nonce=nonce,
server_nonce, server_nonce=server_nonce,
retry_id, retry_id=retry_id,
g_b g_b=g_b
).write() ).write()
sha = sha1(data).digest() sha = sha1(data).digest()
@ -189,9 +189,9 @@ class Auth:
log.debug("Send set_client_DH_params") log.debug("Send set_client_DH_params")
set_client_dh_params_answer = self.send( set_client_dh_params_answer = self.send(
functions.SetClientDHParams( functions.SetClientDHParams(
nonce, nonce=nonce,
server_nonce, server_nonce=server_nonce,
encrypted_data encrypted_data=encrypted_data
) )
) )

View File

@ -134,11 +134,11 @@ class Session:
self.current_salt = FutureSalt( self.current_salt = FutureSalt(
0, 0, 0, 0,
self._send( self._send(
functions.Ping(0), functions.Ping(ping_id=0),
timeout=self.START_TIMEOUT timeout=self.START_TIMEOUT
).new_server_salt ).new_server_salt
) )
self.current_salt = self._send(functions.GetFutureSalts(1), timeout=self.START_TIMEOUT).salts[0] self.current_salt = self._send(functions.GetFutureSalts(num=1), timeout=self.START_TIMEOUT).salts[0]
self.next_salt_thread = Thread(target=self.next_salt, name="NextSaltThread") self.next_salt_thread = Thread(target=self.next_salt, name="NextSaltThread")
self.next_salt_thread.start() self.next_salt_thread.start()
@ -146,8 +146,8 @@ class Session:
if not self.is_cdn: if not self.is_cdn:
self._send( self._send(
functions.InvokeWithLayer( functions.InvokeWithLayer(
layer, layer=layer,
functions.InitConnection( query=functions.InitConnection(
api_id=self.client.api_id, api_id=self.client.api_id,
app_version=self.client.app_version, app_version=self.client.app_version,
device_model=self.client.device_model, device_model=self.client.device_model,
@ -314,7 +314,7 @@ class Session:
log.info("Send {} acks".format(len(self.pending_acks))) log.info("Send {} acks".format(len(self.pending_acks)))
try: try:
self._send(types.MsgsAck(list(self.pending_acks)), False) self._send(types.MsgsAck(msg_ids=list(self.pending_acks)), False)
except (OSError, TimeoutError): except (OSError, TimeoutError):
pass pass
else: else:
@ -335,7 +335,7 @@ class Session:
try: try:
self._send(functions.PingDelayDisconnect( self._send(functions.PingDelayDisconnect(
0, self.WAIT_TIMEOUT + 10 ping_id=0, disconnect_delay=self.WAIT_TIMEOUT + 10
), False) ), False)
except (OSError, TimeoutError, Error): except (OSError, TimeoutError, Error):
pass pass
@ -365,7 +365,7 @@ class Session:
break break
try: try:
self.current_salt = self._send(functions.GetFutureSalts(1)).salts[0] self.current_salt = self._send(functions.GetFutureSalts(num=1)).salts[0]
except (OSError, TimeoutError, Error): except (OSError, TimeoutError, Error):
self.connection.close() self.connection.close()
break break