More merge fixups from master

This commit is contained in:
rocky
2017-06-18 16:05:22 -04:00
parent b7d8cbfaf5
commit 0f489672b9
4 changed files with 68 additions and 61 deletions

View File

@@ -23,7 +23,7 @@ Finally we save token information.
from uncompyle6 import PYTHON_VERSION from uncompyle6 import PYTHON_VERSION
if PYTHON_VERSION < 2.6: if PYTHON_VERSION < 2.6:
from xdis.namedtuple25 import namedtuple from xdis.namedtuple24 import namedtuple
else: else:
from collections import namedtuple from collections import namedtuple

View File

@@ -23,7 +23,7 @@ Finally we save token information.
from uncompyle6 import PYTHON_VERSION from uncompyle6 import PYTHON_VERSION
if PYTHON_VERSION < 2.6: if PYTHON_VERSION < 2.6:
from xdis.namedtuple25 import namedtuple from xdis.namedtuple24 import namedtuple
else: else:
from collections import namedtuple from collections import namedtuple

View File

@@ -79,7 +79,7 @@ from spark_parser.ast import GenericASTTraversalPruningException
from uncompyle6 import PYTHON_VERSION from uncompyle6 import PYTHON_VERSION
if PYTHON_VERSION < 2.6: if PYTHON_VERSION < 2.6:
from xdis.namedtuple25 import namedtuple from xdis.namedtuple24 import namedtuple
else: else:
from collections import namedtuple from collections import namedtuple

View File

