You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-02 16:44:46 +08:00
Simplify make_function3 by customization
We now have different routines for 3.6+ (and 2.x from before). This is desirable before fixing 3.0..3.5 lambdas with default paramerts and * args.
This commit is contained in:
BIN
test/bytecode_3.3_run/00_docstring.pyc
Normal file
BIN
test/bytecode_3.3_run/00_docstring.pyc
Normal file
Binary file not shown.
@@ -341,10 +341,7 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
|
||||
- handle defaults
|
||||
- handle format tuple parameters
|
||||
"""
|
||||
if self.version >= 3.6:
|
||||
value = default
|
||||
else:
|
||||
value = self.traverse(default, indent="")
|
||||
value = self.traverse(default, indent="")
|
||||
maybe_show_tree_param_default(self.showast, name, value)
|
||||
if annotation:
|
||||
result = "%s: %s=%s" % (name, annotation, value)
|
||||
@@ -380,9 +377,7 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
|
||||
# not to be confused with keyword parameters which may appear after *.
|
||||
args_attr = args_node.attr
|
||||
|
||||
if isinstance(args_attr, tuple) or (
|
||||
self.version >= 3.6 and isinstance(args_attr, list)
|
||||
):
|
||||
if isinstance(args_attr, tuple):
|
||||
if len(args_attr) == 3:
|
||||
pos_args, kw_args, annotate_argc = args_attr
|
||||
else:
|
||||
@@ -428,9 +423,7 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
|
||||
lc_index = -3
|
||||
pass
|
||||
|
||||
if (
|
||||
self.version <= 3.5
|
||||
and len(node) > 2
|
||||
if (len(node) > 2
|
||||
and (have_kwargs or node[lc_index].kind != "load_closure")
|
||||
):
|
||||
|
||||
@@ -458,85 +451,11 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
|
||||
default_values_start : default_values_start + args_node.attr[0]
|
||||
]
|
||||
else:
|
||||
if self.version < 3.6:
|
||||
defparams = node[: args_node.attr[0]]
|
||||
kw_args = 0
|
||||
else:
|
||||
defparams = []
|
||||
# FIXME: DRY with code below
|
||||
default, kw_args, annotate_argc = args_node.attr[0:3]
|
||||
if default:
|
||||
expr_node = node[0]
|
||||
if node[0] == "pos_arg":
|
||||
expr_node = expr_node[0]
|
||||
assert (
|
||||
expr_node == "expr"
|
||||
), "expecting mkfunc default node to be an expr"
|
||||
if expr_node[0] == "LOAD_CONST" and isinstance(
|
||||
expr_node[0].attr, tuple
|
||||
):
|
||||
defparams = [repr(a) for a in expr_node[0].attr]
|
||||
elif expr_node[0] in frozenset(("list", "tuple", "dict", "set")):
|
||||
defparams = [
|
||||
self.traverse(n, indent="") for n in expr_node[0][:-1]
|
||||
]
|
||||
else:
|
||||
defparams = []
|
||||
pass
|
||||
else:
|
||||
if self.version < 3.6:
|
||||
defparams = node[: args_node.attr]
|
||||
defparams = node[: args_node.attr[0]]
|
||||
kw_args = 0
|
||||
else:
|
||||
default, kw_args, annotate, closure = args_node.attr
|
||||
if default:
|
||||
expr_node = node[0]
|
||||
if node[0] == "pos_arg":
|
||||
expr_node = expr_node[0]
|
||||
assert (
|
||||
expr_node == "expr"
|
||||
), "expecting mkfunc default node to be an expr"
|
||||
if expr_node[0] == "LOAD_CONST" and isinstance(
|
||||
expr_node[0].attr, tuple
|
||||
):
|
||||
defparams = [repr(a) for a in expr_node[0].attr]
|
||||
elif expr_node[0] in frozenset(("list", "tuple", "dict", "set")):
|
||||
defparams = [self.traverse(n, indent="") for n in expr_node[0][:-1]]
|
||||
else:
|
||||
defparams = []
|
||||
|
||||
i = -4
|
||||
kw_pairs = 0
|
||||
if closure:
|
||||
# FIXME: fill in
|
||||
annotate = node[i]
|
||||
i -= 1
|
||||
if annotate_argc:
|
||||
# Turn into subroutine and DRY with other use
|
||||
annotate_node = node[i]
|
||||
if annotate_node == "expr":
|
||||
annotate_node = annotate_node[0]
|
||||
annotate_name_node = annotate_node[-1]
|
||||
if annotate_node == "dict" and annotate_name_node.kind.startswith(
|
||||
"BUILD_CONST_KEY_MAP"
|
||||
):
|
||||
types = [
|
||||
self.traverse(n, indent="") for n in annotate_node[:-2]
|
||||
]
|
||||
names = annotate_node[-2].attr
|
||||
l = len(types)
|
||||
assert l == len(names)
|
||||
for i in range(l):
|
||||
annotate_dict[names[i]] = types[i]
|
||||
pass
|
||||
pass
|
||||
i -= 1
|
||||
if kw_args:
|
||||
kw_node = node[i]
|
||||
if kw_node == "expr":
|
||||
kw_node = kw_node[0]
|
||||
if kw_node == "dict":
|
||||
kw_pairs = kw_node[-1].attr
|
||||
else:
|
||||
defparams = node[: args_node.attr]
|
||||
kw_args = 0
|
||||
pass
|
||||
|
||||
if lambda_index and is_lambda and iscode(node[lambda_index].attr):
|
||||
@@ -554,7 +473,7 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
|
||||
|
||||
paramnames = list(scanner_code.co_varnames[:argc])
|
||||
if kwonlyargcount > 0:
|
||||
if self.version <= 3.5 and is_lambda:
|
||||
if is_lambda:
|
||||
kwargs = []
|
||||
for i in range(kwonlyargcount):
|
||||
paramnames.append(scanner_code.co_varnames[argc+i])
|
||||
@@ -580,11 +499,7 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
|
||||
self.ERROR = p
|
||||
return
|
||||
|
||||
if self.version >= 3.0:
|
||||
if self.version < 3.6:
|
||||
kw_pairs = args_node.attr[1]
|
||||
else:
|
||||
kw_pairs = 0
|
||||
kw_pairs = 0
|
||||
|
||||
i = len(paramnames) - len(defparams)
|
||||
|
||||
@@ -613,18 +528,15 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
|
||||
params.reverse() # back to correct order
|
||||
|
||||
if code_has_star_arg(code):
|
||||
if self.version > 3.0:
|
||||
star_arg = code.co_varnames[argc + kwonlyargcount]
|
||||
if annotate_dict and star_arg in annotate_dict:
|
||||
params.append("*%s: %s" % (star_arg, annotate_dict[star_arg]))
|
||||
else:
|
||||
params.append("*%s" % star_arg)
|
||||
pass
|
||||
if is_lambda and self.version <= 3.5:
|
||||
params.reverse()
|
||||
star_arg = code.co_varnames[argc + kwonlyargcount]
|
||||
if annotate_dict and star_arg in annotate_dict:
|
||||
params.append("*%s: %s" % (star_arg, annotate_dict[star_arg]))
|
||||
else:
|
||||
params.append("*%s" % code.co_varnames[argc])
|
||||
if not is_lambda or self.version >= 3.6:
|
||||
params.append("*%s" % star_arg)
|
||||
pass
|
||||
if is_lambda:
|
||||
params.reverse()
|
||||
if not is_lambda:
|
||||
argc += 1
|
||||
|
||||
# dump parameter list (with default values)
|
||||
@@ -670,106 +582,37 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
|
||||
self.write(", ")
|
||||
ends_in_comma = True
|
||||
|
||||
if 3.0 <= self.version <= 3.5:
|
||||
kw_args = [None] * kwonlyargcount
|
||||
kw_nodes = node[0]
|
||||
if kw_nodes == "kwargs":
|
||||
for n in kw_nodes:
|
||||
name = eval(n[0].pattr)
|
||||
default = self.traverse(n[1], indent="")
|
||||
idx = kwargs.index(name)
|
||||
kw_args[idx] = "%s=%s" % (name, default)
|
||||
pass
|
||||
kw_args = [None] * kwonlyargcount
|
||||
kw_nodes = node[0]
|
||||
if kw_nodes == "kwargs":
|
||||
for n in kw_nodes:
|
||||
name = eval(n[0].pattr)
|
||||
default = self.traverse(n[1], indent="")
|
||||
idx = kwargs.index(name)
|
||||
kw_args[idx] = "%s=%s" % (name, default)
|
||||
pass
|
||||
pass
|
||||
|
||||
# FIXME: something weird is going on and the below
|
||||
# might not be right. On 3.4 kw_nodes != "kwarg"
|
||||
# because of some sort of type mismatch. I think
|
||||
# the test is for versions earlier than 3.3
|
||||
# on 3.5 if we have "kwarg" we still want to do this.
|
||||
# Perhaps we should be testing that kw_nodes is iterable?
|
||||
if kw_nodes != "kwarg" or self.version == 3.5:
|
||||
other_kw = [c == None for c in kw_args]
|
||||
|
||||
for i, flag in enumerate(other_kw):
|
||||
if flag:
|
||||
if i < len(kwargs):
|
||||
kw_args[i] = "%s" % kwargs[i]
|
||||
else:
|
||||
del kw_args[i]
|
||||
pass
|
||||
|
||||
self.write(", ".join(kw_args))
|
||||
ends_in_comma = False
|
||||
pass
|
||||
elif self.version >= 3.6:
|
||||
# argc = node[-1].attr
|
||||
# co = node[-3].attr
|
||||
# argcount = co.co_argcount
|
||||
# kwonlyargcount = co.co_kwonlyargcount
|
||||
|
||||
free_tup = ann_dict = kw_dict = default_tup = None
|
||||
fn_bits = node[-1].attr
|
||||
|
||||
# Skip over:
|
||||
# MAKE_FUNCTION,
|
||||
# optional docstring
|
||||
# LOAD_CONST qualified name,
|
||||
# LOAD_CONST code object
|
||||
index = -4 # Skip over:
|
||||
if node[-2] == "docstring":
|
||||
index = -5
|
||||
else:
|
||||
index = -4
|
||||
|
||||
if fn_bits[-1]:
|
||||
free_tup = node[index]
|
||||
index -= 1
|
||||
if fn_bits[-2]:
|
||||
ann_dict = node[index]
|
||||
index -= 1
|
||||
if fn_bits[-3]:
|
||||
kw_dict = node[index]
|
||||
index -= 1
|
||||
if fn_bits[-4]:
|
||||
default_tup = node[index]
|
||||
|
||||
if kw_dict == "expr":
|
||||
kw_dict = kw_dict[0]
|
||||
|
||||
# FIXME: handle free_tup, annotate_dict, and default_tup
|
||||
kw_args = [None] * kwonlyargcount
|
||||
|
||||
if kw_dict:
|
||||
assert kw_dict == "dict"
|
||||
defaults = [self.traverse(n, indent="") for n in kw_dict[:-2]]
|
||||
names = eval(self.traverse(kw_dict[-2]))
|
||||
assert len(defaults) == len(names)
|
||||
sep = ""
|
||||
# FIXME: possibly handle line breaks
|
||||
for i, n in enumerate(names):
|
||||
idx = kwargs.index(n)
|
||||
if annotate_dict and n in annotate_dict:
|
||||
t = "%s: %s=%s" % (n, annotate_dict[n], defaults[i])
|
||||
else:
|
||||
t = "%s=%s" % (n, defaults[i])
|
||||
kw_args[idx] = t
|
||||
pass
|
||||
pass
|
||||
|
||||
# handle others
|
||||
# FIXME: something weird is going on and the below
|
||||
# might not be right. On 3.4 kw_nodes != "kwarg"
|
||||
# because of some sort of type mismatch. I think
|
||||
# the test is for versions earlier than 3.3
|
||||
# on 3.5 if we have "kwarg" we still want to do this.
|
||||
# Perhaps we should be testing that kw_nodes is iterable?
|
||||
if kw_nodes != "kwarg" or self.version == 3.5:
|
||||
other_kw = [c == None for c in kw_args]
|
||||
|
||||
for i, flag in enumerate(other_kw):
|
||||
if flag:
|
||||
n = kwargs[i]
|
||||
if ann_dict and n in annotate_dict:
|
||||
kw_args[i] = "%s: %s" % (n, annotate_dict[n])
|
||||
if i < len(kwargs):
|
||||
kw_args[i] = "%s" % kwargs[i]
|
||||
else:
|
||||
kw_args[i] = "%s" % n
|
||||
del kw_args[i]
|
||||
pass
|
||||
|
||||
self.write(", ".join(kw_args))
|
||||
ends_in_comma = False
|
||||
pass
|
||||
|
||||
pass
|
||||
else:
|
||||
|
Reference in New Issue
Block a user