Fix * in multi-target assignment

This commit is contained in:
rocky
2016-06-19 02:31:19 -04:00
parent d7b79c2b59
commit 10b95cd9a8
5 changed files with 36 additions and 9 deletions

Binary file not shown.

View File

@@ -0,0 +1,3 @@
# Bug from Python 3.4 ftplib
cls_or_self, *rest = args
a, *b, c = args

View File

@@ -445,10 +445,6 @@ class Python3Parser(PythonParser):
setcomp ::= {expr}^n LOAD_SETCOMP MAKE_CLOSURE
GET_ITER CALL_FUNCTION_1
dictcomp ::= LOAD_DICTCOMP MAKE_FUNCTION_0 expr
GET_ITER CALL_FUNCTION_1
# build_class (see load_build_class)
build_list ::= {expr}^n BUILD_LIST_n
@@ -456,9 +452,10 @@ class Python3Parser(PythonParser):
load_closure ::= {LOAD_CLOSURE}^n BUILD_TUPLE_n
unpack_list ::= UNPACK_LIST {expr}^n
unpack ::= UNPACK_TUPLE {expr}^n
unpack ::= UNPACK_SEQEUENCE {expr}^n
unpack_list ::= UNPACK_LIST_n {expr}^n
unpack ::= UNPACK_TUPLE_n {expr}^n
unpack ::= UNPACK_SEQEUENCE_n {expr}^n
unpack_ex ::= UNPACK_EX_b_a {expr}^(a+b)
mkfunc ::= {pos_arg}^n LOAD_CONST MAKE_FUNCTION_n
mklambda ::= {pos_arg}^n LOAD_LAMBDA MAKE_FUNCTION_n
@@ -524,6 +521,10 @@ class Python3Parser(PythonParser):
self.add_unique_rule(rule, opname, token.attr, customize)
rule = "mapexpr ::= %s %s" % (opname, kvlist_n)
self.add_unique_rule(rule, opname, token.attr, customize)
elif opname_base in ('UNPACK_EX'):
before_count, after_count = token.attr
rule = 'unpack ::= ' + opname + ' designator' * (before_count + after_count + 1)
self.add_unique_rule(rule, opname, token.attr, customize)
elif opname_base in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'):
rule = 'unpack ::= ' + opname + ' designator' * token.attr
self.add_unique_rule(rule, opname, token.attr, customize)

View File

@@ -91,6 +91,7 @@ class Scanner3(scan.Scanner):
for inst in bytecode:
argval = inst.argval
if inst.offset in jump_targets:
jump_idx = 0
for jump_offset in jump_targets[inst.offset]:
@@ -153,6 +154,14 @@ class Scanner3(scan.Scanner):
):
pos_args = inst.argval
opname = '%s_%d' % (opname, pos_args)
elif opname == 'UNPACK_EX':
# FIXME: try with scanner and parser by
# changing inst.argval
before_args = inst.argval & 0xFF
after_args = (inst.argval >> 8) & 0xff
pattr = "%d before vararg, %d after" % (before_args, after_args)
argval = (before_args, after_args)
opname = '%s_%d+%d' % (opname, before_args, after_args)
elif opname == 'JUMP_ABSOLUTE':
pattr = inst.argval
target = self.get_target(inst.offset)
@@ -171,7 +180,7 @@ class Scanner3(scan.Scanner):
tokens.append(
Token(
type_ = opname,
attr = inst.argval,
attr = argval,
pattr = pattr,
offset = inst.offset,
linestart = inst.starts_line,
@@ -308,7 +317,7 @@ class Scanner3(scan.Scanner):
designator_ops = set([
STORE_FAST, STORE_NAME, STORE_GLOBAL, STORE_DEREF, STORE_ATTR,
STORE_SUBSCR, UNPACK_SEQUENCE, JUMP_ABSOLUTE
STORE_SUBSCR, UNPACK_SEQUENCE, JUMP_ABSOLUTE, UNPACK_EX
])
# Compose preliminary list of indices with statements,

View File

@@ -1432,6 +1432,20 @@ class SourceWalker(GenericASTTraversal, object):
self.prune()
def n_unpack(self, node):
if node[0].type.startswith('UNPACK_EX'):
# Python 3+
before_count, after_count = node[0].attr
for i in range(before_count+1):
self.preorder(node[i])
if i != 0:
self.write(', ')
self.write('*')
for i in range(1, after_count+2):
self.preorder(node[before_count+i])
if i != after_count + 1:
self.write(', ')
self.prune()
return
for n in node[1:]:
if n[0].type == 'unpack':
n[0].type = 'unpack_w_parens'