More 3.6 CALL_FUNCTION argument parsing

This commit is contained in:
rocky
2018-04-01 11:26:46 -04:00
parent 120412f5a8
commit 254d0519bb
3 changed files with 25 additions and 39 deletions

View File

@@ -1,37 +1,18 @@
# From 3.6.4 pickletools.py # From 3.6.4 test_argparse.py
# Bug in 3.6 CALL_FUNCTION_KW in an not exponentially # Bug was in parsing ** args
import argparse import argparse
parser = argparse.ArgumentParser( def test_namespace_starkwargs_notidentifier(self):
description='disassemble one or more pickle files') ns = argparse.Namespace(**{'"': 'quote'})
parser.add_argument( string = """Namespace(**{'"': 'quote'})"""
'pickle_file', type=argparse.FileType('br'), assert ns == string
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()
assert args.annotate == False def test_namespace_kwargs_and_starkwargs_notidentifier(self):
assert args.indentlevel == 4 ns = argparse.Namespace(a=1, **{'"': 'quote'})
assert args.memo == False string = """Namespace(a=1, **{'"': 'quote'})"""
assert args.pickle_file == [] assert ns == string
assert args.preamble == '==> {name} <=='
assert args.test == False
assert args.v == False def test_namespace(self):
ns = argparse.Namespace(foo=42, bar='spam')
string = "Namespace(bar='spam', foo=42)"
assert ns == string

View File

@@ -408,9 +408,13 @@ def customize_for_version(self, is_pypy, version):
# Value 100 is important; it is exactly # Value 100 is important; it is exactly
# module/function precidence. # module/function precidence.
PRECEDENCE['call_kw'] = 100 PRECEDENCE['call_kw'] = 100
PRECEDENCE['call_kw36'] = 100 PRECEDENCE['call_kw36'] = 100
PRECEDENCE['call_ex'] = 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({ TABLE_DIRECT.update({
'tryfinally36': ( '%|try:\n%+%c%-%|finally:\n%+%c%-\n\n', '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' assert call_function_ex == 'CALL_FUNCTION_EX_KW'
# FIXME: decide if the below test be on kwargs == 'dict' # FIXME: decide if the below test be on kwargs == 'dict'
if (call_function_ex.attr & 1 and 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) self.call36_dict(kwargs)
else: else:
self.write('**') self.write('**')