@@ -540,8 +540,10 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
540540 levels [0 ] = 0 ;
541541 if (toplevel ) {
542542 PyOS_snprintf (msgbuf , bufsize ,
543- "expected %d arguments, not %" PY_FORMAT_SIZE_T "d" ,
544- n , len );
543+ "expected %d argument%s, not %" PY_FORMAT_SIZE_T "d" ,
544+ n ,
545+ n == 1 ? "" : "s" ,
546+ len );
545547 }
546548 else {
547549 PyOS_snprintf (msgbuf , bufsize ,
@@ -1718,12 +1720,14 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
17181720 }
17191721 else {
17201722 PyErr_Format (PyExc_TypeError ,
1721- "%.200s%s takes %s %d positional arguments "
1723+ "%.200s%s takes %s %d positional argument%s "
17221724 " (%d given)" ,
17231725 (fname == NULL ) ? "function" : fname ,
17241726 (fname == NULL ) ? "" : "()" ,
17251727 (min != INT_MAX ) ? "at most" : "exactly" ,
1726- max , nargs );
1728+ max ,
1729+ max == 1 ? "" : "s" ,
1730+ nargs );
17271731 }
17281732 return cleanreturn (0 , & freelist );
17291733 }
@@ -1797,12 +1801,14 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
17971801
17981802 if (skip ) {
17991803 PyErr_Format (PyExc_TypeError ,
1800- "%.200s%s takes %s %d positional arguments "
1804+ "%.200s%s takes %s %d positional argument%s "
18011805 " (%d given)" ,
18021806 (fname == NULL ) ? "function" : fname ,
18031807 (fname == NULL ) ? "" : "()" ,
18041808 (Py_MIN (pos , min ) < i ) ? "at least" : "exactly" ,
1805- Py_MIN (pos , min ), nargs );
1809+ Py_MIN (pos , min ),
1810+ Py_MIN (pos , min ) == 1 ? "" : "s" ,
1811+ nargs );
18061812 return cleanreturn (0 , & freelist );
18071813 }
18081814
@@ -2104,11 +2110,13 @@ vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs,
21042110 }
21052111 else {
21062112 PyErr_Format (PyExc_TypeError ,
2107- "%.200s%s takes %s %d positional arguments (%d given)" ,
2113+ "%.200s%s takes %s %d positional argument%s (%d given)" ,
21082114 (parser -> fname == NULL ) ? "function" : parser -> fname ,
21092115 (parser -> fname == NULL ) ? "" : "()" ,
21102116 (parser -> min != INT_MAX ) ? "at most" : "exactly" ,
2111- parser -> max , nargs );
2117+ parser -> max ,
2118+ parser -> max == 1 ? "" : "s" ,
2119+ nargs );
21122120 }
21132121 return cleanreturn (0 , & freelist );
21142122 }
@@ -2152,12 +2160,14 @@ vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs,
21522160 if (i < pos ) {
21532161 Py_ssize_t min = Py_MIN (pos , parser -> min );
21542162 PyErr_Format (PyExc_TypeError ,
2155- "%.200s%s takes %s %d positional arguments "
2163+ "%.200s%s takes %s %d positional argument%s "
21562164 " (%d given)" ,
21572165 (parser -> fname == NULL ) ? "function" : parser -> fname ,
21582166 (parser -> fname == NULL ) ? "" : "()" ,
21592167 min < parser -> max ? "at least" : "exactly" ,
2160- min , nargs );
2168+ min ,
2169+ min == 1 ? "" : "s" ,
2170+ nargs );
21612171 }
21622172 else {
21632173 keyword = PyTuple_GET_ITEM (kwtuple , i - pos );
@@ -2417,9 +2427,9 @@ unpack_stack(PyObject *const *args, Py_ssize_t nargs, const char *name,
24172427 else
24182428 PyErr_Format (
24192429 PyExc_TypeError ,
2420- "unpacked tuple should have %s%zd elements ,"
2430+ "unpacked tuple should have %s%zd element%s ,"
24212431 " but has %zd" ,
2422- (min == max ? "" : "at least " ), min , nargs );
2432+ (min == max ? "" : "at least " ), min , min == 1 ? "" : "s" , nargs );
24232433 return 0 ;
24242434 }
24252435
@@ -2436,9 +2446,9 @@ unpack_stack(PyObject *const *args, Py_ssize_t nargs, const char *name,
24362446 else
24372447 PyErr_Format (
24382448 PyExc_TypeError ,
2439- "unpacked tuple should have %s%zd elements ,"
2449+ "unpacked tuple should have %s%zd element%s ,"
24402450 " but has %zd" ,
2441- (min == max ? "" : "at most " ), max , nargs );
2451+ (min == max ? "" : "at most " ), max , max == 1 ? "" : "s" , nargs );
24422452 return 0 ;
24432453 }
24442454
0 commit comments