diff --git a/docs/docs_writer.py b/docs/docs_writer.py
index 202557ac..f9042f00 100644
--- a/docs/docs_writer.py
+++ b/docs/docs_writer.py
@@ -8,9 +8,10 @@ class DocsWriter:
"""Initializes the writer to the specified output file,
creating the parent directories when used if required.
- 'type_to_path_function' should be a function which, given a type name
- and a named argument relative_to, returns the file path for the specified
- type, relative to the given filename"""
+ 'type_to_path_function' should be a function which, given a type
+ name and a named argument relative_to, returns the file path for
+ the specified type, relative to the given filename
+ """
self.filename = filename
self.handle = None
@@ -18,7 +19,9 @@ class DocsWriter:
self.menu_separator_tag = None
# Utility functions TODO There must be a better way
- self.type_to_path = lambda t: type_to_path_function(t, relative_to=self.filename)
+ self.type_to_path = lambda t: type_to_path_function(
+ t, relative_to=self.filename
+ )
# Control signals
self.menu_began = False
@@ -28,7 +31,9 @@ class DocsWriter:
# High level writing
def write_head(self, title, relative_css_path):
- """Writes the head part for the generated document, with the given title and CSS"""
+ """Writes the head part for the generated document,
+ with the given title and CSS
+ """
self.write('''
@@ -50,9 +55,12 @@ class DocsWriter:
''')
def set_menu_separator(self, relative_image_path):
- """Sets the menu separator. Must be called before adding entries to the menu"""
+ """Sets the menu separator.
+ Must be called before adding entries to the menu
+ """
if relative_image_path:
- self.menu_separator_tag = '
' % relative_image_path
+ self.menu_separator_tag = \
+ '
'.format(relative_image_path)
else:
self.menu_separator_tag = None
@@ -86,13 +94,17 @@ class DocsWriter:
self.write('')
def write_title(self, title, level=1):
- """Writes a title header in the document body, with an optional depth level"""
+ """Writes a title header in the document body,
+ with an optional depth level
+ """
self.write('
' % level)
self.write(title)
self.write('' % level)
def write_code(self, tlobject):
- """Writes the code for the given 'tlobject' properly formatted ith with hyperlinks"""
+ """Writes the code for the given 'tlobject' properly
+ formatted with hyperlinks
+ """
self.write('
---')
self.write('functions' if tlobject.is_function else 'types')
self.write('---\n')
@@ -127,7 +139,9 @@ class DocsWriter:
self.write('!')
if arg.is_vector:
- self.write('Vector<' % self.type_to_path('vector'))
+ self.write(
+ 'Vector<' % self.type_to_path('vector')
+ )
# Argument type
if arg.type:
@@ -146,7 +160,7 @@ class DocsWriter:
if arg.generic_definition:
self.write('}')
- # Now write the resulting type (result from a function, or type for a constructor)
+ # Now write the resulting type (result from a function/type)
self.write(' = ')
generic_name = next((arg.name for arg in tlobject.args
if arg.generic_definition), None)
diff --git a/docs/generate.py b/docs/generate.py
index 2fc35426..80408a47 100755
--- a/docs/generate.py
+++ b/docs/generate.py
@@ -16,7 +16,7 @@ from telethon_generator.parser import TLParser, TLObject
# TLObject -> Python class name
def get_class_name(tlobject):
- """Gets the class name following the Python style guidelines, in ThisClassFormat"""
+ """Gets the class name following the Python style guidelines"""
# Courtesy of http://stackoverflow.com/a/31531797/4759433
name = tlobject.name if isinstance(tlobject, TLObject) else tlobject
result = re.sub(r'_([a-z])', lambda m: m.group(1).upper(), name)
@@ -93,9 +93,9 @@ def get_path_for_type(type_, relative_to='.'):
elif '.' in type_:
# If it's not a core type, then it has to be a custom Telegram type
namespace, name = type_.split('.')
- path = 'types/%s/%s' % (namespace, get_file_name(name, add_extension=True))
+ path = 'types/%s/%s' % (namespace, get_file_name(name, True))
else:
- path = 'types/%s' % get_file_name(type_, add_extension=True)
+ path = 'types/%s' % get_file_name(type_, True)
return get_relative_path(path, relative_to)
@@ -116,7 +116,7 @@ def get_relative_paths(original, relative_to):
# Generate a index.html file for the given folder
def find_title(html_file):
- """Finds the for the given HTML file, returns (Unknown) if not found"""
+ """Finds the for the given HTML file, or (Unknown)"""
with open(html_file) as handle:
for line in handle:
if '' in line:
@@ -196,8 +196,25 @@ def generate_index(folder, original_paths):
docs.end_body()
+def get_description(arg):
+ """Generates a proper description for the given argument"""
+ desc = []
+ if arg.can_be_inferred:
+ desc.append('If left to None, it will be inferred automatically.')
+ if arg.is_vector:
+ desc.append('A list must be supplied for this argument.')
+ if arg.is_generic:
+ desc.append('A different Request must be supplied for this argument.')
+ if arg.is_flag:
+ desc.append('This argument can be omitted.')
+
+ return ' '.join(desc)
+
+
def generate_documentation(scheme_file):
- """Generates the documentation HTML files from from scheme.tl to /methods and /constructors, etc."""
+ """Generates the documentation HTML files from from scheme.tl to
+ /methods and /constructors, etc.
+ """
original_paths = {
'css': 'css/docs.css',
'arrow': 'img/arrow.svg',
@@ -234,7 +251,8 @@ def generate_documentation(scheme_file):
# Determine the relative paths for this file
paths = get_relative_paths(original_paths, relative_to=filename)
- with DocsWriter(filename, type_to_path_function=get_path_for_type) as docs:
+ with DocsWriter(filename, type_to_path_function=get_path_for_type) \
+ as docs:
docs.write_head(
title=get_class_name(tlobject),
relative_css_path=paths['css'])
@@ -274,8 +292,9 @@ def generate_documentation(scheme_file):
inner = tlobject.result
docs.begin_table(column_count=1)
- docs.add_row(inner,
- link=get_path_for_type(inner, relative_to=filename))
+ docs.add_row(inner, link=get_path_for_type(
+ inner, relative_to=filename
+ ))
docs.end_table()
constructors = tltypes.get(inner, [])
@@ -294,9 +313,12 @@ def generate_documentation(scheme_file):
docs.end_table()
# Return (or similar types) written. Now parameters/members
- docs.write_title('Parameters' if tlobject.is_function else 'Members', level=3)
+ docs.write_title(
+ 'Parameters' if tlobject.is_function else 'Members', level=3
+ )
- # Sort the arguments in the same way they're sorted on the generated code (flags go last)
+ # Sort the arguments in the same way they're sorted
+ # on the generated code (flags go last)
args = [
a for a in tlobject.sorted_args()
if not a.flag_indicator and not a.generic_definition
@@ -315,22 +337,13 @@ def generate_documentation(scheme_file):
if arg.is_generic:
docs.add_row('!' + arg.type, align='center')
else:
- docs.add_row(arg.type,
- link=get_path_for_type(arg.type, relative_to=filename),
- align='center')
+ docs.add_row(
+ arg.type, align='center', link=
+ get_path_for_type(arg.type, relative_to=filename)
+ )
- # Create a description for this argument
- description = ''
- if arg.can_be_inferred:
- description += 'If left to None, it will be inferred automatically. '
- if arg.is_vector:
- description += 'A list must be supplied for this argument. '
- if arg.is_generic:
- description += 'A different MTProtoRequest must be supplied for this argument. '
- if arg.is_flag:
- description += 'This argument can be omitted. '
-
- docs.add_row(description.strip())
+ # Add a description for this argument
+ docs.add_row(get_description(arg))
docs.end_table()
else:
@@ -342,14 +355,14 @@ def generate_documentation(scheme_file):
docs.end_body()
# Find all the available types (which are not the same as the constructors)
- # Each type has a list of constructors associated to it, so it should be a map
+ # Each type has a list of constructors associated to it, hence is a map
print('Generating types documentation...')
for tltype, constructors in tltypes.items():
filename = get_path_for_type(tltype)
out_dir = os.path.dirname(filename)
os.makedirs(out_dir, exist_ok=True)
- # Since we don't have access to the full TLObject, split the type into namespace.name
+ # Since we don't have access to the full TLObject, split the type
if '.' in tltype:
namespace, name = tltype.split('.')
else:
@@ -358,7 +371,8 @@ def generate_documentation(scheme_file):
# Determine the relative paths for this file
paths = get_relative_paths(original_paths, relative_to=out_dir)
- with DocsWriter(filename, type_to_path_function=get_path_for_type) as docs:
+ with DocsWriter(filename, type_to_path_function=get_path_for_type) \
+ as docs:
docs.write_head(
title=get_class_name(name),
relative_css_path=paths['css'])
@@ -376,7 +390,8 @@ def generate_documentation(scheme_file):
elif len(constructors) == 1:
docs.write_text('This type has one constructor available.')
else:
- docs.write_text('This type has %d constructors available.' % len(constructors))
+ docs.write_text('This type has %d constructors available.' %
+ len(constructors))
docs.begin_table(2)
for constructor in constructors:
@@ -394,7 +409,10 @@ def generate_documentation(scheme_file):
elif len(functions) == 1:
docs.write_text('Only the following method returns this type.')
else:
- docs.write_text('The following %d methods return this type as a result.' % len(functions))
+ docs.write_text(
+ 'The following %d methods return this type as a result.' %
+ len(functions)
+ )
docs.begin_table(2)
for func in functions:
@@ -456,8 +474,8 @@ def generate_documentation(scheme_file):
docs.end_table()
docs.end_body()
- # After everything's been written, generate an index.html file for every folder.
- # This will be done automatically and not taking into account any additional
+ # After everything's been written, generate an index.html per folder.
+ # This will be done automatically and not taking into account any extra
# information that we have available, simply a file listing all the others
# accessible by clicking on their title
print('Generating indices...')
@@ -485,13 +503,16 @@ def generate_documentation(scheme_file):
methods = sorted(methods, key=lambda m: m.name)
constructors = sorted(constructors, key=lambda c: c.name)
- request_names = ', '.join('"' + get_class_name(m) + '"' for m in methods)
- type_names = ', '.join('"' + get_class_name(t) + '"' for t in types)
- constructor_names = ', '.join('"' + get_class_name(t) + '"' for t in constructors)
+ def fmt(xs, formatter):
+ return ', '.join('"{}"'.format(formatter(x)) for x in xs)
- request_urls = ', '.join('"' + get_create_path_for(m) + '"' for m in methods)
- type_urls = ', '.join('"' + get_path_for_type(t) + '"' for t in types)
- constructor_urls = ', '.join('"' + get_create_path_for(t) + '"' for t in constructors)
+ request_names = fmt(methods, get_class_name)
+ type_names = fmt(types, get_class_name)
+ constructor_names = fmt(constructors, get_class_name)
+
+ request_urls = fmt(methods, get_create_path_for)
+ type_urls = fmt(types, get_create_path_for)
+ constructor_urls = fmt(constructors, get_create_path_for)
replace_dict = {
'type_count': len(types),
diff --git a/run_tests.py b/run_tests.py
index 3a3ab0da..d99cfb56 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -2,7 +2,9 @@
import unittest
if __name__ == '__main__':
- from telethon_tests import CryptoTests, ParserTests, TLTests, UtilsTests, NetworkTests
+ from telethon_tests import \
+ CryptoTests, ParserTests, TLTests, UtilsTests, NetworkTests
+
test_classes = [CryptoTests, ParserTests, TLTests, UtilsTests]
network = input('Run network tests (y/n)?: ').lower() == 'y'
diff --git a/telethon/crypto/auth_key.py b/telethon/crypto/auth_key.py
index 0ce021a4..02774d58 100644
--- a/telethon/crypto/auth_key.py
+++ b/telethon/crypto/auth_key.py
@@ -14,7 +14,9 @@ class AuthKey:
self.key_id = reader.read_long(signed=False)
def calc_new_nonce_hash(self, new_nonce, number):
- """Calculates the new nonce hash based on the current class fields' values"""
+ """Calculates the new nonce hash based on
+ the current class fields' values
+ """
with BinaryWriter() as writer:
writer.write(new_nonce)
writer.write_byte(number)
diff --git a/telethon/crypto/cdn_decrypter.py b/telethon/crypto/cdn_decrypter.py
index 40653c01..ba12a5d9 100644
--- a/telethon/crypto/cdn_decrypter.py
+++ b/telethon/crypto/cdn_decrypter.py
@@ -31,7 +31,8 @@ class CdnDecrypter:
# https://core.telegram.org/cdn
cdn_aes = AESModeCTR(
key=cdn_redirect.encryption_key,
- iv=cdn_redirect.encryption_iv[:12] + (offset >> 4).to_bytes(4, 'big')
+ iv=
+ cdn_redirect.encryption_iv[:12] + (offset >> 4).to_bytes(4, 'big')
)
# Create a new client on said CDN
diff --git a/telethon/crypto/factorization.py b/telethon/crypto/factorization.py
index 12a03af3..69c8dcc9 100644
--- a/telethon/crypto/factorization.py
+++ b/telethon/crypto/factorization.py
@@ -61,7 +61,9 @@ class Factorization:
@staticmethod
def factorize(pq):
- """Factorizes the given number and returns both the divisor and the number divided by the divisor"""
+ """Factorizes the given number and returns both
+ the divisor and the number divided by the divisor
+ """
if sympy:
return tuple(sympy.ntheory.factorint(pq).keys())
else:
diff --git a/telethon/crypto/rsa.py b/telethon/crypto/rsa.py
index 43340b4a..d8b95855 100644
--- a/telethon/crypto/rsa.py
+++ b/telethon/crypto/rsa.py
@@ -10,7 +10,7 @@ from ..extensions import BinaryWriter
# {fingerprint: Crypto.PublicKey.RSA._RSAobj} dictionary
-_server_keys = { }
+_server_keys = {}
def get_byte_array(integer):
diff --git a/telethon/errors/common.py b/telethon/errors/common.py
index 748c4309..fc0a8e5f 100644
--- a/telethon/errors/common.py
+++ b/telethon/errors/common.py
@@ -30,7 +30,8 @@ class InvalidChecksumError(Exception):
def __init__(self, checksum, valid_checksum):
super().__init__(
self,
- 'Invalid checksum ({} when {} was expected). This packet should be skipped.'
+ 'Invalid checksum ({} when {} was expected). '
+ 'This packet should be skipped.'
.format(checksum, valid_checksum))
self.checksum = checksum
diff --git a/telethon/extensions/binary_reader.py b/telethon/extensions/binary_reader.py
index c3016527..6770115c 100644
--- a/telethon/extensions/binary_reader.py
+++ b/telethon/extensions/binary_reader.py
@@ -26,7 +26,8 @@ class BinaryReader:
# region Reading
- # "All numbers are written as little endian." |> Source: https://core.telegram.org/mtproto
+ # "All numbers are written as little endian."
+ # https://core.telegram.org/mtproto
def read_byte(self):
"""Reads a single byte value"""
return self.read(1)[0]
@@ -56,8 +57,7 @@ class BinaryReader:
"""Read the given amount of bytes"""
result = self.reader.read(length)
if len(result) != length:
- raise BufferError(
- 'Trying to read outside the data bounds (no more data left to read)')
+ raise BufferError('No more data left to read')
return result
@@ -70,7 +70,9 @@ class BinaryReader:
# region Telegram custom reading
def tgread_bytes(self):
- """Reads a Telegram-encoded byte array, without the need of specifying its length"""
+ """Reads a Telegram-encoded byte array,
+ without the need of specifying its length
+ """
first_byte = self.read_byte()
if first_byte == 254:
length = self.read_byte() | (self.read_byte() << 8) | (
@@ -102,7 +104,9 @@ class BinaryReader:
raise ValueError('Invalid boolean code {}'.format(hex(value)))
def tgread_date(self):
- """Reads and converts Unix time (used by Telegram) into a Python datetime object"""
+ """Reads and converts Unix time (used by Telegram)
+ into a Python datetime object
+ """
value = self.read_int()
return None if value == 0 else datetime.fromtimestamp(value)
@@ -152,7 +156,9 @@ class BinaryReader:
self.reader.seek(position)
def seek(self, offset):
- """Seeks the stream position given an offset from the current position. May be negative"""
+ """Seeks the stream position given an offset from the
+ current position. The offset may be negative
+ """
self.reader.seek(offset, os.SEEK_CUR)
# endregion
diff --git a/telethon/extensions/binary_writer.py b/telethon/extensions/binary_writer.py
index 4a24616a..a1934a63 100644
--- a/telethon/extensions/binary_writer.py
+++ b/telethon/extensions/binary_writer.py
@@ -22,21 +22,22 @@ class BinaryWriter:
# region Writing
- # "All numbers are written as little endian." |> Source: https://core.telegram.org/mtproto
+ # "All numbers are written as little endian."
+ # https://core.telegram.org/mtproto
def write_byte(self, value):
"""Writes a single byte value"""
self.writer.write(pack('B', value))
self.written_count += 1
def write_int(self, value, signed=True):
- """Writes an integer value (4 bytes), which can or cannot be signed"""
+ """Writes an integer value (4 bytes), optionally signed"""
self.writer.write(
int.to_bytes(
value, length=4, byteorder='little', signed=signed))
self.written_count += 4
def write_long(self, value, signed=True):
- """Writes a long integer value (8 bytes), which can or cannot be signed"""
+ """Writes a long integer value (8 bytes), optionally signed"""
self.writer.write(
int.to_bytes(
value, length=8, byteorder='little', signed=signed))
@@ -101,7 +102,9 @@ class BinaryWriter:
self.write_int(0x997275b5 if boolean else 0xbc799737, signed=False)
def tgwrite_date(self, datetime):
- """Converts a Python datetime object into Unix time (used by Telegram) and writes it"""
+ """Converts a Python datetime object into Unix time
+ (used by Telegram) and writes it
+ """
value = 0 if datetime is None else int(datetime.timestamp())
self.write_int(value)
@@ -127,14 +130,18 @@ class BinaryWriter:
self.writer.close()
def get_bytes(self, flush=True):
- """Get the current bytes array content from the buffer, optionally flushing first"""
+ """Get the current bytes array content from the buffer,
+ optionally flushing first
+ """
if flush:
self.writer.flush()
return self.writer.raw.getvalue()
def get_written_bytes_count(self):
"""Gets the count of bytes written in the buffer.
- This may NOT be equal to the stream length if one was provided when initializing the writer"""
+ This may NOT be equal to the stream length if one
+ was provided when initializing the writer
+ """
return self.written_count
# with block
diff --git a/telethon/helpers.py b/telethon/helpers.py
index 4fe81754..3212bf4b 100644
--- a/telethon/helpers.py
+++ b/telethon/helpers.py
@@ -22,7 +22,9 @@ def ensure_parent_dir_exists(file_path):
def calc_key(shared_key, msg_key, client):
- """Calculate the key based on Telegram guidelines, specifying whether it's the client or not"""
+ """Calculate the key based on Telegram guidelines,
+ specifying whether it's the client or not
+ """
x = 0 if client else 8
sha1a = sha1(msg_key + shared_key[x:x + 32]).digest()
@@ -56,7 +58,9 @@ def generate_key_data_from_nonce(server_nonce, new_nonce):
def get_password_hash(pw, current_salt):
"""Gets the password hash for the two-step verification.
- current_salt should be the byte array provided by invoking GetPasswordRequest()"""
+ current_salt should be the byte array provided by
+ invoking GetPasswordRequest()
+ """
# Passwords are encoded as UTF-8
# At https://github.com/DrKLO/Telegram/blob/e31388
diff --git a/telethon/network/authenticator.py b/telethon/network/authenticator.py
index 6b065b9a..a665fd38 100644
--- a/telethon/network/authenticator.py
+++ b/telethon/network/authenticator.py
@@ -217,6 +217,8 @@ def do_authentication(connection):
def get_int(byte_array, signed=True):
- """Gets the specified integer from its byte array. This should be used by the authenticator,
- who requires the data to be in big endian"""
+ """Gets the specified integer from its byte array.
+ This should be used by the authenticator,
+ who requires the data to be in big endian
+ """
return int.from_bytes(byte_array, byteorder='big', signed=signed)
diff --git a/telethon/network/connection.py b/telethon/network/connection.py
index 77ef349d..c3cb5a9f 100644
--- a/telethon/network/connection.py
+++ b/telethon/network/connection.py
@@ -61,7 +61,8 @@ class Connection:
setattr(self, 'send', self._send_intermediate)
setattr(self, 'recv', self._recv_intermediate)
- elif mode in (ConnectionMode.TCP_ABRIDGED, ConnectionMode.TCP_OBFUSCATED):
+ elif mode in (ConnectionMode.TCP_ABRIDGED,
+ ConnectionMode.TCP_OBFUSCATED):
setattr(self, 'send', self._send_abridged)
setattr(self, 'recv', self._recv_abridged)
@@ -90,8 +91,8 @@ class Connection:
while True:
random = os.urandom(64)
if (random[0] != b'\xef' and
- random[:4] not in keywords and
- random[4:4] != b'\0\0\0\0'):
+ random[:4] not in keywords and
+ random[4:4] != b'\0\0\0\0'):
# Invalid random generated
break
diff --git a/telethon/network/mtproto_plain_sender.py b/telethon/network/mtproto_plain_sender.py
index c387287e..77600abd 100644
--- a/telethon/network/mtproto_plain_sender.py
+++ b/telethon/network/mtproto_plain_sender.py
@@ -4,7 +4,9 @@ from ..extensions import BinaryReader, BinaryWriter
class MtProtoPlainSender:
- """MTProto Mobile Protocol plain sender (https://core.telegram.org/mtproto/description#unencrypted-messages)"""
+ """MTProto Mobile Protocol plain sender
+ (https://core.telegram.org/mtproto/description#unencrypted-messages)
+ """
def __init__(self, connection):
self._sequence = 0
@@ -19,7 +21,9 @@ class MtProtoPlainSender:
self._connection.close()
def send(self, data):
- """Sends a plain packet (auth_key_id = 0) containing the given message body (data)"""
+ """Sends a plain packet (auth_key_id = 0) containing the
+ given message body (data)
+ """
with BinaryWriter(known_length=len(data) + 20) as writer:
writer.write_long(0)
writer.write_long(self._get_new_msg_id())
diff --git a/telethon/network/mtproto_sender.py b/telethon/network/mtproto_sender.py
index c849cda9..8154d4f5 100644
--- a/telethon/network/mtproto_sender.py
+++ b/telethon/network/mtproto_sender.py
@@ -31,7 +31,7 @@ class MtProtoSender:
# Store an RLock instance to make this class safely multi-threaded
self._lock = RLock()
- # Used when logging out, the only request that seems to use 'ack' requests
+ # Used when logging out, the only request that seems to use 'ack'
# TODO There might be a better way to handle msgs_ack requests
self.logging_out = False
@@ -114,7 +114,10 @@ class MtProtoSender:
def _send_packet(self, packet, request):
"""Sends the given packet bytes with the additional
- information of the original request. This does NOT lock the threads!"""
+ information of the original request.
+
+ This does NOT lock the threads!
+ """
request.request_msg_id = self.session.get_new_msg_id()
# First calculate plain_text to encrypt it
@@ -183,7 +186,7 @@ class MtProtoSender:
reader.seek(-4)
# The following codes are "parsed manually"
- if code == 0xf35c6d01: # rpc_result, (response of an RPC call, i.e., we sent a request)
+ if code == 0xf35c6d01: # rpc_result, (response of an RPC call)
return self._handle_rpc_result(msg_id, sequence, reader)
if code == 0x347773c5: # pong
@@ -219,11 +222,15 @@ class MtProtoSender:
if code in tlobjects:
result = reader.tgread_object()
if self.unhandled_callbacks:
- self._logger.debug('Passing TLObject to callbacks %s', repr(result))
+ self._logger.debug(
+ 'Passing TLObject to callbacks %s', repr(result)
+ )
for callback in self.unhandled_callbacks:
callback(result)
else:
- self._logger.debug('Ignoring unhandled TLObject %s', repr(result))
+ self._logger.debug(
+ 'Ignoring unhandled TLObject %s', repr(result)
+ )
return True
diff --git a/telethon/telegram_bare_client.py b/telethon/telegram_bare_client.py
index 1a783182..647e6c22 100644
--- a/telethon/telegram_bare_client.py
+++ b/telethon/telegram_bare_client.py
@@ -184,8 +184,9 @@ class TelegramBareClient:
except (RPCError, ConnectionError) as error:
# Probably errors from the previous session, ignore them
self.disconnect()
- self._logger.debug('Could not stabilise initial connection: {}'
- .format(error))
+ self._logger.debug(
+ 'Could not stabilise initial connection: {}'.format(error)
+ )
return None if initial_query else False
def disconnect(self):
@@ -493,7 +494,7 @@ class TelegramBareClient:
CdnDecrypter.prepare_decrypter(
client, TelegramBareClient, result,
offset, part_size
- )
+ )
except FileMigrateError as e:
client = self._get_exported_client(e.new_dc)
@@ -515,8 +516,10 @@ class TelegramBareClient:
progress_callback(f.tell(), file_size)
finally:
if cdn_decrypter:
- try: cdn_decrypter.client.disconnect()
- except: pass
+ try:
+ cdn_decrypter.client.disconnect()
+ except:
+ pass
if isinstance(file, str):
f.close()
diff --git a/telethon/telegram_client.py b/telethon/telegram_client.py
index 1ca46500..fc0999f1 100644
--- a/telethon/telegram_client.py
+++ b/telethon/telegram_client.py
@@ -124,7 +124,6 @@ class TelegramClient(TelegramBareClient):
# Constantly read for results and updates from within the main client
self._recv_thread = None
-
# endregion
# region Connecting
diff --git a/telethon/tl/session.py b/telethon/tl/session.py
index 445afdae..0897012f 100644
--- a/telethon/tl/session.py
+++ b/telethon/tl/session.py
@@ -73,8 +73,8 @@ class Session:
'time_offset': self.time_offset,
'server_address': self.server_address,
'auth_key_data':
- b64encode(self.auth_key.key).decode('ascii')\
- if self.auth_key else None
+ b64encode(self.auth_key.key).decode('ascii')
+ if self.auth_key else None
}, file)
def delete(self):
diff --git a/telethon_generator/parser/source_builder.py b/telethon_generator/parser/source_builder.py
index cf8466d0..2b62cf61 100644
--- a/telethon_generator/parser/source_builder.py
+++ b/telethon_generator/parser/source_builder.py
@@ -11,21 +11,27 @@ class SourceBuilder:
self.auto_added_line = False
def indent(self):
- """Indents the current source code line by the current indentation level"""
+ """Indents the current source code line
+ by the current indentation level
+ """
self.write(' ' * (self.current_indent * self.indent_size))
def write(self, string):
- """Writes a string into the source code, applying indentation if required"""
+ """Writes a string into the source code,
+ applying indentation if required
+ """
if self.on_new_line:
self.on_new_line = False # We're not on a new line anymore
- if string.strip(
- ): # If the string was not empty, indent; Else it probably was a new line
+ # If the string was not empty, indent; Else probably a new line
+ if string.strip():
self.indent()
self.out_stream.write(string)
def writeln(self, string=''):
- """Writes a string into the source code _and_ appends a new line, applying indentation if required"""
+ """Writes a string into the source code _and_ appends a new line,
+ applying indentation if required
+ """
self.write(string + '\n')
self.on_new_line = True
diff --git a/telethon_generator/parser/tl_parser.py b/telethon_generator/parser/tl_parser.py
index ae6a5b83..a08521db 100644
--- a/telethon_generator/parser/tl_parser.py
+++ b/telethon_generator/parser/tl_parser.py
@@ -11,7 +11,8 @@ class TLParser:
"""This method yields TLObjects from a given .tl file"""
with open(file_path, encoding='utf-8') as file:
- # Start by assuming that the next found line won't be a function (and will hence be a type)
+ # Start by assuming that the next found line won't
+ # be a function (and will hence be a type)
is_function = False
# Read all the lines from the .tl file
@@ -21,7 +22,8 @@ class TLParser:
# Ensure that the line is not a comment
if line and not line.startswith('//'):
- # Check whether the line is a type change (types ⋄ functions) or not
+ # Check whether the line is a type change
+ # (types <-> functions) or not
match = re.match('---(\w+)---', line)
if match:
following_types = match.group(1)
diff --git a/telethon_generator/tl_generator.py b/telethon_generator/tl_generator.py
index b9aef7af..46c5656f 100644
--- a/telethon_generator/tl_generator.py
+++ b/telethon_generator/tl_generator.py
@@ -405,15 +405,14 @@ class TLGenerator:
@staticmethod
def get_class_name(tlobject):
- """Gets the class name following the Python style guidelines, in ThisClassFormat"""
+ """Gets the class name following the Python style guidelines"""
# Courtesy of http://stackoverflow.com/a/31531797/4759433
- # Also, '_' could be replaced for ' ', then use .title(), and then remove ' '
result = re.sub(r'_([a-z])', lambda m: m.group(1).upper(),
tlobject.name)
result = result[:1].upper() + result[1:].replace(
'_', '') # Replace again to fully ensure!
- # If it's a function, let it end with "Request" to identify them more easily
+ # If it's a function, let it end with "Request" to identify them
if tlobject.is_function:
result += 'Request'
return result
@@ -436,9 +435,11 @@ class TLGenerator:
Writes the write code for the given argument
:param builder: The source code builder
:param arg: The argument to write
- :param args: All the other arguments in TLObject same on_send. This is required to determine the flags value
+ :param args: All the other arguments in TLObject same on_send.
+ This is required to determine the flags value
:param name: The name of the argument. Defaults to "self.argname"
- This argument is an option because it's required when writing Vectors<>
+ This argument is an option because it's required when
+ writing Vectors<>
"""
if arg.generic_definition:
@@ -447,8 +448,10 @@ class TLGenerator:
if name is None:
name = 'self.{}'.format(arg.name)
- # The argument may be a flag, only write if it's not None AND if it's not a True type
- # True types are not actually sent, but instead only used to determine the flags
+ # The argument may be a flag, only write if it's not None AND
+ # if it's not a True type.
+ # True types are not actually sent, but instead only used to
+ # determine the flags.
if arg.is_flag:
if arg.type == 'true':
return # Exit, since True type is never written
@@ -457,8 +460,7 @@ class TLGenerator:
if arg.is_vector:
if arg.use_vector_id:
- builder.writeln(
- "writer.write_int(0x1cb5c415, signed=False) # Vector's constructor ID")
+ builder.writeln('writer.write_int(0x1cb5c415, signed=False)')
builder.writeln('writer.write_int(len({}))'.format(name))
builder.writeln('for _x in {}:'.format(name))
@@ -501,7 +503,7 @@ class TLGenerator:
elif 'Bool' == arg.type:
builder.writeln('writer.tgwrite_bool({})'.format(name))
- elif 'true' == arg.type: # Awkwardly enough, Telegram has both bool and "true", used in flags
+ elif 'true' == arg.type:
pass # These are actually NOT written! Only used for flags
elif 'bytes' == arg.type:
@@ -528,9 +530,11 @@ class TLGenerator:
:param builder: The source code builder
:param arg: The argument to write
- :param args: All the other arguments in TLObject same on_send. This is required to determine the flags value
+ :param args: All the other arguments in TLObject same on_send.
+ This is required to determine the flags value
:param name: The name of the argument. Defaults to "self.argname"
- This argument is an option because it's required when writing Vectors<>
+ This argument is an option because it's required when
+ writing Vectors<>
"""
if arg.generic_definition:
@@ -544,8 +548,10 @@ class TLGenerator:
if arg.is_flag:
was_flag = True
builder.writeln('if (flags & (1 << {})) != 0:'.format(
- arg.flag_index))
- # Temporary disable .is_flag not to enter this if again when calling the method recursively
+ arg.flag_index
+ ))
+ # Temporary disable .is_flag not to enter this if
+ # again when calling the method recursively
arg.is_flag = False
if arg.is_vector:
@@ -621,7 +627,8 @@ class TLGenerator:
Writes the receive code for the given function
:param builder: The source code builder
- :param tlobject: The TLObject for which the 'self.result = ' will be written
+ :param tlobject: The TLObject for which the 'self.result = '
+ will be written
"""
if tlobject.result.startswith('Vector<'):
# Vector results are a bit special since they can also be composed
@@ -631,13 +638,15 @@ class TLGenerator:
if tlobject.result == 'Vector':
builder.writeln('reader.read_int() # Vector id')
builder.writeln('count = reader.read_int()')
- builder.writeln('self.result = [reader.read_int() for _ in range(count)]')
-
+ builder.writeln(
+ 'self.result = [reader.read_int() for _ in range(count)]'
+ )
elif tlobject.result == 'Vector':
builder.writeln('reader.read_int() # Vector id')
builder.writeln('count = reader.read_long()')
- builder.writeln('self.result = [reader.read_long() for _ in range(count)]')
-
+ builder.writeln(
+ 'self.result = [reader.read_long() for _ in range(count)]'
+ )
else:
builder.writeln('self.result = reader.tgread_vector()')
else:
diff --git a/telethon_tests/higher_level_test.py b/telethon_tests/higher_level_test.py
index edd5073b..7bd4b181 100644
--- a/telethon_tests/higher_level_test.py
+++ b/telethon_tests/higher_level_test.py
@@ -13,8 +13,8 @@ api_hash = None
if not api_id or not api_hash:
raise ValueError('Please fill in both your api_id and api_hash.')
-class HigherLevelTests(unittest.TestCase):
+class HigherLevelTests(unittest.TestCase):
@staticmethod
def test_cdn_download():
client = TelegramClient(None, api_id, api_hash)
@@ -24,7 +24,7 @@ class HigherLevelTests(unittest.TestCase):
try:
phone = '+999662' + str(randint(0, 9999)).zfill(4)
client.send_code_request(phone)
- client.sign_up(phone, '22222', 'Test', 'DC')
+ client.sign_up('22222', 'Test', 'DC')
me = client.get_me()
data = os.urandom(2 ** 17)