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
)