summaryrefslogtreecommitdiffstats
path: root/Lib/inspect.py
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2011-06-24 14:37:26 (GMT)
committerBenjamin Peterson <benjamin@python.org>2011-06-24 14:37:26 (GMT)
commite109c70860ceb4102a84c32d4bda4e5025eaf92a (patch)
tree1924a1728b34a81dd1dc3890230be4aae0c44f68 /Lib/inspect.py
parent947d6b044454eebef483f2e520aa57ea86053689 (diff)
downloadcpython-e109c70860ceb4102a84c32d4bda4e5025eaf92a.zip
cpython-e109c70860ceb4102a84c32d4bda4e5025eaf92a.tar.gz
cpython-e109c70860ceb4102a84c32d4bda4e5025eaf92a.tar.bz2
give the names of missing positional or keyword-only arguments (closes #12356)
Diffstat (limited to 'Lib/inspect.py')
-rw-r--r--Lib/inspect.py41
1 files changed, 29 insertions, 12 deletions
diff --git a/Lib/inspect.py b/Lib/inspect.py
index aa4c30f..80802e4 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -918,10 +918,24 @@ def formatargvalues(args, varargs, varkw, locals,
specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
return '(' + ', '.join(specs) + ')'
-def _positional_error(f_name, args, kwonly, varargs, defcount, given, values):
+def _missing_arguments(f_name, argnames, pos, values):
+ names = [repr(name) for name in argnames if name not in values]
+ missing = len(names)
+ if missing == 1:
+ s = names[0]
+ elif missing == 2:
+ s = "{} and {}".format(*names)
+ else:
+ tail = ", {} and {}".format(names[-2:])
+ del names[-2:]
+ s = ", ".join(names) + tail
+ raise TypeError("%s() missing %i required %s argument%s: %s" %
+ (f_name, missing,
+ "positional" if pos else "keyword-only",
+ "" if missing == 1 else "s", s))
+
+def _too_many(f_name, args, kwonly, varargs, defcount, given, values):
atleast = len(args) - defcount
- if given is None:
- given = len([arg for arg in args if arg in values])
kwonly_given = len([arg for arg in kwonly if arg in values])
if varargs:
plural = atleast != 1
@@ -980,22 +994,25 @@ def getcallargs(func, *positional, **named):
(f_name, kw))
arg2value[kw] = value
if num_pos > num_args and not varargs:
- _positional_error(f_name, args, kwonlyargs, varargs, num_defaults,
- num_pos, arg2value)
+ _too_many(f_name, args, kwonlyargs, varargs, num_defaults,
+ num_pos, arg2value)
if num_pos < num_args:
- for arg in args[:num_args - num_defaults]:
+ req = args[:num_args - num_defaults]
+ for arg in req:
if arg not in arg2value:
- _positional_error(f_name, args, kwonlyargs, varargs,
- num_defaults, None, arg2value)
+ _missing_arguments(f_name, req, True, arg2value)
for i, arg in enumerate(args[num_args - num_defaults:]):
if arg not in arg2value:
arg2value[arg] = defaults[i]
+ missing = 0
for kwarg in kwonlyargs:
if kwarg not in arg2value:
- if kwarg not in kwonlydefaults:
- raise TypeError("%s() requires keyword-only argument %r" %
- (f_name, kwarg))
- arg2value[kwarg] = kwonlydefaults[kwarg]
+ if kwarg in kwonlydefaults:
+ arg2value[kwarg] = kwonlydefaults[kwarg]
+ else:
+ missing += 1
+ if missing:
+ _missing_arguments(f_name, kwonlyargs, False, arg2value)
return arg2value
# -------------------------------------------------- stack frame extraction