Avoid cyclic imports caused by #348 (fix #357)

This commit is contained in:
Lonami Exo 2017-10-24 10:07:31 +02:00
parent d58c729af0
commit b3ca68b7d9
3 changed files with 21 additions and 11 deletions

View File

@ -154,11 +154,10 @@ def generate_code(output, json_file, errors_desc):
patterns.append((pattern, name))
capture = capture_names.get(name, 'x') if has_captures else None
# TODO Some errors have the same name but different code,
# split this accross different files?
# split this across different files?
write_error(f, error_code, name, description, capture)
f.write('\n\nrpc_errors_all = {\n')
for pattern, name in patterns:
f.write(' {}: {},\n'.format(repr(pattern), name))
f.write('}\n')

View File

@ -104,8 +104,7 @@ class TLObject:
def class_name_for(typename, is_function=False):
"""Gets the class name following the Python style guidelines"""
# Courtesy of http://stackoverflow.com/a/31531797/4759433
result = re.sub(r'_([a-z])', lambda m: m.group(1).upper(),
typename)
result = re.sub(r'_([a-z])', lambda m: m.group(1).upper(), typename)
result = result[:1].upper() + result[1:].replace('_', '')
# If it's a function, let it end with "Request" to identify them
if is_function:

View File

@ -129,11 +129,6 @@ class TLGenerator:
builder.writeln(
'from {}.tl.tlobject import TLObject'.format('.' * depth)
)
if ns:
# Only import the parent types if we're not in such file
builder.writeln(
'from {}.tl import types'.format('.' * depth)
)
# Add the relative imports to the namespaces,
# unless we already are in a namespace.
@ -646,8 +641,25 @@ class TLGenerator:
if not arg.skip_constructor_id:
builder.writeln('{} = reader.tgread_object()'.format(name))
else:
builder.writeln('{} = types.{}.from_reader(reader)'.format(
name, TLObject.class_name_for(arg.type)))
# Import the correct type inline to avoid cyclic imports.
# There may be better solutions so that we can just access
# all the types before the files have been parsed, but I
# don't know of any.
sep_index = arg.type.find('.')
if sep_index == -1:
ns, t = '.', arg.type
else:
ns, t = '.' + arg.type[:sep_index], arg.type[sep_index+1:]
class_name = TLObject.class_name_for(t)
# There would be no need to import the type if we're in the
# file with the same namespace, but since it does no harm
# and we don't have information about such thing in the
# method we just ignore that case.
builder.writeln('from {} import {}'.format(ns, class_name))
builder.writeln('{} = {}.from_reader(reader)'.format(
name, class_name
))
# End vector and flag blocks if required (if we opened them before)
if arg.is_vector: