From c7b1d6f70a97674fc59afc21b1334cd10f024b87 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 5 Jan 2019 15:26:40 +0100 Subject: [PATCH] Take into account that flags:# could be not always the first argument For instance, in Layer 91, Poll's flags:# is at the second position. This mess also happened in the past (thanks tg devs) and eventually will be fixed again with the next Layer update, but from now on Pyrogram will be able to correctly generate code even in such cases. --- compiler/api/compiler.py | 52 +++++++++++++++++-------------- compiler/api/template/mtproto.txt | 2 -- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/compiler/api/compiler.py b/compiler/api/compiler.py index 57e4d22b..9e671e80 100644 --- a/compiler/api/compiler.py +++ b/compiler/api/compiler.py @@ -26,7 +26,7 @@ NOTICE_PATH = "NOTICE" SECTION_RE = re.compile(r"---(\w+)---") LAYER_RE = re.compile(r"//\sLAYER\s(\d+)") COMBINATOR_RE = re.compile(r"^([\w.]+)#([0-9a-f]+)\s(?:.*)=\s([\w<>.]+);(?: // Docs: (.+))?$", re.MULTILINE) -ARGS_RE = re.compile("[^{](\w+):([\w?!.<>]+)") +ARGS_RE = re.compile("[^{](\w+):([\w?!.<>#]+)") FLAGS_RE = re.compile(r"flags\.(\d+)\?") FLAGS_RE_2 = re.compile(r"flags\.(\d+)\?([\w<>.]+)") FLAGS_RE_3 = re.compile(r"flags:#") @@ -288,17 +288,20 @@ def start(): sorted_args = sort_args(c.args) arguments = ", " + ", ".join( - [get_argument_type(i) for i in sorted_args] + [get_argument_type(i) for i in sorted_args if i != ("flags", "#")] ) if c.args else "" fields = "\n ".join( - ["self.{0} = {0} # {1}".format(i[0], i[1]) for i in c.args] + ["self.{0} = {0} # {1}".format(i[0], i[1]) for i in c.args if i != ("flags", "#")] ) if c.args else "pass" docstring_args = [] docs = c.docs.split("|")[1:] if c.docs else None for i, arg in enumerate(sorted_args): + if arg == ("flags", "#"): + continue + arg_name, arg_type = arg is_optional = FLAGS_RE.match(arg_type) flag_number = is_optional.group(1) if is_optional else -1 @@ -338,28 +341,31 @@ def start(): if references: docstring_args += "\n\n See Also:\n This object can be returned by " + references + "." - if c.has_flags: - write_flags = [] - for i in c.args: - flag = FLAGS_RE.match(i[1]) - if flag: - write_flags.append("flags |= (1 << {}) if self.{} is not None else 0".format(flag.group(1), i[0])) - - write_flags = "\n ".join([ - "flags = 0", - "\n ".join(write_flags), - "b.write(Int(flags))" - ]) - else: - write_flags = "# No flags" - - read_flags = "flags = Int.read(b)" if c.has_flags else "# No flags" - - write_types = read_types = "" + write_types = read_types = "" if c.has_flags else "# No flags\n " for arg_name, arg_type in c.args: flag = FLAGS_RE_2.findall(arg_type) + if arg_name == "flags" and arg_type == "#": + write_flags = [] + + for i in c.args: + flag = FLAGS_RE.match(i[1]) + if flag: + write_flags.append( + "flags |= (1 << {}) if self.{} is not None else 0".format(flag.group(1), i[0])) + + write_flags = "\n ".join([ + "flags = 0", + "\n ".join(write_flags), + "b.write(Int(flags))\n " + ]) + + write_types += write_flags + read_types += "flags = Int.read(b)\n " + + continue + if flag: index, flag_type = flag[0] @@ -448,11 +454,9 @@ def start(): object_id=c.id, arguments=arguments, fields=fields, - read_flags=read_flags, read_types=read_types, - write_flags=write_flags, write_types=write_types, - return_arguments=", ".join([i[0] for i in sorted_args]) + return_arguments=", ".join([i[0] for i in sorted_args if i != ("flags", "#")]) ) ) diff --git a/compiler/api/template/mtproto.txt b/compiler/api/template/mtproto.txt index 368d4712..9a65b52d 100644 --- a/compiler/api/template/mtproto.txt +++ b/compiler/api/template/mtproto.txt @@ -16,7 +16,6 @@ class {class_name}(Object): @staticmethod def read(b: BytesIO, *args) -> "{class_name}": - {read_flags} {read_types} return {class_name}({return_arguments}) @@ -24,6 +23,5 @@ class {class_name}(Object): b = BytesIO() b.write(Int(self.ID, False)) - {write_flags} {write_types} return b.getvalue()