Skip to content

Commit a2e932b

Browse files
committed
kmod's comments; fix up error messages
1 parent e7f77b3 commit a2e932b

File tree

2 files changed

+66
-16
lines changed

2 files changed

+66
-16
lines changed

src/runtime/rearrange_arguments.cpp

+47-16
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,26 @@ static inline void fillArgsFromStarArg(Box** args_out, Box* given_varargs, ArgPa
9494
}
9595
}
9696

97-
if (i < numParams || (i > numParams && !takesStarParam)) {
98-
if (takesStarParam) {
99-
raiseExcHelper(TypeError, takesStarParam ? "%s() takes at least %d argument%s (%d given)"
100-
: "%s() takes exactly %d argument%s (%d given)",
101-
fname, paramspec.num_args, paramspec.num_args == 1 ? "" : "s", argspec.num_args + i);
97+
assert(!paramspec.num_defaults);
98+
// Because there are no defaults, we don't need to do the 'at most' error message.
99+
// Right now i is the number of args (not eaten by the star param, if applicable)
100+
if (takesStarParam) {
101+
// It takes star params, so it takes at least this many arguments.
102+
// If we found less than that, then error.
103+
if (i < numParams) {
104+
raiseExcHelper(TypeError, "%s() takes at least %d argument%s (%d given)", fname, paramspec.num_args,
105+
paramspec.num_args == 1 ? "" : "s", argspec.num_args + i);
106+
}
107+
} else {
108+
// It doesn't take star params, so we needed to have found exactly numParams
109+
// arguments. If we found any other number, then error.
110+
if (i != numParams) {
111+
if (paramspec.num_args == 0) {
112+
raiseExcHelper(TypeError, "%s() takes no arguments (%d given)", fname, argspec.num_args + i);
113+
} else {
114+
raiseExcHelper(TypeError, "%s() takes exactly %d argument%s (%d given)", fname, paramspec.num_args,
115+
paramspec.num_args == 1 ? "" : "s", argspec.num_args + i);
116+
}
102117
}
103118
}
104119

@@ -128,7 +143,8 @@ extern "C" BoxedTuple* makeVarArgsFromArgsAndStarArgs(Box* arg1, Box* arg2, Box*
128143
assert(argspec.has_starargs);
129144
assert(paramspec.takes_varargs);
130145

131-
llvm::SmallVector<Box*, 8> starParamElts;
146+
// TODO use PyTuple_Resize
147+
std::vector<Box*, StlCompatAllocator<Box*>> starParamElts;
132148

133149
for (int i = paramspec.num_args; i < argspec.num_args; i++) {
134150
starParamElts.push_back(getArg(i, arg1, arg2, arg3, args));
@@ -258,8 +274,15 @@ void rearrangeArguments(ParamReceiveSpec paramspec, const ParamNames* param_name
258274
Box* ovarargs = BoxedTuple::create(unused_positional.size(), &unused_positional[0]);
259275
getArg(varargs_idx, oarg1, oarg2, oarg3, oargs) = ovarargs;
260276
} else if (unused_positional.size()) {
261-
raiseExcHelper(TypeError, "%s() takes at most %d argument%s (%d given)", func_name, paramspec.num_args,
262-
(paramspec.num_args == 1 ? "" : "s"), argspec.num_args + argspec.num_keywords + varargs.size());
277+
if (paramspec.num_args == 0) {
278+
raiseExcHelper(TypeError, "%s() takes no argument%s (%d given)", func_name,
279+
(paramspec.num_args == 1 ? "" : "s"),
280+
argspec.num_args + argspec.num_keywords + varargs.size());
281+
} else {
282+
raiseExcHelper(TypeError, "%s() takes at most %d argument%s (%d given)", func_name, paramspec.num_args,
283+
(paramspec.num_args == 1 ? "" : "s"),
284+
argspec.num_args + argspec.num_keywords + varargs.size());
285+
}
263286
}
264287

265288
////
@@ -331,10 +354,15 @@ void rearrangeArguments(ParamReceiveSpec paramspec, const ParamNames* param_name
331354
// Fill with defaults:
332355

333356
for (int i = 0; i < paramspec.num_args - paramspec.num_defaults; i++) {
334-
if (params_filled[i])
335-
continue;
336-
// TODO not right error message
337-
raiseExcHelper(TypeError, "%s() did not get a value for positional argument %d", func_name, i);
357+
if (!params_filled[i]) {
358+
// TODO not right error message
359+
if (paramspec.num_defaults || paramspec.takes_varargs)
360+
raiseExcHelper(TypeError, "%s() takes at least %d arguments (%d given)", func_name,
361+
paramspec.num_args - paramspec.num_defaults, argspec.num_args + varargs.size());
362+
else
363+
raiseExcHelper(TypeError, "%s() takes exactly %d arguments (%d given)", func_name,
364+
paramspec.num_args - paramspec.num_defaults, argspec.num_args + varargs.size());
365+
}
338366
}
339367

340368
for (int arg_idx = paramspec.num_args - paramspec.num_defaults; arg_idx < paramspec.num_args; arg_idx++) {
@@ -367,6 +395,8 @@ void rearrangeArguments(ParamReceiveSpec paramspec, const ParamNames* param_name
367395
if (argspec.has_starargs && !paramspec.num_defaults) {
368396
assert(!argspec.has_kwargs);
369397
assert(!argspec.num_keywords);
398+
assert(!paramspec.num_defaults);
399+
370400
// We just dispatch to a helper function to copy the args and call pyElements
371401
// TODO In some cases we can be smarter depending on the arrangement of args and type
372402
// of the star args object. For example if star args is an (immutable) tuple,
@@ -375,10 +405,11 @@ void rearrangeArguments(ParamReceiveSpec paramspec, const ParamNames* param_name
375405
assert(paramspec.takes_varargs);
376406

377407
RewriterVar::SmallVector callargs;
378-
callargs.push_back(rewrite_args->arg1 ? rewrite_args->arg1 : rewrite_args->rewriter->loadConst(0));
379-
callargs.push_back(rewrite_args->arg2 ? rewrite_args->arg2 : rewrite_args->rewriter->loadConst(0));
380-
callargs.push_back(rewrite_args->arg3 ? rewrite_args->arg3 : rewrite_args->rewriter->loadConst(0));
381-
callargs.push_back(rewrite_args->args ? rewrite_args->args : rewrite_args->rewriter->loadConst(0));
408+
// TODO no need to actually load the constant 0 since makeVarArgsAndStarArgs won't look at them
409+
callargs.push_back(num_passed_args >= 1 ? rewrite_args->arg1 : rewrite_args->rewriter->loadConst(0));
410+
callargs.push_back(num_passed_args >= 2 ? rewrite_args->arg2 : rewrite_args->rewriter->loadConst(0));
411+
callargs.push_back(num_passed_args >= 3 ? rewrite_args->arg3 : rewrite_args->rewriter->loadConst(0));
412+
callargs.push_back(num_passed_args >= 4 ? rewrite_args->args : rewrite_args->rewriter->loadConst(0));
382413
callargs.push_back(rewrite_args->rewriter->loadConst(argspec.asInt()));
383414
callargs.push_back(rewrite_args->rewriter->loadConst(paramspec.asInt()));
384415
RewriterVar* r_varargs = rewrite_args->rewriter->call(true /* has side effects */,

test/tests/starargs_ics2.py

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
3+
try:
4+
def f():
5+
pass
6+
7+
for i in [0, 10]:
8+
f(*range(i))
9+
except Exception as e:
10+
print e.message
11+
12+
try:
13+
def f(a, b, c, d):
14+
pass
15+
16+
for i in [4, 3]:
17+
f(*range(i))
18+
except Exception as e:
19+
print e.message

0 commit comments

Comments
 (0)