mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 01:48:00 +00:00
testcrypt.py: use parameter names in diagnostics.
Making a virtue of the necessity of adding parameter names to testcrypt.h a couple of commits ago, we can now use those names to improve diagnostics, so that if you use the wrong type in a Python function call the error message will tell you the name as well as the index of the offending argument. Also, the repr() text for the function itself will now print a full prototype (albeit in a nasty hybrid of C, Python and testcrypt.h syntax) which shows all the parameter names. That should be handy when trying to remember the order of arguments at the REPL prompt.
This commit is contained in:
parent
3153f3ef39
commit
aaaf11d7fb
@ -149,7 +149,7 @@ def marshal_string(val):
|
|||||||
else "%{:02x}".format(b)
|
else "%{:02x}".format(b)
|
||||||
for b in val)
|
for b in val)
|
||||||
|
|
||||||
def make_argword(arg, argtype, fnname, argindex, to_preserve):
|
def make_argword(arg, argtype, fnname, argindex, argname, to_preserve):
|
||||||
typename, consumed = argtype
|
typename, consumed = argtype
|
||||||
if typename.startswith("opt_"):
|
if typename.startswith("opt_"):
|
||||||
if arg is None:
|
if arg is None:
|
||||||
@ -166,8 +166,8 @@ def make_argword(arg, argtype, fnname, argindex, to_preserve):
|
|||||||
if isinstance(arg, Value):
|
if isinstance(arg, Value):
|
||||||
if arg._typename != typename:
|
if arg._typename != typename:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"{}() argument {:d} should be {} ({} given)".format(
|
"{}() argument #{:d} ({}) should be {} ({} given)".format(
|
||||||
fnname, argindex, typename, arg._typename))
|
fnname, argindex, argname, typename, arg._typename))
|
||||||
ident = arg._ident
|
ident = arg._ident
|
||||||
if consumed:
|
if consumed:
|
||||||
arg._consumed()
|
arg._consumed()
|
||||||
@ -185,14 +185,14 @@ def make_argword(arg, argtype, fnname, argindex, to_preserve):
|
|||||||
return arg
|
return arg
|
||||||
if typename == "mpint_list":
|
if typename == "mpint_list":
|
||||||
sublist = [make_argword(len(arg), ("uint", False),
|
sublist = [make_argword(len(arg), ("uint", False),
|
||||||
fnname, argindex, to_preserve)]
|
fnname, argindex, argname, to_preserve)]
|
||||||
for val in arg:
|
for val in arg:
|
||||||
sublist.append(make_argword(val, ("val_mpint", False),
|
sublist.append(make_argword(val, ("val_mpint", False),
|
||||||
fnname, argindex, to_preserve))
|
fnname, argindex, argname, to_preserve))
|
||||||
return b" ".join(coerce_to_bytes(sub) for sub in sublist)
|
return b" ".join(coerce_to_bytes(sub) for sub in sublist)
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"Can't convert {}() argument {:d} to {} (value was {!r})".format(
|
"Can't convert {}() argument #{:d} ({}) to {} (value was {!r})".format(
|
||||||
fnname, argindex, typename, arg))
|
fnname, argindex, argname, typename, arg))
|
||||||
|
|
||||||
def unpack_string(identifier):
|
def unpack_string(identifier):
|
||||||
retwords = childprocess.funcall("getstring", [identifier])
|
retwords = childprocess.funcall("getstring", [identifier])
|
||||||
@ -247,12 +247,20 @@ def make_retvals(rettypes, retwords, unpack_strings=True):
|
|||||||
for rettype, word in zip(rettypes, retwords)]
|
for rettype, word in zip(rettypes, retwords)]
|
||||||
|
|
||||||
class Function(object):
|
class Function(object):
|
||||||
def __init__(self, fnname, rettypes, argtypes):
|
def __init__(self, fnname, rettypes, retnames, argtypes, argnames):
|
||||||
self.fnname = fnname
|
self.fnname = fnname
|
||||||
self.rettypes = rettypes
|
self.rettypes = rettypes
|
||||||
|
self.retnames = retnames
|
||||||
self.argtypes = argtypes
|
self.argtypes = argtypes
|
||||||
|
self.argnames = argnames
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Function {}>".format(self.fnname)
|
return "<Function {}({}) -> ({})>".format(
|
||||||
|
self.fnname,
|
||||||
|
", ".join(("consumed " if c else "")+t+" "+n
|
||||||
|
for (t,c),n in zip(self.argtypes, self.argnames)),
|
||||||
|
", ".join((t+" "+n if n is not None else t)
|
||||||
|
for t,n in zip(self.rettypes, self.retnames)),
|
||||||
|
)
|
||||||
def __call__(self, *args):
|
def __call__(self, *args):
|
||||||
if len(args) != len(self.argtypes):
|
if len(args) != len(self.argtypes):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
@ -261,7 +269,8 @@ class Function(object):
|
|||||||
to_preserve = []
|
to_preserve = []
|
||||||
retwords = childprocess.funcall(
|
retwords = childprocess.funcall(
|
||||||
self.fnname, [make_argword(args[i], self.argtypes[i],
|
self.fnname, [make_argword(args[i], self.argtypes[i],
|
||||||
self.fnname, i, to_preserve)
|
self.fnname, i, self.argnames[i],
|
||||||
|
to_preserve)
|
||||||
for i in range(len(args))])
|
for i in range(len(args))])
|
||||||
retvals = make_retvals(self.rettypes, retwords)
|
retvals = make_retvals(self.rettypes, retwords)
|
||||||
if len(retvals) == 0:
|
if len(retvals) == 0:
|
||||||
@ -380,14 +389,18 @@ def _setup(scope):
|
|||||||
tokens = _lex_testcrypt_header(header)
|
tokens = _lex_testcrypt_header(header)
|
||||||
for function, rettype, arglist in _parse_testcrypt_header(tokens):
|
for function, rettype, arglist in _parse_testcrypt_header(tokens):
|
||||||
rettypes = []
|
rettypes = []
|
||||||
|
retnames = []
|
||||||
if rettype != "void":
|
if rettype != "void":
|
||||||
rettypes.append(trim_argtype(rettype))
|
rettypes.append(trim_argtype(rettype))
|
||||||
|
retnames.append(None)
|
||||||
|
|
||||||
argtypes = []
|
argtypes = []
|
||||||
|
argnames = []
|
||||||
argsconsumed = []
|
argsconsumed = []
|
||||||
for arg, argname in arglist:
|
for arg, argname in arglist:
|
||||||
if arg.startswith(outprefix):
|
if arg.startswith(outprefix):
|
||||||
rettypes.append(trim_argtype(arg[len(outprefix):]))
|
rettypes.append(trim_argtype(arg[len(outprefix):]))
|
||||||
|
retnames.append(argname)
|
||||||
else:
|
else:
|
||||||
consumed = False
|
consumed = False
|
||||||
if arg.startswith(consprefix):
|
if arg.startswith(consprefix):
|
||||||
@ -395,7 +408,9 @@ def _setup(scope):
|
|||||||
consumed = True
|
consumed = True
|
||||||
arg = trim_argtype(arg)
|
arg = trim_argtype(arg)
|
||||||
argtypes.append((arg, consumed))
|
argtypes.append((arg, consumed))
|
||||||
func = Function(function, rettypes, argtypes)
|
argnames.append(argname)
|
||||||
|
func = Function(function, rettypes, retnames,
|
||||||
|
argtypes, argnames)
|
||||||
scope[function] = func
|
scope[function] = func
|
||||||
if len(argtypes) > 0:
|
if len(argtypes) > 0:
|
||||||
t = argtypes[0][0]
|
t = argtypes[0][0]
|
||||||
|
Loading…
Reference in New Issue
Block a user