From 5feb2104421f73de7581ab6ec23bae48590ef2fd Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Thu, 12 May 2022 10:20:42 +0200 Subject: [PATCH] Add support for flags2 in the TL --- telethon_generator/generators/docs.py | 2 +- telethon_generator/generators/tlobject.py | 57 +++++++++---------- telethon_generator/parsers/tlobject/tlarg.py | 26 ++++----- .../parsers/tlobject/tlobject.py | 5 +- 4 files changed, 44 insertions(+), 46 deletions(-) diff --git a/telethon_generator/generators/docs.py b/telethon_generator/generators/docs.py index 34b599ff..af6ebff7 100755 --- a/telethon_generator/generators/docs.py +++ b/telethon_generator/generators/docs.py @@ -164,7 +164,7 @@ def _get_description(arg): if arg.can_be_inferred: desc.append('If left unspecified, it will be inferred automatically.') otherwise = True - elif arg.is_flag: + elif arg.flag: desc.append('This argument defaults to ' 'None and can be omitted.') otherwise = True diff --git a/telethon_generator/generators/tlobject.py b/telethon_generator/generators/tlobject.py index 4326b189..535ff38d 100644 --- a/telethon_generator/generators/tlobject.py +++ b/telethon_generator/generators/tlobject.py @@ -187,9 +187,9 @@ def _write_class_init(tlobject, kind, type_constructors, builder): crc32(tlobject.result.encode('ascii'))) builder.writeln() - # Convert the args to string parameters, flags having =None + # Convert the args to string parameters, those with flag having =None args = ['{}: {}{}'.format( - a.name, a.type_hint(), '=None' if a.is_flag or a.can_be_inferred else '') + a.name, a.type_hint(), '=None' if a.flag or a.can_be_inferred else '') for a in tlobject.real_args ] @@ -266,7 +266,7 @@ def _write_resolve(tlobject, builder): if not ac: continue - if arg.is_flag: + if arg.flag: builder.writeln('if self.{}:', arg.name) if arg.is_vector: @@ -279,7 +279,7 @@ def _write_resolve(tlobject, builder): builder.writeln('self.{} = {}', arg.name, ac.format('self.' + arg.name)) - if arg.is_flag: + if arg.flag: builder.end_block() builder.end_block() @@ -327,8 +327,8 @@ def _write_to_bytes(tlobject, builder): # at the same time. In this case, add an assertion. repeated_args = defaultdict(list) for arg in tlobject.args: - if arg.is_flag: - repeated_args[arg.flag_index].append(arg) + if arg.flag: + repeated_args[(arg.flag, arg.flag_index)].append(arg) for ra in repeated_args.values(): if len(ra) > 1: @@ -416,7 +416,7 @@ def _write_arg_to_bytes(builder, arg, tlobject, name=None): # 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.flag: if arg.type == 'true': return # Exit, since True type is never written elif arg.is_vector: @@ -444,31 +444,31 @@ def _write_arg_to_bytes(builder, arg, tlobject, name=None): builder.write("b''.join(") # Temporary disable .is_vector, not to enter this if again - # Also disable .is_flag since it's not needed per element - old_flag = arg.is_flag - arg.is_vector = arg.is_flag = False + # Also disable .flag since it's not needed per element + old_flag, arg.flag = arg.flag, None + arg.is_vector = False _write_arg_to_bytes(builder, arg, tlobject, name='x') arg.is_vector = True - arg.is_flag = old_flag + arg.flag = old_flag builder.write(' for x in {})', name) elif arg.flag_indicator: # Calculate the flags with those items which are not None - if not any(f.is_flag for f in tlobject.args): + if not any(f.flag for f in tlobject.args): # There's a flag indicator, but no flag arguments so it's 0 builder.write(r"b'\0\0\0\0'") else: - def fmt_flag(flag): - if flag.type == 'Bool': + def fmt_flag_arg(a): + if a.type == 'Bool': fmt = '(0 if {0} is None else {1})' else: fmt = '(0 if {0} is None or {0} is False else {1})' - return fmt.format('self.{}'.format(flag.name), 1 << flag.flag_index) + return fmt.format('self.{}'.format(a.name), 1 << a.flag_index) builder.write("struct.pack('.]+)', self.type) + # The type may be a flag (FLAGS.IDX?REAL_TYPE) + # FLAGS can be any name, but it should have appeared previously. + flag_match = re.match(r'(\w+).(\d+)\?([\w<>.]+)', self.type) if flag_match: - self.is_flag = True - self.flag_index = int(flag_match.group(1)) + self.flag = flag_match.group(1) + self.flag_index = int(flag_match.group(2)) # Update the type to match the exact type, not the "flagged" one - self.type = flag_match.group(2) + self.type = flag_match.group(3) # Then check if the type is a Vector vector_match = re.match(r'[Vv]ector<([\w\d.]+)>', self.type) @@ -180,7 +178,7 @@ class TLArg: }.get(cls, "'Type{}'".format(cls)) if self.is_vector: result = 'List[{}]'.format(result) - if self.is_flag and cls != 'date': + if self.flag and cls != 'date': result = 'Optional[{}]'.format(result) return result @@ -200,8 +198,8 @@ class TLArg: if self.is_generic: real_type = '!{}'.format(real_type) - if self.is_flag: - real_type = 'flags.{}?{}'.format(self.flag_index, real_type) + if self.flag: + real_type = '{}.{}?{}'.format(self.flag, self.flag_index, real_type) return real_type @@ -244,5 +242,5 @@ class TLArg: self.cls[0].as_example(f, indent) def omit_example(self): - return (self.is_flag or self.can_be_inferred) \ + return (self.flag or self.can_be_inferred) \ and self.name in OMITTED_EXAMPLES diff --git a/telethon_generator/parsers/tlobject/tlobject.py b/telethon_generator/parsers/tlobject/tlobject.py index da6c5f65..d30b1b4a 100644 --- a/telethon_generator/parsers/tlobject/tlobject.py +++ b/telethon_generator/parsers/tlobject/tlobject.py @@ -72,7 +72,7 @@ class TLObject: can be inferred will go last so they can default =None) """ return sorted(self.args, - key=lambda x: x.is_flag or x.can_be_inferred) + key=lambda x: bool(x.flag) or x.can_be_inferred) def __repr__(self, ignore_id=False): if self.id is None or ignore_id: @@ -95,8 +95,9 @@ class TLObject: .replace('<', ' ').replace('>', '')\ .replace('{', '').replace('}', '') + # Remove optional empty values (special-cased to the true type) representation = re.sub( - r' \w+:flags\.\d+\?true', + r' \w+:\w+\.\d+\?true', r'', representation )