from .t import T as Template

class T(Template):
    def __init__(self): super().__init__("Python")
    
    def _NUMBER(s):                                                                 return str(s.n[1])
    def _STRING(s):                                                                 return f"\"{s.n[1]}\""
    def _BSTRING(s):                                                                return f"b\"{s.n[1]}\""
    def _RSTRING(s):                                                                return f"r'{s.n[1]}'"
    def _TRUE(s):                                                                   return "True"
    def _FALSE(s):                                                                  return "False"
    def _NONE(s):                                                                   return "None"
    def _COMMENT(s):                                                                return f"# {s.n[1]}"
    def _ellipsis(s):                                                               return f"..."
    def _super_init(s):                                                             return f"super().__init__"
    def _output(s):                                                                 return f"print({s.wt(s.n[1])})"
    def _pass(s):                                                                   return f"pass"
    def _next(s):                                                                   return f"continue"
    def _break(s):                                                                  return f"break"
    def _global(s):                                                                 return f"global {s.wt(s.n[1])}"
    def _assert(s):                                                                 return f"assert {s.wt(s.n[1])}"
    def _raise(s):                                                                  return f"raise {s.wt(s.n[1])}"
    def _func(s):                                                                   return f"{s.wt(s.n[1])}({s.jwt(s.n[2], ", ")})"
    def _func_self(s):                                                              return f"{(_ := s.wt(s.n[1]))}.{s.wt(s.n[2])}({_}{f", {_}" if (_ := s.jwt(s.n[3], ", ")) else ""})"
    def _tuple(s):                                                                  return f"({s.jwt(s.n[1], ", ")}{"," if len(s.n[1]) == 1 else ""})"
    def _list(s):                                                                   return f"[{s.jwt(s.n[1], ", ")}]"
    def _dict(s):                                                                   return "{"+(", ".join(f"{s.wt(k)}: {s.wt(v)}" for k, v in s.n[1]))+"}"
    def _type(s):                                                                   return s.n[1]
    def _type_expr(s):                                                              return s.wt(s.n[1])
    def _typelist(s):                                                               return f"{s.wt(s.n[1])}[{", ".join(str(s.wt(arg)) for arg in s.n[2])}]"
    def _typesel(s):                                                                return f"{s.wt(s.n[1])} | {s.wt(s.n[2])}"
    def _arg(s):                                                                    return f"*{s.n[1]}"
    def _kwarg(s):                                                                  return f"**{s.n[1]}"
    def _typed_arg(s):                                                              return f"{s.n[1]}: {s.wt(s.n[2])}"
    def _default_arg(s):                                                            return f"{s.n[1]} = {s.wt(s.n[2])}"
    def _default_typed_arg(s):                                                      return f"{s.n[1]}: {s.wt(s.n[2])} = {s.wt(s.n[3])}"
    def _set(s):                            s.dollar = s.jwt(s.n[1], ", ");         return f"{s.dollar} = {s.jwt(s.n[2], ", ")}"
    def _set_add(s):                        s.dollar = s.wt(s.n[1]);                return f"{s.dollar} += {s.wt(s.n[2])}"
    def _set_subtract(s):                   s.dollar = s.wt(s.n[1]);                return f"{s.dollar} -= {s.wt(s.n[2])}"
    def _set_multiply(s):                   s.dollar = s.wt(s.n[1]);                return f"{s.dollar} *= {s.wt(s.n[2])}"
    def _set_divide(s):                     s.dollar = s.wt(s.n[1]);                return f"{s.dollar} /= {s.wt(s.n[2])}"
    def _set_dot(s):                        s.dollar = s.wt(s.n[1]);                return f"{s.dollar} = {s.dollar}.{s.wt(s.n[2])}"
    def _set_power(s):                      s.dollar = s.wt(s.n[1]);                return f"{s.dollar} **= {s.wt(s.n[2])}"
    def _set_floor_divide(s):               s.dollar = s.wt(s.n[1]);                return f"{s.dollar} //= {s.wt(s.n[2])}"
    def _set_modulo(s):                     s.dollar = s.wt(s.n[1]);                return f"{s.dollar} %= {s.wt(s.n[2])}"
    def _set_matmul(s):                     s.dollar = s.wt(s.n[1]);                return f"{s.dollar} @= {s.wt(s.n[2])}"
    def _set_bitwise_and(s):                s.dollar = s.wt(s.n[1]);                return f"{s.dollar} &= {s.wt(s.n[2])}"
    def _set_bitwise_or(s):                 s.dollar = s.wt(s.n[1]);                return f"{s.dollar} |= {s.wt(s.n[2])}"
    def _set_bitwise_xor(s):                s.dollar = s.wt(s.n[1]);                return f"{s.dollar} ^= {s.wt(s.n[2])}"
    def _set_bitwise_not(s):                s.dollar = s.wt(s.n[1]);                return f"{s.dollar} = ~{s.dollar}"
    def _set_bitwise_shl(s):                s.dollar = s.wt(s.n[1]);                return f"{s.dollar} <<= {s.wt(s.n[2])}"
    def _set_bitwise_shr(s):                s.dollar = s.wt(s.n[1]);                return f"{s.dollar} >>= {s.wt(s.n[2])}"
    def _set_self(s):                                                               return f"self.{(_ := s.wt(s.n[1]))} = {_}"
    def _set_cast(s):                       s.dollar = s.wt(s.n[1]);                return f"{s.dollar} = type({s.wt(s.n[2])}())({s.dollar})"
    def _set_strjoin(s):                                                            return s._add()
    def _add(s):                                                                    return f"{s.wt(s.n[1])} + {s.wt(s.n[2])}"
    def _subtract(s):                                                               return f"{s.wt(s.n[1])} - {s.wt(s.n[2])}"
    def _multiply(s):                                                               return f"{s.wt(s.n[1])} * {s.wt(s.n[2])}"
    def _divide(s):                                                                 return f"{s.wt(s.n[1])} / {s.wt(s.n[2])}"
    def _unary_plus(s):                                                             return f"+{s.wt(s.n[1])}"
    def _unary_minus(s):                                                            return f"-{s.wt(s.n[1])}"
    def _walrus(s):                         s.dollar = s.wt(s.n[1]);                return f"({s.wt(s.n[1])} := {s.wt(s.n[2])})"
    def _power(s):                                                                  return f"{s.wt(s.n[1])} ** {s.wt(s.n[2])}"
    def _floor_divide(s):                                                           return f"{s.wt(s.n[1])} // {s.wt(s.n[2])}"
    def _modulo(s):                                                                 return f"{s.wt(s.n[1])} % {s.wt(s.n[2])}"
    def _matmul(s):                                                                 return f"{s.wt(s.n[1])} @ {s.wt(s.n[2])}"
    def _bitwise_and(s):                                                            return f"{s.wt(s.n[1])} & {s.wt(s.n[2])}"
    def _bitwise_or(s):                                                             return f"{s.wt(s.n[1])} | {s.wt(s.n[2])}"
    def _bitwise_xor(s):                                                            return f"{s.wt(s.n[1])} ^ {s.wt(s.n[2])}"
    def _bitwise_not(s):                                                            return f"~{s.wt(s.n[1])}"
    def _bitwise_shl(s):                                                            return f"{s.wt(s.n[1])} << {s.wt(s.n[2])}"
    def _bitwise_shr(s):                                                            return f"{s.wt(s.n[1])} >> {s.wt(s.n[2])}"
    def _strjoin(s):                                                                return s._add()
    def _cmp_e(s):                                                                  return f"{s.wt(s.n[1])} == {s.wt(s.n[2])}"
    def _cmp_g(s):                                                                  return f"{s.wt(s.n[1])} > {s.wt(s.n[2])}"
    def _cmp_l(s):                                                                  return f"{s.wt(s.n[1])} < {s.wt(s.n[2])}"
    def _cmp_le(s):                                                                 return f"{s.wt(s.n[1])} <= {s.wt(s.n[2])}"
    def _cmp_ge(s):                                                                 return f"{s.wt(s.n[1])} >= {s.wt(s.n[2])}"
    def _cmp_ne(s):                                                                 return f"{s.wt(s.n[1])} != {s.wt(s.n[2])}"
    def _between(s):                                                                return f"({s.wt(s.n[2])} <= {s.wt(s.n[1])} <= {s.wt(s.n[3])})"
    def _index(s):                                                                  return f"{s.wt(s.n[1])}[{s.wt(s.n[2])}]"
    def _index_from(s):                                                             return f"{s.wt(s.n[1])}[{s.wt(s.n[2])}:]"
    def _index_to(s):                                                               return f"{s.wt(s.n[1])}[:{s.wt(s.n[2])}]"
    def _index_from_to(s):                                                          return f"{s.wt(s.n[1])}[{s.wt(s.n[2])}:{s.wt(s.n[3])}]"
    def _index_step(s):                                                             return f"{s.wt(s.n[1])}[::{s.wt(s.n[2])}]"
    def _index_from_step(s):                                                        return f"{s.wt(s.n[1])}[{s.wt(s.n[2])}::{s.wt(s.n[3])}]"
    def _index_to_step(s):                                                          return f"{s.wt(s.n[1])}[:{s.wt(s.n[2])}:{s.wt(s.n[3])}]"
    def _index_from_to_step(s):                                                     return f"{s.wt(s.n[1])}[{s.wt(s.n[2])}:{s.wt(s.n[3])}:{s.wt(s.n[4])}]"
    def _list_remove(s):                                                            return f"{s.wt(s.n[2])} = {s.wt(s.n[1])}.pop()"
    def _list_append(s):                                                            return f"{s.wt(s.n[1])}.append({s.wt(s.n[2])})"
    def _member(s):                                                                 return f"{s.wt(s.n[1])}.{s.wt(s.n[2])}"
    def _string_upper(s):                                                           return f"{s.wt(s.n[1])}.upper()"
    def _string_lower(s):                                                           return f"{s.wt(s.n[1])}.lower()"
    def _range_inc_inc(s):                                                          return f"range({s.wt(s.n[1])}, {s.wt(s.n[2])}+1, {s.wt(s.n[3])})"
    def _range_inc_exc(s):                                                          return f"range({s.wt(s.n[1])}, {s.wt(s.n[2])}, {s.wt(s.n[3])})"
    def _range_exc_inc(s):                                                          return f"range({s.wt(s.n[1])}+1, {s.wt(s.n[2])}+1, {s.wt(s.n[3])})"
    def _range_exc_exc(s):                                                          return f"range({s.wt(s.n[1])}+1, {s.wt(s.n[2])}, {s.wt(s.n[3])})"
    def _range(s):                                                                  return f"range({s.wt(s.n[1])}, {s.wt(s.n[2])}, {s.wt(s.n[3])})"
    def _length(s):                                                                 return f"len({s.wt(s.n[1])})"
    def _get_type(s):                                                               return f"type({s.wt(s.n[1])})"
    def _cast(s):                                                                   return f"{s.wt(s.n[2])}({s.wt(s.n[1])})"
    def _cast_type(s):                                                              return f"type({s.wt(s.n[2])})({s.wt(s.n[1])})"
    def _use(s):                                                                    return f"import {s.wt(s.n[1])}"
    def _use_as(s):                                                                 return f"{s._use()} as {s.wt(s.n[2])}"
    def _use_from(s):                                                               return f"from {s.n[2]} "+s._use()
    def _use_as_from(s):                                                            return f"from {s.n[3]} "+s._use_as()
    def _while(s):                          s.indent += 4;                          return f"while {s.wt(s.n[1])}:{s.body(s.wt(s.n[2]))}"
    def _for(s):                            s.indent += 4;                          return f"for {s.jwt(s.n[1], ", ")} in {s.wt(s.n[2])}:{s.body(s.wt(s.n[3]))}"
    def _for_at(s):                         s.indent += 4;                          return f"for {s.wt(s.n[2])}, ({s.jwt(s.n[1], ", ")}) in enumerate({s.wt(s.n[3])}):{s.body(s.wt(s.n[4]))}"
    def _for_else(s):                                                               return f"{s._for()}\n{" "*(s.indent-4)}else:{s.body(s.wt(s.n[4]))}"
    def _for_at_else(s):                                                            return f"{s._for_at()}\n{" "*(s.indent-4)}else:{s.body(s.wt(s.n[4]))}"
    def _for_to(s):                         s.indent += 4;                          return f"for {s.wt(s.n[1])} in range(0, {s.wt(s.n[2])}):{s.body(s.wt(s.n[3]))}"
    def _for_from_to(s):                    s.indent += 4;                          return f"for {s.wt(s.n[1])} in range({s.wt(s.n[2])}, {s.wt(s.n[3])}):{s.body(s.wt(s.n[4]))}"
    def _times(s):                          s.indent += 4;                          return f"for _ in range({s.wt(s.n[1])}):\n{" " * s.indent}del _{s.body(s.wt(s.n[2]))}"
    def _if(s):                             s.indent += 4;                          return f"if {s.wt(s.n[1])}:{s.body(s.wt(s.n[2]))}"
    def _if_else(s):                                                                return f"{s._if()}\n{" "*(s.indent-4)}else:{s.body(s.wt(s.n[3]))}"
    def _if_elif(s):                                                                return f"{s._if()}{s.body(list((" "*(s.indent-4))+f"elif {s.wt(cond)}:{s.body(s.wt(prog))}" for cond, prog in s.n[3]))}"
    def _if_elif_else(s):                                                           return f"{s._if_elif()}\n{" "*(s.indent-4)}else:{s.body(s.wt(s.n[4]))}"
    def _generator(s):                      s.dollar = s.wt(s.n[1]);                return f"({s.dollar} for {s.jwt(s.n[2], ", ")} in {(s.wt(s.n[3]))})"
    def _generator_at(s):                   s.dollar = f"({s.jwt(s.n[2], ", ")})";  return f"({s.wt(s.n[1])} for {s.wt(s.n[3])}, {s.dollar} in enumerate({s.wt(s.n[4])}))"
    def _ternary(s):                                                                return f"({s.wt(s.n[1])} if {s.wt(s.n[2])} else {s.wt(s.n[3])})"
    def _try(s):                            s.indent += 4;                          return f"try:{s.body(s.wt(s.n[1]))}\n{" "*(s.indent-4)}except:\n{" "*(s.indent)}pass"
    def _try_else(s):                                                               return f"{s._try()}\n{" "*(s.indent-4)}else:{s.body(s.wt(s.n[2]))}"
    def _try_catch(s):                      s.indent += 4;                          return f"try:{s.body(s.wt(s.n[1]))}{s.body(list((" "*(s.indent-4))+f"except {s.wt(cond)}:{s.body(s.wt(prog))}" for cond, prog in s.n[2]))}"
    def _try_catch_else(s):                                                         return f"{s._try_catch()}\n{" "*(s.indent-4)}else:{s.body(s.wt(s.n[3]))}"
    def _match(s):                          s.indent += 4;                          return f"match {s.wt(s.n[1])}:{s.body(s.wt(s.n[2]))}"
    def _case(s):                           s.indent += 4;                          return f"case {s.wt(s.n[1])}:{s.body(s.wt(s.n[2]))}"
    def _ignore(s):                         s.indent += 4;                          return f"case {s.wt(s.n[1])}:{s.body(s.empty_body())}"
    def _inc_before(s):                                                             return f"({(tmp := s.wt(s.n[1]))} := {tmp}+1)"
    def _dec_before(s):                                                             return f"({(tmp := s.wt(s.n[1]))} := {tmp}-1)"
    def _inc_after(s):                                                              return f"({s._inc_before()}-1)"
    def _dec_after(s):                                                              return f"({s._dec_before()}+1)"
    def _func_def(s):                       s.indent += 4;                          return f"def {s.wt(s.n[1])}({s.jwt(s.n[2], ", ")}) -> {s.wt(s.n[3])}:{s.body(([f"{" " * s.indent}super().__init__({", ".join(f"{(s.wt(arg)+":").split(":")[0]}={(s.wt(arg)+":").split(":")[0]}" for arg in filter(lambda _: _[0] == "func_assign_super", s.n[2]))})"] if len(list(filter(lambda _: _[0] == "func_assign_super", s.n[2]))) > 0 else [])+[f"{" " * s.indent}self.{(s.wt(arg)+":").split(":")[0]} = {(s.wt(arg)+":").split(":")[0]}" for arg in filter(lambda _: _[0] == "func_assign_self", s.n[2])]+s.wt(s.n[4]))}"
    def _func_def_self(s):                  s.indent += 4;                          return f"def {s.wt(s.n[1])}(self{", " if s.n[2] else ""}{s.jwt(s.n[2], ", ")}) -> {s.wt(s.n[3])}:{s.body(([f"{" " * s.indent}super().__init__({", ".join(f"{(s.wt(arg)+":").split(":")[0]}={(s.wt(arg)+":").split(":")[0]}" for arg in filter(lambda _: _[0] == "func_assign_super", s.n[2]))})"] if len(list(filter(lambda _: _[0] == "func_assign_super", s.n[2]))) > 0 else [])+[f"{" " * s.indent}self.{(s.wt(arg)+":").split(":")[0]} = {(s.wt(arg)+":").split(":")[0]}" for arg in filter(lambda _: _[0] == "func_assign_self", s.n[2])]+s.wt(s.n[4]))}"
    def _func_def_untyped(s):               s.indent += 4;                          return f"def {s.wt(s.n[1])}({s.jwt(s.n[2], ", ")}):{s.body(([f"{" " * s.indent}super().__init__({", ".join(f"{(s.wt(arg)+":").split(":")[0]}={(s.wt(arg)+":").split(":")[0]}" for arg in filter(lambda _: _[0] == "func_assign_super", s.n[2]))})"] if len(list(filter(lambda _: _[0] == "func_assign_super", s.n[2]))) > 0 else [])+[f"{" " * s.indent}self.{(s.wt(arg)+":").split(":")[0]} = {(s.wt(arg)+":").split(":")[0]}" for arg in filter(lambda _: _[0] == "func_assign_self", s.n[2])]+s.wt(s.n[3]))}"
    def _func_def_self_untyped(s):          s.indent += 4;                          return f"def {s.wt(s.n[1])}(self{", " if s.n[2] else ""}{s.jwt(s.n[2], ", ")}):{s.body(([f"{" " * s.indent}super().__init__({", ".join(f"{(s.wt(arg)+":").split(":")[0]}={(s.wt(arg)+":").split(":")[0]}" for arg in filter(lambda _: _[0] == "func_assign_super", s.n[2]))})"] if len(list(filter(lambda _: _[0] == "func_assign_super", s.n[2]))) > 0 else [])+[f"{" " * s.indent}self.{(s.wt(arg)+":").split(":")[0]} = {(s.wt(arg)+":").split(":")[0]}" for arg in filter(lambda _: _[0] == "func_assign_self", s.n[2])]+s.wt(s.n[3]))}"
    def _func_def__(s):                     s.indent += 4;                          return f"def __{s.wt(s.n[1])}__(self{", " if s.n[2] else ""}{s.jwt(s.n[2], ", ")}):{s.body(([f"{" " * s.indent}super().__init__({", ".join(f"{(s.wt(arg)+":").split(":")[0]}={(s.wt(arg)+":").split(":")[0]}" for arg in filter(lambda _: _[0] == "func_assign_super", s.n[2]))})"] if len(list(filter(lambda _: _[0] == "func_assign_super", s.n[2]))) > 0 else [])+[f"{" " * s.indent}self.{(s.wt(arg)+":").split(":")[0]} = {(s.wt(arg)+":").split(":")[0]}" for arg in filter(lambda _: _[0] == "func_assign_self", s.n[2])]+s.wt(s.n[3]))}"
    def _func_def_async_self(s):                                                    return f"async {s._func_def_self()}"
    def _func_def_async_untyped(s):                                                 return f"async {s._func_def_untyped()}"
    def _func_def_async_self_untyped(s):                                            return f"async {s._func_def_self_untyped()}"
    def _func_def_async__(s):                                                       return f"async {s._func_def__()}"
    def _func_assign_self(s):                                                       return s.wt(s.n[1])
    def _func_assign_super(s):                                                      return s.wt(s.n[1])
    def _class_def(s):                      s.indent += 4;                          return f"class {s.n[1]}:{s.body(s.wt(s.n[2]))}"
    def _class_def_from(s):                 s.indent += 4;                          return f"class {s.n[1]}({s.n[2]}):{s.body(s.wt(s.n[3]))}"
    def _namespace_def(s):                                                          return s._class_def()
    def _with(s):                           s.indent += 4;                          return f"with {s.wt(s.n[1])} as {s.wt(s.n[2])}:{s.body(s.wt(s.n[3]))}"
    def _return(s):                                                                 return f"return {s.wt(s.n[1])}"
    def _yield(s):                                                                  return f"yield {s.wt(s.n[1])}"
    def _del(s):                                                                    return f"del {s.wt(s.n[1])}"
    def _and(s):                                                                    return f"{s.wt(s.n[1])} and {s.wt(s.n[2])}"
    def _or(s):                                                                     return f"{s.wt(s.n[1])} or {s.wt(s.n[2])}"
    def _not(s):                                                                    return f"not {s.wt(s.n[1])}"
    def _is(s):                                                                     return f"{s.wt(s.n[1])} is {s.wt(s.n[2])}"
    def _in(s):                                                                     return f"{s.wt(s.n[1])} in {s.wt(s.n[2])}"
    def _lambda(s):                                                                 return f"(lambda {s.jwt(s.n[2], ", ")}: {s.wt(s.n[1])})"
    def _decorator(s):                                                              return f"@{s.wt(s.n[1])}"
    def _slash_arg(s):                                                              return f"/"
    def _asterisk_arg(s):                                                           return f"*"
    def _self(s):                                                                   return f"self"
    def _super(s):                                                                  return f"super()"
    
    def empty_body(s):
        return [" "*s.indent+s._pass()]