From 77aa37d2ad7318101c66e421086d30c7eccec064 Mon Sep 17 00:00:00 2001 From: Lonami Date: Mon, 26 Sep 2016 17:16:15 +0200 Subject: [PATCH] Added an .empty() function to the objects, fixes to msgs_ack The .empty() function returns an "empty" instance of the object (attributes set to None). This is used rather than using reflection. The msgs_ack handling broke stuff (InvokeWithLayer when there were updates), so this is now handled; yet there may be a better fix --- telethon/network/mtproto_sender.py | 13 ++++++++----- telethon/telegram_client.py | 3 +++ telethon/utils/binary_reader.py | 11 +++-------- telethon_generator/tl_generator.py | 11 +++++++++++ 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/telethon/network/mtproto_sender.py b/telethon/network/mtproto_sender.py index bf79910f..7c1a5edd 100755 --- a/telethon/network/mtproto_sender.py +++ b/telethon/network/mtproto_sender.py @@ -26,6 +26,12 @@ class MtProtoSender: self.updates_thread_running = False self.updates_thread_receiving = False + # Determine whether the received acknowledge request confirm + # our requests or not. This is not desired until we initialize + # our connection, because it breaks things when we call InvokeWithLayer + # TODO There might be a better way to handle msgs_ack requests + self.ack_requests_confirm = False + def disconnect(self): """Disconnects and **stops all the running threads** if any""" self.set_listen_for_updates(enabled=False) @@ -192,12 +198,9 @@ class MtProtoSender: if code == 0xa7eff811: # bad_msg_notification return self.handle_bad_msg_notification(msg_id, sequence, reader) - if code == 0x62d6b459: # msgs_ack, it may handle the request we wanted + # msgs_ack, it may handle the request we wanted + if self.ack_requests_confirm and code == 0x62d6b459: ack = reader.tgread_object() - for message_id in ack.msg_ids: - if message_id in self.need_confirmation: - self.need_confirmation.remove(message_id) - if request and request.msg_id in ack.msg_ids: request.confirm_received = True return False diff --git a/telethon/telegram_client.py b/telethon/telegram_client.py index 162bf39f..b4cd7979 100644 --- a/telethon/telegram_client.py +++ b/telethon/telegram_client.py @@ -85,6 +85,9 @@ class TelegramClient: # We're only interested in the DC options, # although many other options are available! self.dc_options = result.dc_options + + # We can now enable these (for such methods such as logout) + self.sender.ack_requests_confirm = True return True except RPCError as error: print('Could not stabilise initial connection: {}'.format(error)) diff --git a/telethon/utils/binary_reader.py b/telethon/utils/binary_reader.py index 0413f12f..6d04671e 100755 --- a/telethon/utils/binary_reader.py +++ b/telethon/utils/binary_reader.py @@ -117,14 +117,9 @@ class BinaryReader: # If there was still no luck, give up raise TypeNotFoundError(constructor_id) - # Now we need to determine the number of parameters of the class, so we can - # instantiate it with all of them set to None, and still, no need to write - # the default =None in all the classes, thus forcing the user to provide a real value - sig = inspect.signature(clazz.__init__) - params = [None] * (len(sig.parameters) - 1) # Subtract 1 (self) - result = clazz(*params) # https://docs.python.org/3/tutorial/controlflow.html#unpacking-argument-lists - - # Finally, read the object and return the result + # Create an empty instance of the class and + # fill it with the read attributes + result = clazz.empty() result.on_response(self) return result diff --git a/telethon_generator/tl_generator.py b/telethon_generator/tl_generator.py index c6bdc0e0..e84c2706 100755 --- a/telethon_generator/tl_generator.py +++ b/telethon_generator/tl_generator.py @@ -132,6 +132,17 @@ class TLGenerator: TLGenerator.write_onsend_code(builder, arg, tlobject.args) builder.end_block() + # Write the empty() function, which returns an "empty" + # instance, in which all attributes are set to None + builder.writeln('@staticmethod') + builder.writeln('def empty():') + builder.writeln('"""Returns an "empty" instance (all attributes are None)"""') + builder.writeln('return {}({})'.format( + TLGenerator.get_class_name(tlobject), + ', '.join('None' for _ in range(len(args))) + )) + builder.end_block() + # Write the on_response(self, reader) function builder.writeln('def on_response(self, reader):') # Do not read constructor's ID, since that's already been read somewhere else