3.6 argument parsing

This commit is contained in:
rocky
2018-03-31 23:07:06 -04:00
parent 535df1592e
commit b54be24e14
4 changed files with 60 additions and 21 deletions

Binary file not shown.

View File

@@ -0,0 +1,37 @@
# From 3.6.4 pickletools.py
# Bug in 3.6 CALL_FUNCTION_KW in an not exponentially
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()
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

View File

@@ -205,11 +205,9 @@ class Python36Parser(Python35Parser):
self.add_unique_rule('expr ::= async_call', token.kind, uniq_param, customize) self.add_unique_rule('expr ::= async_call', token.kind, uniq_param, customize)
if opname.startswith('CALL_FUNCTION_KW'): if opname.startswith('CALL_FUNCTION_KW'):
self.addRule("expr ::= call_kw", nop_func) self.addRule("expr ::= call_kw36", nop_func)
values = 'expr ' * token.attr values = 'expr ' * token.attr
rule = 'call_kw ::= expr kwargs_36 {token.kind}'.format(**locals()) rule = "call_kw36 ::= expr {values} LOAD_CONST {opname}".format(**locals())
self.addRule(rule, nop_func)
rule = 'kwargs_36 ::= {values} LOAD_CONST'.format(**locals())
self.add_unique_rule(rule, token.kind, token.attr, customize) self.add_unique_rule(rule, token.kind, token.attr, customize)
elif opname == 'CALL_FUNCTION_EX_KW': elif opname == 'CALL_FUNCTION_EX_KW':
self.addRule("""expr ::= call_ex_kw self.addRule("""expr ::= call_ex_kw

View File

@@ -407,8 +407,9 @@ 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_ex'] = 100 PRECEDENCE['call_kw36'] = 100
PRECEDENCE['call_ex'] = 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',
@@ -731,40 +732,43 @@ def customize_for_version(self, is_pypy, version):
# return # return
# self.n_kwargs_only_36 = kwargs_only_36 # self.n_kwargs_only_36 = kwargs_only_36
def kwargs_36(node): def n_call_kw36(node):
self.write('(') self.template_engine(("%c(", 0), node)
keys = node[-1].attr keys = node[-2].attr
num_kwargs = len(keys) num_kwargs = len(keys)
num_posargs = len(node) - (num_kwargs + 1) num_posargs = len(node) - (num_kwargs + 2)
n = len(node) n = len(node)
assert n >= len(keys)+1, \ assert n >= len(keys)+1, \
'not enough parameters keyword-tuple values' 'not enough parameters keyword-tuple values'
# try:
# assert n >= len(keys)+1, \
# 'not enough parameters keyword-tuple values'
# except:
# from trepan.api import debug; debug()
sep = '' sep = ''
# FIXME: adjust output for line breaks?
for i in range(num_posargs): line_number = self.line_number
for i in range(1, num_posargs):
self.write(sep) self.write(sep)
self.preorder(node[i]) self.preorder(node[i])
sep = ', ' if line_number != self.line_number:
sep = ",\n" + self.indent + " "
else:
sep = ", "
line_number = self.line_number
i = num_posargs i = num_posargs
j = 0 j = 0
# FIXME: adjust output for line breaks? # FIXME: adjust output for line breaks?
while i < n-1: while i < n-2:
self.write(sep) self.write(sep)
self.write(keys[j] + '=') self.write(keys[j] + '=')
self.preorder(node[i]) self.preorder(node[i])
sep=', ' if line_number != self.line_number:
sep = ",\n" + self.indent + " "
else:
sep = ", "
i += 1 i += 1
j += 1 j += 1
self.write(')') self.write(')')
self.prune() self.prune()
return return
self.n_kwargs_36 = kwargs_36 self.n_call_kw36 = n_call_kw36
def starred(node): def starred(node):
l = len(node) l = len(node)