From 68a625b82bba0f8c013a0da1a07b80b7d1754012 Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Mon, 12 Jun 2017 10:16:24 +0200 Subject: [PATCH] Try to adhere to the 80-characters limit --- telethon_generator/tl_generator.py | 106 +++++++++++++++++------------ 1 file changed, 64 insertions(+), 42 deletions(-) diff --git a/telethon_generator/tl_generator.py b/telethon_generator/tl_generator.py index 76fdf5dc..8adf3dfe 100755 --- a/telethon_generator/tl_generator.py +++ b/telethon_generator/tl_generator.py @@ -19,7 +19,9 @@ output_base_depth = 2 # telethon/tl/ class TLGenerator: @staticmethod def tlobjects_exist(): - """Determines whether the TLObjects were previously generated (hence exist) or not""" + """Determines whether the TLObjects were previously + generated (hence exist) or not + """ return os.path.isfile(get_output_path('all_tlobjects.py')) @staticmethod @@ -36,25 +38,28 @@ class TLGenerator: @staticmethod def generate_tlobjects(scheme_file): - """Generates all the TLObjects from scheme.tl to tl/functions and tl/types""" + """Generates all the TLObjects from scheme.tl to + tl/functions and tl/types + """ # First ensure that the required parent directories exist os.makedirs(get_output_path('functions'), exist_ok=True) os.makedirs(get_output_path('types'), exist_ok=True) - # Step 0: Store the parsed file in a tuple to avoid parsing it on each iteration + # Step 0: Cache the parsed file on a tuple tlobjects = tuple(TLParser.parse_file(scheme_file)) # Step 1: Ensure that no object has the same name as a namespace # We must check this because Python will complain if it sees a - # file and a directory with the same name, which happens for example with "updates" + # file and a directory with the same name, which happens for + # example with "updates". # # We distinguish between function and type namespaces since we # will later need to perform a relative import for them to be used function_namespaces = set() type_namespaces = set() - # Now that we're iterating over all the objects we also store Type: [Constructors] + # Make use of this iteration to also store 'Type: [Constructors]' type_constructors = defaultdict(list) for tlobject in tlobjects: if tlobject.is_function: @@ -72,8 +77,9 @@ class TLGenerator: for tlobject in tlobjects: if TLGenerator.get_file_name(tlobject, add_extension=False) \ in namespace_directories: - # If this TLObject isn't under the same directory as its name (i.e. "contacts"), - # append "_tg" to avoid confusion between the file and the directory (i.e. "updates") + # If this TLObject isn't under the same directory as its + # name (i.e. "contacts"), append "_tg" to avoid confusion + # between the file and the directory (i.e. "updates") if tlobject.namespace != tlobject.name: tlobject.name += '_tg' @@ -95,7 +101,7 @@ class TLGenerator: os.makedirs(out_dir, exist_ok=True) - # Also add this object to __init__.py, so we can import the whole packet at once + # Add this object to __init__.py, so we can import * init_py = os.path.join(out_dir, '__init__.py') with open(init_py, 'a', encoding='utf-8') as file: with SourceBuilder(file) as builder: @@ -112,7 +118,8 @@ class TLGenerator: with open(filename, 'w', encoding='utf-8') as file: # Let's build the source code! with SourceBuilder(file) as builder: - # Both types and functions inherit from MTProtoRequest so they all can be sent + # Both types and functions inherit from + # MTProtoRequest so they all can be sent builder.writeln('from {}.tl.mtproto_request import MTProtoRequest' .format('.' * depth)) @@ -125,27 +132,28 @@ class TLGenerator: builder.writeln('class {}(MTProtoRequest):'.format( TLGenerator.get_class_name(tlobject))) - # Write the original .tl definition, along with a "generated automatically" message + # Write the original .tl definition, + # along with a "generated automatically" message builder.writeln( '"""Class generated by TLObjects\' generator. ' - 'All changes will be ERASED. Original .tl definition below.') + 'All changes will be ERASED. TL definition below.') builder.writeln('{}"""'.format(repr(tlobject))) builder.writeln() - # Create an class-level variable that stores the TLObject's constructor ID + # Class-level variable to store its constructor ID builder.writeln( - "# Telegram's constructor ID (and unique identifier) for this class") + "# Telegram's constructor (U)ID for this class") builder.writeln('constructor_id = {}'.format( hex(tlobject.id))) builder.writeln() - # First sort the arguments so that those not being a flag come first + # Flag arguments must go last args = [ a for a in tlobject.sorted_args() if not a.flag_indicator and not a.generic_definition ] - # Then convert the args to string parameters, the flags having =None + # Convert the args to string parameters, flags having =None args = [ (a.name if not a.is_flag and not a.can_be_inferred else '{}=None'.format(a.name)) @@ -160,26 +168,32 @@ class TLGenerator: builder.writeln('def __init__(self):') # Now update args to have the TLObject arguments, _except_ - # those which are generated automatically: flag indicator and generic definitions. - # We don't need the generic definitions in Python because arguments can be any type + # those which are calculated on send or ignored, this is + # flag indicator and generic definitions. + # + # We don't need the generic definitions in Python + # because arguments can be any type args = [arg for arg in tlobject.args if not arg.flag_indicator and not arg.generic_definition] if args: - # Write the docstring, so we know the type of the arguments + # Write the docstring, to know the type of the args builder.writeln('"""') for arg in args: if not arg.flag_indicator: builder.write( - ':param {}: Telegram type: "{}".'.format( - arg.name, arg.type)) + ':param {}: Telegram type: "{}".' + .format(arg.name, arg.type) + ) if arg.is_vector: - builder.write(' Must be a list.'.format( - arg.name)) + builder.write( + ' Must be a list.'.format(arg.name) + ) if arg.is_generic: builder.write( - ' This should be another MTProtoRequest.') + ' Must be another MTProtoRequest.' + ) builder.writeln() # We also want to know what type this request returns @@ -243,21 +257,23 @@ class TLGenerator: if args: builder.writeln('return {') - base_types = ["string", "bytes", "int", "long", "int128", "int256", "double", "Bool", "true", - "date"] + base_types = ['string', 'bytes', 'int', 'long', + 'int128', 'int256', 'double', 'Bool', + 'true', 'date'] for arg in args: - builder.writeln("\'{}\': ".format(arg.name)) + builder.writeln("'{}': ".format(arg.name)) if arg.is_vector: - builder.writeln("[x{} for x in self.{}] if self.{} is not None else []," - .format(".to_dict() if x is not None else None" - if arg.type not in base_types else "", + builder.writeln('[x{} for x in self.{}] if self.{} is not None else [],' + .format('.to_dict() if x is not None else None' + if arg.type not in base_types else '', arg.name, arg.name)) else: - builder.writeln("self.{}{}," - .format(arg.name, - ".to_dict() if self.{} is not None else None".format(arg.name) - if arg.type not in base_types else "")) + builder.writeln( + 'self.{}{},'.format( + arg.name, + '.to_dict() if self.{} is not None else None' + .format(arg.name) if arg.type not in base_types else '')) builder.write("}") else: builder.writeln('return {}') @@ -280,7 +296,7 @@ class TLGenerator: builder.writeln('@staticmethod') builder.writeln('def empty():') builder.writeln( - '"""Returns an "empty" instance (all attributes are None)"""') + '"""Returns an "empty" instance (attributes=None)"""') builder.writeln('return {}({})'.format( TLGenerator.get_class_name(tlobject), ', '.join( 'None' for _ in range(len(args))))) @@ -288,7 +304,8 @@ class TLGenerator: # 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 + # Do not read constructor's ID, since + # that's already been read somewhere else if tlobject.is_function: TLGenerator.write_request_result_code(builder, tlobject) else: @@ -297,7 +314,8 @@ class TLGenerator: TLGenerator.write_onresponse_code( builder, arg, tlobject.args) else: - # If there were no arguments, we still need an on_response method, and hence "pass" if empty + # If there were no arguments, we still need an + # on_response method, and hence "pass" if empty builder.writeln('pass') builder.end_block() @@ -308,7 +326,7 @@ class TLGenerator: builder.writeln('def __str__(self):') builder.writeln('return {}'.format(str(tlobject))) - # builder.end_block() # There is no need to end the last block + # builder.end_block() # No need to end the last block # Step 3: Add the relative imports to the namespaces on __init__.py's init_py = os.path.join(get_output_path('functions'), '__init__.py') @@ -321,7 +339,8 @@ class TLGenerator: file.write('from . import {}\n' .format(', '.join(type_namespaces))) - # Step 4: Once all the objects have been generated, we can now group them in a single file + # Step 4: Once all the objects have been generated, + # we can now group them in a single file filename = os.path.join(get_output_path('all_tlobjects.py')) with open(filename, 'w', encoding='utf-8') as file: with SourceBuilder(file) as builder: @@ -349,7 +368,9 @@ class TLGenerator: constructor = '0x' + constructor[2:].zfill(8) builder.write('{}: '.format(constructor)) - builder.write('functions' if tlobject.is_function else 'types') + builder.write( + 'functions' if tlobject.is_function else 'types') + if tlobject.namespace: builder.write('.' + tlobject.namespace) @@ -582,9 +603,10 @@ class TLGenerator: :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 of - # integer values and such; however, the result of requests is not - # parsed as arguments are and it's a bit harder to tell which is which. + # Vector results are a bit special since they can also be composed + # of integer values and such; however, the result of requests is + # not parsed as arguments are and it's a bit harder to tell which + # is which. if tlobject.result == 'Vector': builder.writeln('reader.read_int() # Vector id') builder.writeln('count = reader.read_int()')