@@ -430,34 +430,10 @@ def make_function2(self, node, isLambda, nested=1, codeNode=None):
def make_function3(self, node, isLambda, nested=1, codeNode=None): def make_function3(self, node, isLambda, nested=1, codeNode=None):
"""Dump function definition, doc string, and function body in """Dump function definition, doc string, and function body."""
Python version 3.0 and above
"""
# For Python 3.3, the evaluation stack in MAKE_FUNCTION is: # FIXME: call make_function3 if we are self.version >= 3.0
# and then simplify the below.
# * default argument objects in positional order
# * pairs of name and default argument, with the name just below
# the object on the stack, for keyword-only parameters
# * parameter annotation objects
# * a tuple listing the parameter names for the annotations
# (only if there are ony annotation objects)
# * the code associated with the function (at TOS1)
# * the qualified name of the function (at TOS)
# For Python 3.0 .. 3.2 the evaluation stack is:
# The function object is defined to have argc default parameters,
# which are found below TOS.
# * first come positional args in the order they are given in the source,
# * next come the keyword args in the order they given in the source,
# * finally is the code associated with the function (at TOS)
#
# Note: There is no qualified name at TOS
# MAKE_CLOSURE adds an additional closure slot
# Thank you, Python, for a such a well-thought out system that has
# changed 4 or so times.
def build_param(ast, name, default): def build_param(ast, name, default):
"""build parameters: """build parameters:
@@ -477,31 +453,21 @@ def make_function3(self, node, isLambda, nested=1, codeNode=None):
# MAKE_FUNCTION_... or MAKE_CLOSURE_... # MAKE_FUNCTION_... or MAKE_CLOSURE_...
assert node[-1].type.startswith('MAKE_') assert node[-1].type.startswith('MAKE_')
# Python 3.3+ adds a qualified name at TOS (-1)
# moving down the LOAD_LAMBDA instruction
if 3.0 <= self.version <= 3.2:
lambda_index = -2
elif 3.03 <= self.version:
lambda_index = -3
else:
lambda_index = None
args_node = node[-1] args_node = node[-1]
if isinstance(args_node.attr, tuple): if isinstance(args_node.attr, tuple):
pos_args, kw_args, annotate_argc = args_node.attr if self.version <= 3.3 and len(node) > 2 and node[-3] != 'LOAD_LAMBDA':
if self.version <= 3.3 and len(node) > 2 and node[lambda_index] != 'LOAD_LAMBDA': # positional args are after kwargs
# args are after kwargs; kwargs are bundled as one node
defparams = node[1:args_node.attr[0]+1] defparams = node[1:args_node.attr[0]+1]
else: else:
# args are before kwargs; kwags as bundled as one node # positional args are before kwargs
defparams = node[:args_node.attr[0]] defparams = node[:args_node.attr[0]]
pos_args, kw_args, annotate_argc = args_node.attr
else: else:
if self.version < 3.6: if self.version < 3.6:
defparams = node[:args_node.attr] defparams = node[:args_node.attr]
else: else:
default, kw, annotate, closure = args_node.attr default, kw, annotate, closure = args_node.attr
# FIXME: start here for Python 3.6 and above: # FIXME: start here.
defparams = [] defparams = []
# if default: # if default:
# defparams = node[-(2 + kw + annotate + closure)] # defparams = node[-(2 + kw + annotate + closure)]
@@ -511,6 +477,12 @@ def make_function3(self, node, isLambda, nested=1, codeNode=None):
kw_args = 0 kw_args = 0
pass pass
if 3.0 <= self.version <= 3.2:
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): if lambda_index and isLambda and iscode(node[lambda_index].attr):
assert node[lambda_index].type == 'LOAD_LAMBDA' assert node[lambda_index].type == 'LOAD_LAMBDA'
@@ -526,7 +498,7 @@ def make_function3(self, node, isLambda, nested=1, codeNode=None):
paramnames = list(code.co_varnames[:argc]) paramnames = list(code.co_varnames[:argc])
# defaults are for last n parameters, thus reverse # defaults are for last n parameters, thus reverse
if not 3.0 <= self.version <= 3.1: if not 3.0 <= self.version <= 3.2:
paramnames.reverse(); defparams.reverse() paramnames.reverse(); defparams.reverse()
try: try:
@@ -543,27 +515,62 @@ def make_function3(self, node, isLambda, nested=1, codeNode=None):
kw_pairs = args_node.attr[1] kw_pairs = args_node.attr[1]
else: else:
kw_pairs = 0 kw_pairs = 0
indent = self.indent
# build parameters # build parameters
params = [build_param(ast, name, d) for if self.version != 3.2:
name, d in zip_longest(paramnames, defparams, fillvalue=None)] tup = [paramnames, defparams]
params = [build_param(ast, name, default) for
if not 3.0 <= self.version <= 3.1: name, default in map(lambda *tup:tup, *tup)]
params.reverse() # back to correct order params.reverse() # back to correct order
if code_has_star_arg(code): if code_has_star_arg(code):
if self.version > 3.0: if self.version > 3.0:
params.append('*%s' % code.co_varnames[argc + kw_pairs]) params.append('*%s' % code.co_varnames[argc + kw_pairs])
else: else:
params.append('*%s' % code.co_varnames[argc]) params.append('*%s' % code.co_varnames[argc])
argc += 1 argc += 1
# dump parameter list (with default values)
if isLambda:
self.write("lambda ", ", ".join(params))
else:
self.write("(", ", ".join(params))
# self.println(indent, '#flags:\t', int(code.co_flags))
# dump parameter list (with default values)
if isLambda:
self.write("lambda ", ", ".join(params))
else: else:
self.write("(", ", ".join(params)) if isLambda:
# self.println(indent, '#flags:\t', int(code.co_flags)) self.write("lambda ")
else:
self.write("(")
pass
last_line = self.f.getvalue().split("\n")[-1]
l = len(last_line)
indent = ' ' * l
line_number = self.line_number
if code_has_star_arg(code):
self.write('*%s' % code.co_varnames[argc + kw_pairs])
argc += 1
i = len(paramnames) - len(defparams)
self.write(", ".join(paramnames[:i]))
if i > 0:
suffix = ', '
else:
suffix = ''
for n in node:
if n == 'pos_arg':
self.write(suffix)
self.write(paramnames[i] + '=')
i += 1
self.preorder(n)
if (line_number != self.line_number):
suffix = ",\n" + indent
line_number = self.line_number
else:
suffix = ', '
if kw_args > 0: if kw_args > 0:
if not (4 & code.co_flags): if not (4 & code.co_flags):