You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 09:22:40 +08:00
Python 3.2 MAKE_FUNCTION adjustment
This commit is contained in:
BIN
test/bytecode_3.2/10_lambda.pyc
Normal file
BIN
test/bytecode_3.2/10_lambda.pyc
Normal file
Binary file not shown.
@@ -1,10 +0,0 @@
|
|||||||
# Bug in Python 3
|
|
||||||
|
|
||||||
# mklambda ::= LOAD_LAMBDA LOAD_CONST MAKE_FUNCTION_0
|
|
||||||
# _mklambda ::= mklambda
|
|
||||||
# expr ::= _mklambda
|
|
||||||
# kwarg ::= LOAD_CONST expr
|
|
||||||
# exprlist ::= exprlist expr
|
|
||||||
# call_function ::= expr kwarg CALL_FUNCTION_256
|
|
||||||
|
|
||||||
inspect.formatargvalues(formatvalue=lambda value: __file__)
|
|
28
test/simple_source/expression/10_lambda.py
Normal file
28
test/simple_source/expression/10_lambda.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Bug in Python 3
|
||||||
|
|
||||||
|
# Python 3.3+
|
||||||
|
# mklambda ::= LOAD_LAMBDA LOAD_CONST MAKE_FUNCTION_0
|
||||||
|
# Python 3.0 .. 3.2
|
||||||
|
# mklambda ::= LOAD_LAMBDA MAKE_FUNCTION_0
|
||||||
|
|
||||||
|
# _mklambda ::= mklambda
|
||||||
|
# expr ::= _mklambda
|
||||||
|
# kwarg ::= LOAD_CONST expr
|
||||||
|
# exprlist ::= exprlist expr
|
||||||
|
# call_function ::= expr kwarg CALL_FUNCTION_256
|
||||||
|
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
inspect.formatargvalues(formatvalue=lambda value: __file__)
|
||||||
|
|
||||||
|
# bug from python 3.2 calendar
|
||||||
|
# Handling lambda
|
||||||
|
months = []
|
||||||
|
months.insert(0, lambda x: "")
|
||||||
|
|
||||||
|
# Python 3.2 configparser.py
|
||||||
|
class ExtendedInterpolation():
|
||||||
|
def items(self, section, option, d):
|
||||||
|
value_getter = lambda option: self._interpolation.before_get(self,
|
||||||
|
section, option, d[option], d)
|
||||||
|
return value_getter
|
@@ -325,7 +325,6 @@ class Python3Parser(PythonParser):
|
|||||||
load_genexpr ::= BUILD_TUPLE_1 LOAD_GENEXPR LOAD_CONST
|
load_genexpr ::= BUILD_TUPLE_1 LOAD_GENEXPR LOAD_CONST
|
||||||
|
|
||||||
# Is there something general going on here?
|
# Is there something general going on here?
|
||||||
genexpr ::= LOAD_GENEXPR LOAD_CONST MAKE_FUNCTION_0 expr GET_ITER CALL_FUNCTION_1
|
|
||||||
genexpr ::= load_closure LOAD_GENEXPR LOAD_CONST MAKE_CLOSURE_0 expr GET_ITER CALL_FUNCTION_1
|
genexpr ::= load_closure LOAD_GENEXPR LOAD_CONST MAKE_CLOSURE_0 expr GET_ITER CALL_FUNCTION_1
|
||||||
dictcomp ::= load_closure LOAD_DICTCOMP LOAD_CONST MAKE_CLOSURE_0 expr GET_ITER CALL_FUNCTION_1
|
dictcomp ::= load_closure LOAD_DICTCOMP LOAD_CONST MAKE_CLOSURE_0 expr GET_ITER CALL_FUNCTION_1
|
||||||
'''
|
'''
|
||||||
@@ -418,6 +417,13 @@ class Python3Parser(PythonParser):
|
|||||||
% (('expr ' * (args_pos-1)), opname, args_pos))
|
% (('expr ' * (args_pos-1)), opname, args_pos))
|
||||||
self.add_unique_rule(rule, token.type, args_pos, customize)
|
self.add_unique_rule(rule, token.type, args_pos, customize)
|
||||||
|
|
||||||
|
def add_make_function_rule(self, rule, opname, attr, customize):
|
||||||
|
"""Python 3.3 added a an addtional LOAD_CONST before MAKE_FUNCTION and
|
||||||
|
this has an effect on many rules.
|
||||||
|
"""
|
||||||
|
new_rule = rule % (('LOAD_CONST ') * (1 if self.version >= 3.3 else 0))
|
||||||
|
self.add_unique_rule(new_rule, opname, attr, customize)
|
||||||
|
|
||||||
def add_custom_rules(self, tokens, customize):
|
def add_custom_rules(self, tokens, customize):
|
||||||
"""
|
"""
|
||||||
Special handling for opcodes that take a variable number
|
Special handling for opcodes that take a variable number
|
||||||
@@ -444,7 +450,9 @@ class Python3Parser(PythonParser):
|
|||||||
load_closure ::= {LOAD_CLOSURE}^n BUILD_TUPLE_n
|
load_closure ::= {LOAD_CLOSURE}^n BUILD_TUPLE_n
|
||||||
# call_function (see custom_classfunc_rule)
|
# call_function (see custom_classfunc_rule)
|
||||||
|
|
||||||
|
------------
|
||||||
Python 3.3+:
|
Python 3.3+:
|
||||||
|
------------
|
||||||
listcomp ::= LOAD_LISTCOMP LOAD_CONST MAKE_FUNCTION_0 expr
|
listcomp ::= LOAD_LISTCOMP LOAD_CONST MAKE_FUNCTION_0 expr
|
||||||
GET_ITER CALL_FUNCTION_1
|
GET_ITER CALL_FUNCTION_1
|
||||||
listcomp ::= {expr}^n LOAD_LISTCOMP MAKE_CLOSURE
|
listcomp ::= {expr}^n LOAD_LISTCOMP MAKE_CLOSURE
|
||||||
@@ -452,12 +460,14 @@ class Python3Parser(PythonParser):
|
|||||||
|
|
||||||
dictcomp ::= LOAD_DICTCOMP LOAD_CONST MAKE_FUNCTION_0 expr
|
dictcomp ::= LOAD_DICTCOMP LOAD_CONST MAKE_FUNCTION_0 expr
|
||||||
GET_ITER CALL_FUNCTION_1
|
GET_ITER CALL_FUNCTION_1
|
||||||
|
genexpr ::= LOAD_GENEXPR LOAD_CONST MAKE_FUNCTION_0 expr GET_ITER CALL_FUNCTION_1
|
||||||
|
|
||||||
|
------------
|
||||||
Python < 3.3
|
Python < 3.3
|
||||||
|
------------
|
||||||
listcomp ::= LOAD_LISTCOMP MAKE_FUNCTION_0 expr
|
listcomp ::= LOAD_LISTCOMP MAKE_FUNCTION_0 expr
|
||||||
GET_ITER CALL_FUNCTION_1
|
GET_ITER CALL_FUNCTION_1
|
||||||
|
genexpr ::= LOAD_GENEXPR MAKE_FUNCTION_0 expr GET_ITER CALL_FUNCTION_1
|
||||||
|
|
||||||
setcomp ::= {expr}^n LOAD_SETCOMP MAKE_CLOSURE
|
setcomp ::= {expr}^n LOAD_SETCOMP MAKE_CLOSURE
|
||||||
GET_ITER CALL_FUNCTION_1
|
GET_ITER CALL_FUNCTION_1
|
||||||
|
|
||||||
@@ -485,6 +495,9 @@ class Python3Parser(PythonParser):
|
|||||||
rule = ("dictcomp ::= LOAD_DICTCOMP MAKE_FUNCTION_0 expr "
|
rule = ("dictcomp ::= LOAD_DICTCOMP MAKE_FUNCTION_0 expr "
|
||||||
"GET_ITER CALL_FUNCTION_1")
|
"GET_ITER CALL_FUNCTION_1")
|
||||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
self.add_unique_rule(rule, opname, token.attr, customize)
|
||||||
|
elif opname == 'LOAD_GENEXPR':
|
||||||
|
rule_pat = "genexpr ::= LOAD_GENEXPR %sMAKE_FUNCTION_0 expr GET_ITER CALL_FUNCTION_1"
|
||||||
|
self.add_make_function_rule(rule_pat, opname, token.attr, customize)
|
||||||
elif opname == 'LOAD_SETCOMP':
|
elif opname == 'LOAD_SETCOMP':
|
||||||
if self.version >= 3.3:
|
if self.version >= 3.3:
|
||||||
rule = ("setcomp ::= LOAD_SETCOMP LOAD_CONST MAKE_FUNCTION_0 expr "
|
rule = ("setcomp ::= LOAD_SETCOMP LOAD_CONST MAKE_FUNCTION_0 expr "
|
||||||
@@ -526,9 +539,8 @@ class Python3Parser(PythonParser):
|
|||||||
elif opname_base.startswith('MAKE_FUNCTION'):
|
elif opname_base.startswith('MAKE_FUNCTION'):
|
||||||
# DRY with MAKE_CLOSURE
|
# DRY with MAKE_CLOSURE
|
||||||
args_pos, args_kw, annotate_args = token.attr
|
args_pos, args_kw, annotate_args = token.attr
|
||||||
rule = ('mklambda ::= %sLOAD_LAMBDA LOAD_CONST %s' %
|
rule_pat = ('mklambda ::= %sLOAD_LAMBDA %%s%s' % ('pos_arg '* args_pos, opname))
|
||||||
('pos_arg '* args_pos, opname))
|
self.add_make_function_rule(rule_pat, opname, token.attr, customize)
|
||||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
|
||||||
if self.version == 3.3:
|
if self.version == 3.3:
|
||||||
# positional args after keyword args
|
# positional args after keyword args
|
||||||
rule = ('mkfunc ::= kwargs %s%s %s' %
|
rule = ('mkfunc ::= kwargs %s%s %s' %
|
||||||
@@ -549,14 +561,9 @@ class Python3Parser(PythonParser):
|
|||||||
# DRY with MAKE_FUNCTION
|
# DRY with MAKE_FUNCTION
|
||||||
# Note: this probably doesn't handle kwargs proprerly
|
# Note: this probably doesn't handle kwargs proprerly
|
||||||
args_pos, args_kw, annotate_args = token.attr
|
args_pos, args_kw, annotate_args = token.attr
|
||||||
rule = ('mklambda ::= %sload_closure LOAD_LAMBDA LOAD_CONST %s' %
|
rule_pat = ('mklambda ::= %sload_closure LOAD_LAMBDA %%s%s' %
|
||||||
('pos_arg '* args_pos, opname))
|
('pos_arg '* args_pos, opname))
|
||||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
self.add_make_function_rule(rule_pat, opname, token.attr, customize)
|
||||||
self.add_unique_rule('genexpr ::= %sload_closure '
|
|
||||||
'load_genexpr %s '
|
|
||||||
'expr GET_ITER CALL_FUNCTION_1' %
|
|
||||||
('pos_arg ' * args_pos, opname),
|
|
||||||
opname, token.attr, customize)
|
|
||||||
if self.version >= 3.3:
|
if self.version >= 3.3:
|
||||||
rule1 = ('listcomp ::= %sload_closure LOAD_LISTCOMP LOAD_CONST %s expr '
|
rule1 = ('listcomp ::= %sload_closure LOAD_LISTCOMP LOAD_CONST %s expr '
|
||||||
'GET_ITER CALL_FUNCTION_1' % ('expr ' * args_pos, opname))
|
'GET_ITER CALL_FUNCTION_1' % ('expr ' * args_pos, opname))
|
||||||
|
@@ -1057,7 +1057,7 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
|
|
||||||
def n_genexpr(self, node):
|
def n_genexpr(self, node):
|
||||||
self.write('(')
|
self.write('(')
|
||||||
code_index = -6 if self.version > 3.0 else -5
|
code_index = -6 if self.version > 3.2 else -5
|
||||||
self.comprehension_walk(node, iter_index=3, code_index=code_index)
|
self.comprehension_walk(node, iter_index=3, code_index=code_index)
|
||||||
self.write(')')
|
self.write(')')
|
||||||
self.prune()
|
self.prune()
|
||||||
@@ -1796,8 +1796,16 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
kw_args, annotate_args = (0, 0)
|
kw_args, annotate_args = (0, 0)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if self.version > 3.0 and isLambda and iscode(node[-3].attr):
|
if 3.0 <= self.version <= 3.2:
|
||||||
code = node[-3].attr
|
lambda_index = -2
|
||||||
|
elif 3.03<= self.version:
|
||||||
|
lambda_index = -3
|
||||||
|
else:
|
||||||
|
lambda_index = None
|
||||||
|
|
||||||
|
if lambda_index and isLambda and iscode(node[lambda_index].attr):
|
||||||
|
assert node[lambda_index].type == 'LOAD_LAMBDA'
|
||||||
|
code = node[lambda_index].attr
|
||||||
else:
|
else:
|
||||||
code = code.attr
|
code = code.attr
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user