You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 08:49:51 +08:00
BIN
test/bytecode_2.6_run/01_ifelse_listcomp.pyc
Normal file
BIN
test/bytecode_2.6_run/01_ifelse_listcomp.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.7_run/01_ifelse_listcomp.pyc
Normal file
BIN
test/bytecode_2.7_run/01_ifelse_listcomp.pyc
Normal file
Binary file not shown.
4
test/simple_source/bug26/01_ifelse_listcomp.py
Normal file
4
test/simple_source/bug26/01_ifelse_listcomp.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# Bug from issue #171: parsing "if x if a else y" inside a list comprehension on 2.7
|
||||
# This is RUNNABLE!
|
||||
assert [False, True, True, True, True] == [False if not a else True for a in range(5)]
|
||||
assert [True, False, False, False, False] == [False if a else True for a in range(5)]
|
@@ -264,6 +264,9 @@ class Python26Parser(Python2Parser):
|
||||
dict ::= BUILD_MAP kvlist
|
||||
kvlist ::= kvlist kv3
|
||||
|
||||
expr ::= conditional_not
|
||||
conditional_not ::= expr jmp_true expr _jump COME_FROM POP_TOP expr COME_FROM
|
||||
|
||||
conditional ::= expr jmp_false expr jf_cf_pop expr come_from_opt
|
||||
and ::= expr JUMP_IF_FALSE POP_TOP expr JUMP_IF_FALSE POP_TOP
|
||||
|
||||
|
@@ -165,6 +165,9 @@ class Python27Parser(Python2Parser):
|
||||
::= expr jmp_true expr return_if_lambda
|
||||
return_stmt_lambda LAMBDA_MARKER
|
||||
|
||||
expr ::= conditional_not
|
||||
conditional_not ::= expr jmp_true expr _jump expr COME_FROM
|
||||
|
||||
kv3 ::= expr expr STORE_MAP
|
||||
"""
|
||||
|
||||
@@ -172,12 +175,17 @@ class Python27Parser(Python2Parser):
|
||||
# 2.7 changes COME_FROM to COME_FROM_FINALLY
|
||||
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
|
||||
tryfinallystmt ::= SETUP_FINALLY suite_stmts_opt
|
||||
POP_BLOCK LOAD_CONST COME_FROM suite_stmts_opt
|
||||
END_FINALLY
|
||||
""")
|
||||
super(Python27Parser, self).customize_grammar_rules(tokens, customize)
|
||||
self.check_reduce['and'] = 'AST'
|
||||
# self.check_reduce['or'] = 'AST'
|
||||
self.check_reduce['raise_stmt1'] = 'AST'
|
||||
# self.check_reduce['conditional_true'] = 'AST'
|
||||
self.check_reduce['list_if_not'] = 'AST'
|
||||
self.check_reduce['list_if'] = 'AST'
|
||||
self.check_reduce['conditional_true'] = 'AST'
|
||||
return
|
||||
|
||||
def reduce_is_invalid(self, rule, ast, tokens, first, last):
|
||||
@@ -195,6 +203,21 @@ class Python27Parser(Python2Parser):
|
||||
tokens[last].pattr == jmp_false.pattr)
|
||||
elif rule[0] == ('raise_stmt1'):
|
||||
return ast[0] == 'expr' and ast[0][0] == 'or'
|
||||
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
|
||||
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
|
||||
elif rule == ('or', ('expr', 'jmp_true', 'expr', '\\e_come_from_opt')):
|
||||
# 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)
|
||||
# elif rule[0] == ('conditional_true'):
|
||||
# # FIXME: the below is a hack: we check expr for
|
||||
# # nodes that could have possibly been a been a Boolean.
|
||||
|
@@ -207,7 +207,7 @@ TABLE_DIRECT = {
|
||||
'conditional': ( '%p if %p else %p', (2, 27), (0, 27), (4, 27) ),
|
||||
'conditional_true': ( '%p if 1 else %p', (0, 27), (2, 27) ),
|
||||
'ret_cond': ( '%p if %p else %p', (2, 27), (0, 27), (-1, 27) ),
|
||||
'conditionalnot': ( '%p if not %p else %p', (2, 27), (0, 22), (4, 27) ),
|
||||
'conditional_not': ( '%p if not %p else %p', (2, 27), (0, 22), (4, 27) ),
|
||||
'ret_cond_not': ( '%p if not %p else %p', (2, 27), (0, 22), (-1, 27) ),
|
||||
'conditional_lambda':
|
||||
( '%c if %c else %c',
|
||||
|
@@ -784,7 +784,7 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
def n_list_comp(self, node):
|
||||
"""List comprehensions"""
|
||||
p = self.prec
|
||||
self.prec = 27
|
||||
self.prec = 100
|
||||
if self.version >= 2.7:
|
||||
if self.is_pypy:
|
||||
self.n_list_comp_pypy27(node)
|
||||
|
Reference in New Issue
Block a user