You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Python 3.0 comprehensions are a snowflake
This commit is contained in:
@@ -59,11 +59,22 @@ class Python30Parser(Python31Parser):
|
|||||||
LOAD_FAST FOR_ITER store comp_iter
|
LOAD_FAST FOR_ITER store comp_iter
|
||||||
JUMP_BACK POP_TOP JUMP_BACK RETURN_VALUE RETURN_LAST
|
JUMP_BACK POP_TOP JUMP_BACK RETURN_VALUE RETURN_LAST
|
||||||
|
|
||||||
list_comp_header ::= BUILD_LIST_0 DUP_TOP STORE_FAST
|
list_comp_header ::= BUILD_LIST_0 DUP_TOP STORE_FAST
|
||||||
list_comp ::= list_comp_header
|
list_comp ::= list_comp_header
|
||||||
LOAD_FAST FOR_ITER store comp_iter
|
LOAD_FAST FOR_ITER store comp_iter
|
||||||
JUMP_BACK
|
JUMP_BACK
|
||||||
|
|
||||||
|
set_comp_header ::= BUILD_SET_0 DUP_TOP STORE_FAST
|
||||||
|
set_comp ::= set_comp_header
|
||||||
|
LOAD_FAST FOR_ITER store comp_iter
|
||||||
|
JUMP_BACK
|
||||||
|
|
||||||
|
dict_comp_header ::= BUILD_MAP_0 DUP_TOP STORE_FAST
|
||||||
|
dict_comp ::= dict_comp_header
|
||||||
|
LOAD_FAST FOR_ITER store dict_comp_iter
|
||||||
|
JUMP_BACK
|
||||||
|
|
||||||
|
dict_comp_iter ::= expr expr ROT_TWO expr STORE_SUBSCR
|
||||||
|
|
||||||
# JUMP_IF_TRUE POP_TOP as a replacement
|
# JUMP_IF_TRUE POP_TOP as a replacement
|
||||||
comp_if ::= expr jmp_false comp_iter
|
comp_if ::= expr jmp_false comp_iter
|
||||||
|
@@ -1051,10 +1051,15 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
self.prec=100
|
self.prec=100
|
||||||
ast = ast[0]
|
ast = ast[0]
|
||||||
|
|
||||||
|
# Pick out important parts of the comprehension:
|
||||||
|
# * the variable we interate over: "store"
|
||||||
|
# * the results we accumulate: "n"
|
||||||
|
|
||||||
|
is_30_dict_comp = False
|
||||||
store = None
|
store = None
|
||||||
n = ast[iter_index]
|
n = ast[iter_index]
|
||||||
if ast in ['set_comp_func', 'dict_comp_func',
|
if ast in ('set_comp_func', 'dict_comp_func',
|
||||||
'list_comp', 'set_comp_func_header']:
|
'list_comp', 'set_comp_func_header'):
|
||||||
for k in ast:
|
for k in ast:
|
||||||
if k == 'comp_iter':
|
if k == 'comp_iter':
|
||||||
n = k
|
n = k
|
||||||
@@ -1063,6 +1068,21 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
pass
|
pass
|
||||||
pass
|
pass
|
||||||
pass
|
pass
|
||||||
|
elif ast in ('dict_comp', 'set_comp'):
|
||||||
|
assert self.version == 3.0
|
||||||
|
for k in ast:
|
||||||
|
if k in ('dict_comp_header', 'set_comp_header'):
|
||||||
|
n = k
|
||||||
|
elif k == 'store':
|
||||||
|
store = k
|
||||||
|
elif k == 'dict_comp_iter':
|
||||||
|
is_30_dict_comp = True
|
||||||
|
n = (k[3], k[1])
|
||||||
|
pass
|
||||||
|
elif k == 'comp_iter':
|
||||||
|
n = k[1]
|
||||||
|
pass
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
assert n == 'list_iter', n
|
assert n == 'list_iter', n
|
||||||
|
|
||||||
@@ -1115,7 +1135,12 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
# Another approach might be to be able to pass in the source name
|
# Another approach might be to be able to pass in the source name
|
||||||
# for the dummy argument.
|
# for the dummy argument.
|
||||||
|
|
||||||
self.preorder(n[0])
|
if is_30_dict_comp:
|
||||||
|
self.preorder(n[0])
|
||||||
|
self.write(': ')
|
||||||
|
self.preorder(n[1])
|
||||||
|
else:
|
||||||
|
self.preorder(n[0])
|
||||||
self.write(' for ')
|
self.write(' for ')
|
||||||
if comp_store:
|
if comp_store:
|
||||||
self.preorder(comp_store)
|
self.preorder(comp_store)
|
||||||
|
Reference in New Issue
Block a user