pycharm lint, isort & black

This commit is contained in:
rocky 2022-12-01 17:24:17 -05:00
parent 9f1514a2dd
commit e8d4d383c6
9 changed files with 168 additions and 112 deletions

View File

@ -3,19 +3,21 @@
spark grammar differences over Python2.5 for Python 2.4.
"""
from uncompyle6.parser import PythonParserSingle
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
from uncompyle6.parser import PythonParserSingle
from uncompyle6.parsers.parse25 import Python25Parser
class Python24Parser(Python25Parser):
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
super(Python24Parser, self).__init__(debug_parser)
self.customized = {}
def p_misc24(self, args):
'''
"""
# Python 2.4 only adds something like the below for if 1:
# However we will just treat it as a noop (which of course messes up
# However we will just treat it as a noop which messes up
# simple verify of bytecode.
# See also below in reduce_is_invalid where we check that the JUMP_FORWARD
# target matches the COME_FROM target
@ -69,16 +71,18 @@ class Python24Parser(Python25Parser):
# Python 2.3- use kv
kvlist ::= kvlist kv2
kv2 ::= DUP_TOP expr expr ROT_THREE STORE_SUBSCR
'''
"""
def remove_rules_24(self):
self.remove_rules("""
self.remove_rules(
"""
expr ::= if_exp
""")
"""
)
def customize_grammar_rules(self, tokens, customize):
self.remove_rules("""
self.remove_rules(
"""
gen_comp_body ::= expr YIELD_VALUE POP_TOP
kvlist ::= kvlist kv3
while1stmt ::= SETUP_LOOP l_stmts JUMP_BACK COME_FROM
@ -91,44 +95,49 @@ class Python24Parser(Python25Parser):
with ::= expr setupwith SETUP_FINALLY suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM with_cleanup
stmt ::= with
stmt ::= withasstmt
""")
"""
)
super(Python24Parser, self).customize_grammar_rules(tokens, customize)
self.remove_rules_24()
if self.version[:2] == (2, 4):
self.check_reduce['nop_stmt'] = 'tokens'
self.check_reduce["nop_stmt"] = "tokens"
if self.version[:2] <= (2, 4):
# TODO: We may add something different or customize something
del self.reduce_check_table["ifelsestmt"]
def reduce_is_invalid(self, rule, ast, tokens, first, last):
invalid = super(Python24Parser,
self).reduce_is_invalid(rule, ast,
tokens, first, last)
invalid = super(Python24Parser, self).reduce_is_invalid(
rule, ast, tokens, first, last
)
if invalid or tokens is None:
return invalid
lhs = rule[0]
if lhs == 'nop_stmt':
if lhs == "nop_stmt":
l = len(tokens)
if 0 <= l < len(tokens):
return not int(tokens[first].pattr) == tokens[last].offset
elif lhs == 'try_except':
elif lhs == "try_except":
if last == len(tokens):
last -= 1
if tokens[last] != 'COME_FROM' and tokens[last-1] == 'COME_FROM':
if tokens[last] != "COME_FROM" and tokens[last - 1] == "COME_FROM":
last -= 1
return (tokens[last] == 'COME_FROM'
and tokens[last-1] == 'END_FINALLY'
and tokens[last-2] == 'POP_TOP'
and tokens[last-3].kind != 'JUMP_FORWARD')
return (
tokens[last] == "COME_FROM"
and tokens[last - 1] == "END_FINALLY"
and tokens[last - 2] == "POP_TOP"
and tokens[last - 3].kind != "JUMP_FORWARD"
)
return False
class Python24ParserSingle(Python24Parser, PythonParserSingle):
pass
if __name__ == '__main__':
if __name__ == "__main__":
# Check grammar
p = Python24Parser()
p.check_grammar()

View File

@ -3,10 +3,12 @@
spark grammar differences over Python2.6 for Python 2.5.
"""
from uncompyle6.parser import PythonParserSingle
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
from uncompyle6.parser import PythonParserSingle
from uncompyle6.parsers.parse26 import Python26Parser
from uncompyle6.parsers.reducecheck import (ifelsestmt)
from uncompyle6.parsers.reducecheck import ifelsestmt
class Python25Parser(Python26Parser):
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
@ -60,7 +62,8 @@ class Python25Parser(Python26Parser):
def customize_grammar_rules(self, tokens, customize):
# Remove grammar rules inherited from Python 2.6 or Python 2
self.remove_rules("""
self.remove_rules(
"""
setupwith ::= DUP_TOP LOAD_ATTR ROT_TWO LOAD_ATTR CALL_FUNCTION_0 POP_TOP
with ::= expr setupwith SETUP_FINALLY suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM WITH_CLEANUP END_FINALLY
@ -87,7 +90,8 @@ class Python25Parser(Python26Parser):
return_stmt_lambda LAMBDA_MARKER
if_exp_not_lambda ::= expr jmp_true_then expr return_if_lambda
return_stmt_lambda LAMBDA_MARKER
""")
"""
)
super(Python25Parser, self).customize_grammar_rules(tokens, customize)
if self.version[:2] == (2, 5):
self.check_reduce["try_except"] = "AST"
@ -95,9 +99,9 @@ class Python25Parser(Python26Parser):
self.check_reduce["ifelsestmt"] = "AST"
def reduce_is_invalid(self, rule, ast, tokens, first, last):
invalid = super(Python25Parser,
self).reduce_is_invalid(rule, ast,
tokens, first, last)
invalid = super(Python25Parser, self).reduce_is_invalid(
rule, ast, tokens, first, last
)
if invalid or tokens is None:
return invalid
if rule == ("aug_assign1", ("expr", "expr", "inplace_op", "store")):
@ -112,6 +116,7 @@ class Python25Parser(Python26Parser):
class Python25ParserSingle(Python26Parser, PythonParserSingle):
pass
if __name__ == "__main__":
# Check grammar
p = Python25Parser()

View File

@ -3,15 +3,16 @@
spark grammar differences over Python2 for Python 2.6.
"""
from uncompyle6.parser import PythonParserSingle
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
from uncompyle6.parser import PythonParserSingle
from uncompyle6.parsers.parse2 import Python2Parser
from uncompyle6.parsers.reducecheck import (
except_handler,
ifelsestmt2,
ifstmt2,
tryexcept,
tryelsestmt,
tryexcept,
)
@ -64,8 +65,8 @@ class Python26Parser(Python2Parser):
except_suite ::= c_stmts_opt jmp_abs come_from_pop
# This is what happens after a jump where
# we start a new block. For reasons I don't fully
# understand, there is also a value on the top of the stack
# we start a new block. For reasons that I don't fully
# understand, there is also a value on the top of the stack.
come_from_pop ::= COME_FROM POP_TOP
come_froms_pop ::= come_froms POP_TOP
"""
@ -78,7 +79,7 @@ class Python26Parser(Python2Parser):
def p_jumps26(self, args):
"""
# The are the equivalents of Python 2.7+'s
# There are the equivalents of Python 2.7+'s
# POP_JUMP_IF_TRUE and POP_JUMP_IF_FALSE
jmp_true ::= JUMP_IF_TRUE POP_TOP
jmp_false ::= JUMP_IF_FALSE POP_TOP
@ -106,8 +107,8 @@ class Python26Parser(Python2Parser):
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD come_froms POP_TOP COME_FROM
# This is what happens after a jump where
# we start a new block. For reasons I don't fully
# understand, there is also a value on the top of the stack
# we start a new block. For reasons that I don't fully
# understand, there is also a value on the top of the stack.
come_froms_pop ::= come_froms POP_TOP
"""
@ -394,7 +395,7 @@ class Python26Parser(Python2Parser):
if ast[1] is None:
return False
# For now, we won't let the 2nd 'expr' be a "if_exp_not"
# For now, we won't let the 2nd 'expr' be an "if_exp_not"
# However in < 2.6 where we don't have if/else expression it *can*
# be.
if self.version >= (2, 6) and ast[2][0] == "if_exp_not":
@ -464,7 +465,7 @@ class Python26Parser(Python2Parser):
ja_attr = ast[4].attr
return tokens[last].offset != ja_attr
elif lhs == "try_except":
# We need to distingush try_except from tryelsestmt and we do that
# We need to distingush "try_except" from "tryelsestmt"; we do that
# by checking the jump before the END_FINALLY
# If we have:
# insn
@ -490,7 +491,7 @@ class Python26Parser(Python2Parser):
) or (tokens[last - 3] == "JUMP_FORWARD" and tokens[last - 3].attr != 2)
elif lhs == "tryelsestmt":
# We need to distingush try_except from tryelsestmt and we do that
# We need to distinguish "try_except" from "tryelsestmt"; we do that
# by making sure that the jump before the except handler jumps to
# code somewhere before the end of the construct.
# This AST method is slower, but the token-only based approach
@ -508,8 +509,8 @@ class Python26Parser(Python2Parser):
return else_start >= last_offset
# The above test apparently isn't good enough, so we have additional
# checks distinguish try_except from tryelsestmt and we do that
# by checking the jump before the END_FINALLY
# checks distinguish "try_except" from "tryelsestmt". we do that
# by checking the jump before the "END_FINALLY".
# If we have:
# insn
# POP_TOP
@ -546,7 +547,7 @@ if __name__ == "__main__":
# Check grammar
p = Python26Parser()
p.check_grammar()
from xdis.version_info import PYTHON_VERSION_TRIPLE, IS_PYPY
from xdis.version_info import IS_PYPY, PYTHON_VERSION_TRIPLE
if PYTHON_VERSION_TRIPLE[:2] == (2, 6):
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()

View File

@ -4,19 +4,20 @@
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
from xdis import next_offset
from uncompyle6.parser import PythonParserSingle, nop_func
from uncompyle6.parsers.parse2 import Python2Parser
from uncompyle6.parsers.reducecheck import (
aug_assign1_check,
ifelsestmt,
except_handler,
for_block_check,
ifelsestmt,
or_check,
tryelsestmt,
except_handler,
)
class Python27Parser(Python2Parser):
class Python27Parser(Python2Parser):
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
super(Python27Parser, self).__init__(debug_parser)
self.customized = {}
@ -223,18 +224,22 @@ class Python27Parser(Python2Parser):
def customize_grammar_rules(self, tokens, customize):
# 2.7 changes COME_FROM to COME_FROM_FINALLY
self.remove_rules("""
self.remove_rules(
"""
while1elsestmt ::= SETUP_LOOP l_stmts JUMP_BACK else_suite COME_FROM
tryfinallystmt ::= SETUP_FINALLY suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM suite_stmts_opt
END_FINALLY
""")
if 'PyPy' in customize:
"""
)
if "PyPy" in customize:
# PyPy-specific customizations
self.addRule("""
self.addRule(
"""
return_if_stmt ::= return_expr RETURN_END_IF come_froms
""", nop_func)
""",
nop_func,
)
super(Python27Parser, self).customize_grammar_rules(tokens, customize)
@ -273,9 +278,9 @@ class Python27Parser(Python2Parser):
return
def reduce_is_invalid(self, rule, ast, tokens, first, last):
invalid = super(Python27Parser,
self).reduce_is_invalid(rule, ast,
tokens, first, last)
invalid = super(Python27Parser, self).reduce_is_invalid(
rule, ast, tokens, first, last
)
lhs = rule[0]
n = len(tokens)
@ -293,7 +298,8 @@ class Python27Parser(Python2Parser):
pass
elif (rule[0], rule[1][0:5]) == (
"if_exp",
("expr", "jmp_false", "expr", "JUMP_ABSOLUTE", "expr")):
("expr", "jmp_false", "expr", "JUMP_ABSOLUTE", "expr"),
):
jmp_false = ast[1]
if jmp_false[0] == "POP_JUMP_IF_FALSE":
else_instr = ast[4].first_child()
@ -302,14 +308,16 @@ class Python27Parser(Python2Parser):
end_offset = ast[3].attr
return end_offset < tokens[last].offset
pass
elif rule[0] == ("raise_stmt1"):
elif rule[0] == "raise_stmt1":
return ast[0] == "expr" and ast[0][0] == "or"
elif rule[0] in ("assert", "assert2"):
jump_inst = ast[1][0]
jump_target = jump_inst.attr
return not (last >= len(tokens)
return not (
last >= len(tokens)
or jump_target == tokens[last].offset
or jump_target == next_offset(ast[-1].op, ast[-1].opc, ast[-1].offset))
or jump_target == next_offset(ast[-1].op, ast[-1].opc, ast[-1].offset)
)
elif rule == ("ifstmt", ("testexpr", "_ifstmts_jump")):
for i in range(last - 1, last - 4, -1):
t = tokens[i]
@ -327,11 +335,11 @@ class Python27Parser(Python2Parser):
jmp_target = test[1][0].attr
if last == len(tokens):
last -= 1
while (isinstance(tokens[first].offset, str) and first < last):
while isinstance(tokens[first].offset, str) and first < last:
first += 1
if first == last:
return True
while (first < last and isinstance(tokens[last].offset, str)):
while first < last and isinstance(tokens[last].offset, str):
last -= 1
return tokens[first].off2int() < jmp_target < tokens[last].off2int()
pass
@ -340,26 +348,31 @@ class Python27Parser(Python2Parser):
elif rule == ("list_if_not", ("expr", "jmp_true", "list_iter")):
jump_inst = ast[1][0]
jump_offset = jump_inst.attr
return jump_offset > jump_inst.offset and jump_offset < tokens[last].offset
return jump_inst.offset < jump_offset < tokens[last].offset
elif rule == ("list_if", ("expr", "jmp_false", "list_iter")):
jump_inst = ast[1][0]
jump_offset = jump_inst.attr
return jump_offset > jump_inst.offset and jump_offset < tokens[last].offset
return jump_inst.offset < jump_offset < tokens[last].offset
elif rule == ("or", ("expr", "jmp_true", "expr", "\\e_come_from_opt")):
# Test that jmp_true doesn"t jump inside the middle the "or"
# Test that jmp_true doesn't jump inside the middle the "or"
# or that it jumps to the same place as the end of "and"
jmp_true = ast[1][0]
jmp_target = jmp_true.offset + jmp_true.attr + 3
return not (jmp_target == tokens[last].offset or
tokens[last].pattr == jmp_true.pattr)
return not (
jmp_target == tokens[last].offset
or tokens[last].pattr == jmp_true.pattr
)
elif (rule[0] == "whilestmt" and
rule[1][0:-2] ==
("SETUP_LOOP", "testexpr", "l_stmts_opt",
"JUMP_BACK", "JUMP_BACK")):
elif rule[0] == "whilestmt" and rule[1][0:-2] == (
"SETUP_LOOP",
"testexpr",
"l_stmts_opt",
"JUMP_BACK",
"JUMP_BACK",
):
# Make sure that the jump backs all go to the same place
i = last - 1
while (tokens[i] != "JUMP_BACK"):
while tokens[i] != "JUMP_BACK":
i -= 1
return tokens[i].attr != tokens[i - 1].attr
elif rule[0] == "if_exp_true":
@ -371,26 +384,31 @@ class Python27Parser(Python2Parser):
class Python27ParserSingle(Python27Parser, PythonParserSingle):
pass
if __name__ == "__main__":
# Check grammar
p = Python27Parser()
p.check_grammar()
from xdis.version_info import PYTHON_VERSION_TRIPLE, IS_PYPY
from xdis.version_info import IS_PYPY, PYTHON_VERSION_TRIPLE
if PYTHON_VERSION_TRIPLE[:2] == (2, 7):
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
from uncompyle6.scanner import get_scanner
s = get_scanner(PYTHON_VERSION_TRIPLE, IS_PYPY)
opcode_set = set(s.opc.opname).union(set(
opcode_set = set(s.opc.opname).union(
set(
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP
LAMBDA_MARKER RETURN_LAST
""".split()))
""".split()
)
)
remain_tokens = set(tokens) - opcode_set
import re
remain_tokens = set([re.sub(r"_\d+$", "", t)
for t in remain_tokens])
remain_tokens = set([re.sub("_CONT$", "", t)
for t in remain_tokens])
remain_tokens = set([re.sub(r"_\d+$", "", t) for t in remain_tokens])
remain_tokens = set([re.sub("_CONT$", "", t) for t in remain_tokens])
remain_tokens = set(remain_tokens) - opcode_set
print(remain_tokens)
# p.dump_grammar()

View File

@ -7,8 +7,8 @@ from __future__ import print_function
from uncompyle6.parser import PythonParserSingle
from uncompyle6.parsers.parse32 import Python32Parser
class Python31Parser(Python32Parser):
class Python31Parser(Python32Parser):
def p_31(self, args):
"""
subscript2 ::= expr expr DUP_TOPX BINARY_SUBSCR
@ -20,7 +20,7 @@ class Python31Parser(Python32Parser):
POP_BLOCK LOAD_CONST COME_FROM_FINALLY
load delete WITH_CLEANUP END_FINALLY
# Keeps Python 3.1 withas desigator in the same position as it is in other version
# Keeps Python 3.1 "with .. as" designator in the same position as it is in other version.
setupwithas31 ::= setupwithas SETUP_FINALLY load delete
withasstmt ::= expr setupwithas31 store
@ -32,49 +32,63 @@ class Python31Parser(Python32Parser):
load ::= LOAD_FAST
load ::= LOAD_NAME
"""
def remove_rules_31(self):
self.remove_rules("""
self.remove_rules(
"""
# DUP_TOP_TWO is DUP_TOPX in 3.1 and earlier
subscript2 ::= expr expr DUP_TOP_TWO BINARY_SUBSCR
# The were found using grammar coverage
list_if ::= expr jmp_false list_iter COME_FROM
list_if_not ::= expr jmp_true list_iter COME_FROM
""")
"""
)
def customize_grammar_rules(self, tokens, customize):
super(Python31Parser, self).customize_grammar_rules(tokens, customize)
self.remove_rules_31()
return
pass
class Python31ParserSingle(Python31Parser, PythonParserSingle):
pass
if __name__ == '__main__':
if __name__ == "__main__":
# Check grammar
p = Python31Parser()
p.remove_rules_31()
p.check_grammar()
from xdis.version_info import PYTHON_VERSION_TRIPLE, IS_PYPY
from xdis.version_info import IS_PYPY, PYTHON_VERSION_TRIPLE
if PYTHON_VERSION_TRIPLE[:2] == (3, 1):
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
from uncompyle6.scanner import get_scanner
s = get_scanner(PYTHON_VERSION_TRIPLE, IS_PYPY)
opcode_set = set(s.opc.opname).union(set(
opcode_set = set(s.opc.opname).union(
set(
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP LOAD_CLASSNAME
LAMBDA_MARKER RETURN_LAST
""".split()))
## FIXME: try this
""".split()
)
)
# FIXME: try this
remain_tokens = set(tokens) - opcode_set
import re
remain_tokens = set([re.sub(r'_\d+$', '', t) for t in remain_tokens])
remain_tokens = set([re.sub('_CONT$', '', t) for t in remain_tokens])
remain_tokens = set([re.sub(r"_\d+$", "", t) for t in remain_tokens])
remain_tokens = set([re.sub("_CONT$", "", t) for t in remain_tokens])
remain_tokens = set(remain_tokens) - opcode_set
print(remain_tokens)
import sys
if len(sys.argv) > 1:
from spark_parser.spark import rule2str
for rule in sorted(p.rule2name.items()):
print(rule2str(rule[0]))

View File

@ -7,6 +7,7 @@ from __future__ import print_function
from uncompyle6.parser import PythonParserSingle
from uncompyle6.parsers.parse3 import Python3Parser
class Python32Parser(Python3Parser):
def p_30to33(self, args):
"""
@ -15,7 +16,6 @@ class Python32Parser(Python3Parser):
store_locals ::= LOAD_FAST STORE_LOCALS
"""
def p_gen_comp32(self, args):
"""
genexpr_func ::= LOAD_ARG FOR_ITER store comp_iter JUMP_BACK
@ -59,6 +59,7 @@ class Python32Parser(Python3Parser):
kv3 ::= expr expr STORE_MAP
"""
pass
def p_32on(self, args):
@ -69,7 +70,8 @@ class Python32Parser(Python3Parser):
pass
def customize_grammar_rules(self, tokens, customize):
self.remove_rules("""
self.remove_rules(
"""
except_handler ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY COME_FROM
except_handler ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY COME_FROM_EXCEPT
except_handler ::= JUMP_FORWARD COME_FROM_EXCEPT except_stmts END_FINALLY COME_FROM_EXCEPT_CLAUSE
@ -77,17 +79,22 @@ class Python32Parser(Python3Parser):
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK except_handler else_suite come_from_except_clauses
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK NOP COME_FROM_LOOP
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK NOP COME_FROM_LOOP
""")
"""
)
super(Python32Parser, self).customize_grammar_rules(tokens, customize)
for i, token in enumerate(tokens):
opname = token.kind
if opname.startswith('MAKE_FUNCTION_A'):
if opname.startswith("MAKE_FUNCTION_A"):
args_pos, args_kw, annotate_args = token.attr
# Check that there are 2 annotated params?
rule = (('mkfunc_annotate ::= %s%sannotate_tuple '
'LOAD_CONST LOAD_CODE EXTENDED_ARG %s') %
(('pos_arg ' * (args_pos)),
('annotate_arg ' * (annotate_args-1)), opname))
rule = (
"mkfunc_annotate ::= %s%sannotate_tuple "
"LOAD_CONST LOAD_CODE EXTENDED_ARG %s"
) % (
("pos_arg " * args_pos),
("annotate_arg " * (annotate_args - 1)),
opname,
)
self.add_unique_rule(rule, opname, token.attr, customize)
pass
return

View File

@ -7,6 +7,7 @@ from __future__ import print_function
from uncompyle6.parser import PythonParserSingle
from uncompyle6.parsers.parse32 import Python32Parser
class Python33Parser(Python32Parser):
def p_33on(self, args):

View File

@ -19,6 +19,7 @@ spark grammar differences over Python 3.3 for Python 3.4
from uncompyle6.parser import PythonParserSingle
from uncompyle6.parsers.parse33 import Python33Parser
class Python34Parser(Python33Parser):
def p_misc34(self, args):
@ -70,7 +71,7 @@ if __name__ == '__main__':
# Check grammar
p = Python34Parser()
p.check_grammar()
from xdis.version_info import PYTHON_VERSION_TRIPLE, IS_PYPY
from xdis.version_info import IS_PYPY, PYTHON_VERSION_TRIPLE
if PYTHON_VERSION_TRIPLE[:2] == (3, 4):
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
from uncompyle6.scanner import get_scanner

View File

@ -8,15 +8,16 @@ scanner routine for Python 3.
from __future__ import print_function
import xdis
from xdis import instruction_size
# bytecode verification, verify(), uses JUMP_OPs from here
from xdis.opcodes import opcode_30 as opc
from xdis import instruction_size
import xdis
JUMP_TF = frozenset([opc.JUMP_IF_FALSE, opc.JUMP_IF_TRUE])
from uncompyle6.scanners.scanner3 import Scanner3
JUMP_TF = frozenset([opc.JUMP_IF_FALSE, opc.JUMP_IF_TRUE])
class Scanner30(Scanner3):
def __init__(self, show_asm=None, is_pypy=False):
@ -365,7 +366,6 @@ class Scanner30(Scanner3):
# 'end': end})
# self.else_start[rtarget] = end
elif self.is_jump_back(pre_rtarget, 0):
if_end = rtarget
self.structs.append(
{"type": "if-then", "start": start, "end": pre_rtarget}
)