diff --git a/test/bytecode_3.6_run/10_argparse.pyc b/test/bytecode_3.6_run/10_argparse.pyc index 891345a8..78be71d8 100644 Binary files a/test/bytecode_3.6_run/10_argparse.pyc and b/test/bytecode_3.6_run/10_argparse.pyc differ diff --git a/test/simple_source/bug36/10_argparse.py b/test/simple_source/bug36/10_argparse.py index 14685606..966bdfcf 100644 --- a/test/simple_source/bug36/10_argparse.py +++ b/test/simple_source/bug36/10_argparse.py @@ -1,37 +1,18 @@ -# From 3.6.4 pickletools.py -# Bug in 3.6 CALL_FUNCTION_KW in an not exponentially - +# From 3.6.4 test_argparse.py +# Bug was in parsing ** args import argparse -parser = argparse.ArgumentParser( - description='disassemble one or more pickle files') -parser.add_argument( - 'pickle_file', type=argparse.FileType('br'), - nargs='*', help='the pickle file') -parser.add_argument( - '-m', '--memo', action='store_true', - help='preserve memo between disassemblies') -parser.add_argument( - '-l', '--indentlevel', default=4, type=int, - help='the number of blanks by which to indent a new MARK level') -parser.add_argument( - '-a', '--annotate', action='store_true', - help='annotate each line with a short opcode description') -parser.add_argument( - '-p', '--preamble', default="==> {name} <==", - help='if more than one pickle file is specified, print this before' - ' each disassembly') -parser.add_argument( - '-t', '--test', action='store_true', - help='run self-test suite') -parser.add_argument( - '-v', action='store_true', - help='run verbosely; only affects self-test run') -args = parser.parse_args() +def test_namespace_starkwargs_notidentifier(self): + ns = argparse.Namespace(**{'"': 'quote'}) + string = """Namespace(**{'"': 'quote'})""" + assert ns == string -assert args.annotate == False -assert args.indentlevel == 4 -assert args.memo == False -assert args.pickle_file == [] -assert args.preamble == '==> {name} <==' -assert args.test == False -assert args.v == False +def test_namespace_kwargs_and_starkwargs_notidentifier(self): + ns = argparse.Namespace(a=1, **{'"': 'quote'}) + string = """Namespace(a=1, **{'"': 'quote'})""" + assert ns == string + + +def test_namespace(self): + ns = argparse.Namespace(foo=42, bar='spam') + string = "Namespace(bar='spam', foo=42)" + assert ns == string diff --git a/uncompyle6/semantics/customize.py b/uncompyle6/semantics/customize.py index 2d987f17..88d431e2 100644 --- a/uncompyle6/semantics/customize.py +++ b/uncompyle6/semantics/customize.py @@ -408,9 +408,13 @@ def customize_for_version(self, is_pypy, version): # Value 100 is important; it is exactly # module/function precidence. - PRECEDENCE['call_kw'] = 100 - PRECEDENCE['call_kw36'] = 100 - PRECEDENCE['call_ex'] = 100 + PRECEDENCE['call_kw'] = 100 + PRECEDENCE['call_kw36'] = 100 + PRECEDENCE['call_ex'] = 100 + PRECEDENCE['call_ex_kw'] = 100 + PRECEDENCE['call_ex_kw2'] = 100 + PRECEDENCE['call_ex_kw3'] = 100 + PRECEDENCE['call_ex_kw4'] = 100 TABLE_DIRECT.update({ 'tryfinally36': ( '%|try:\n%+%c%-%|finally:\n%+%c%-\n\n', @@ -570,7 +574,8 @@ def customize_for_version(self, is_pypy, version): assert call_function_ex == 'CALL_FUNCTION_EX_KW' # FIXME: decide if the below test be on kwargs == 'dict' if (call_function_ex.attr & 1 and - (not isinstance(kwargs, Token) and kwargs != 'attribute')): + (not isinstance(kwargs, Token) and kwargs != 'attribute') + and not kwargs[0].kind.startswith('kvlist')): self.call36_dict(kwargs) else: self.write('**')