diff --git a/test/bytecode_3.6/05_set_comprehension.pyc b/test/bytecode_3.6/05_set_comprehension.pyc new file mode 100644 index 00000000..0db9601d Binary files /dev/null and b/test/bytecode_3.6/05_set_comprehension.pyc differ diff --git a/test/simple_source/bug35/04_call_function.py b/test/simple_source/bug35/04_call_function.py index a7b9902d..a5900f6a 100644 --- a/test/simple_source/bug35/04_call_function.py +++ b/test/simple_source/bug35/04_call_function.py @@ -54,3 +54,7 @@ def merge(*iterables, key=None, reverse=False): def __call__(self, *args, **kwds): pass + +# From 3.6.4 shutil +def unpack_archive(func, filename, dict, format_info, extract_dir=None): + func(filename, extract_dir, **dict(format_info[2])) diff --git a/uncompyle6/main.py b/uncompyle6/main.py index 79e44804..6d0bf61f 100644 --- a/uncompyle6/main.py +++ b/uncompyle6/main.py @@ -165,6 +165,7 @@ def main(in_base, out_base, files, codes, outfile=None, for filename in files: infile = os.path.join(in_base, filename) + # print("XXX", infile) if not os.path.exists(infile): sys.stderr.write("File '%s' doesn't exist. Skipped\n" % infile) diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index 54309521..9e9a4615 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -571,6 +571,7 @@ class Python3Parser(PythonParser): # This is used in parse36.py as well as here self.seen_LOAD_DICTCOMP = False + self.seen_LOAD_SETCOMP = False # Loop over instructions adding custom grammar rules based on @@ -806,6 +807,7 @@ class Python3Parser(PythonParser): elif opname == 'LOAD_LISTCOMP': self.add_unique_rule("expr ::= listcomp", opname, token.attr, customize) elif opname == 'LOAD_SETCOMP': + self.seen_LOAD_SETCOMP = True # Should this be generalized and put under MAKE_FUNCTION? if has_get_iter_call_function1: self.addRule("expr ::= set_comp", nop_func) diff --git a/uncompyle6/parsers/parse36.py b/uncompyle6/parsers/parse36.py index f3925400..86c042b6 100644 --- a/uncompyle6/parsers/parse36.py +++ b/uncompyle6/parsers/parse36.py @@ -107,14 +107,23 @@ class Python36Parser(Python35Parser): fstring_single ::= expr FORMAT_VALUE """ self.add_unique_doc_rules(rules_str, customize) - elif opname == 'MAKE_FUNCTION_8' and self.seen_LOAD_DICTCOMP: - # Is there something general going on here? - rule = """ - dict_comp ::= load_closure LOAD_DICTCOMP LOAD_CONST - MAKE_FUNCTION_8 expr - GET_ITER CALL_FUNCTION_1 - """ - self.addRule(rule, nop_func) + elif opname == 'MAKE_FUNCTION_8': + if self.seen_LOAD_DICTCOMP: + # Is there something general going on here? + rule = """ + dict_comp ::= load_closure LOAD_DICTCOMP LOAD_CONST + MAKE_FUNCTION_8 expr + GET_ITER CALL_FUNCTION_1 + """ + self.addRule(rule, nop_func) + elif self.seen_LOAD_SETCOMP: + rule = """ + set_comp ::= load_closure LOAD_SETCOMP LOAD_CONST + MAKE_FUNCTION_8 expr + GET_ITER CALL_FUNCTION_1 + """ + self.addRule(rule, nop_func) + elif opname == 'BEFORE_ASYNC_WITH': rules_str = """ stmt ::= async_with_stmt diff --git a/uncompyle6/semantics/customize.py b/uncompyle6/semantics/customize.py index a0d34f48..2d987f17 100644 --- a/uncompyle6/semantics/customize.py +++ b/uncompyle6/semantics/customize.py @@ -28,6 +28,7 @@ from xdis.code import iscode from uncompyle6.parsers.astnode import AST from uncompyle6.scanners.tok import Token from uncompyle6.semantics.helper import flatten_list +from spark_parser.ast import GenericASTTraversalPruningException def customize_for_version(self, is_pypy, version): if is_pypy: @@ -672,7 +673,11 @@ def customize_for_version(self, is_pypy, version): pass pass else: - assert False, "Don't know how to untangle dictionary" + self.write("**") + try: + self.default(node) + except GenericASTTraversalPruningException: + pass self.prec = p self.indent_less(INDENT_PER_LEVEL) diff --git a/uncompyle6/semantics/make_function.py b/uncompyle6/semantics/make_function.py index 4da3f7a9..7d85d65a 100644 --- a/uncompyle6/semantics/make_function.py +++ b/uncompyle6/semantics/make_function.py @@ -536,8 +536,10 @@ def make_function3(self, node, is_lambda, nested=1, codeNode=None): else: default, kw_args, annotate, closure = args_node.attr if default: - assert node[0] == 'expr', "expecting mkfunc default node to be an expr" 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]