List of commits:
Subject Hash Author Date (UTC)
bpo-29951: Include function name for some error messages in `PyArg_ParseTuple*` (#916) 64c8f705c0121a4b45ca2c3bc7b47b282e9efcd8 Michael Seifert 2017-04-09 07:47:12
Remove invalid comment in urllib.request. (#1054) a2a9ddd923a849124bdd1c484f70f02df6fde0e9 Senthil Kumaran 2017-04-09 06:27:25
Improvements to typing documentation (#967) 45d22c256bce3afcf57f49032a6b20fdec4f26ad Jelle Zijlstra 2017-04-08 16:09:14
bpo-29998: Pickling and copying ImportError now preserves name and path (#1010) b785396ab451b0c9d6ae9ee5a9e56c810209a6cb Serhiy Storchaka 2017-04-08 06:55:07
Expand the PySlice_GetIndicesEx macro. (#1023) b879fe82e7e5c3f7673c9a7fa4aad42bd05445d8 Serhiy Storchaka 2017-04-08 06:53:51
bpo-29914: Fix default implementations of __reduce__ and __reduce_ex__(). (#843) 205e00c5cfd495a4dc6dae8e8fa0fb828fb3dca9 Serhiy Storchaka 2017-04-08 06:52:59
Fix a minor typo. (#1032) dd9a0a14c89d57e43898d4b866b8c161e4ff8506 Barry Warsaw 2017-04-07 18:18:14
bpo-29958: Minor improvements to zipfile and tarfile CLI. (#944) 150cd1916a59e750ce88c65325de9ef0c42c6cb5 Serhiy Storchaka 2017-04-07 15:56:12
Remove Invalid comment in test_urllib2.py (#1020) fd0cd07a5a3c964c084f4efc5bbcb89dd2193ee6 Senthil Kumaran 2017-04-07 07:19:08
bpo-28837: Fix lib2to3 handling of map/zip/filter calls when followed with a 'trailer', e.g. zip()[x] (#24) 93b4b47e3a720171d67f3b608de406aef462835c Stuart Berg 2017-04-06 05:19:40
Correct typo in configparser.rst (#1012) 01fa9ae5460b00bf1ced500c797176ebd3fb060d Alex Jordan 2017-04-06 02:21:30
bpo-29962: add math.remainder (#950) a0ce375e10b50f7606cb86b072fed7d8cd574fe7 Mark Dickinson 2017-04-05 17:34:27
Miscellaneous minor fixes of Misc/NEWS formatting. (#1002) a0157b5f11e621f2196af4e918b9f07688a6cd1c Serhiy Storchaka 2017-04-05 09:07:22
Update Argument Clinic generated code for bpo-29878. (#1001) bae6881b4215b2613ad08ef0dc7bed7743c2b8cc Serhiy Storchaka 2017-04-05 09:00:42
bpo-29762: More use "raise from None". (#569) 5affd23e6f42125998724787025080a24839266e Serhiy Storchaka 2017-04-05 06:37:24
bpo-29549: Fixes docstring for str.index (#256) 43ba8861e0ad044efafa46a7cc04e12ac5df640e Lisa Roach 2017-04-05 05:36:22
correct parse_qs and parse_qsl test case descriptions. (#968) 257b980b316a5206ecf6c23b958e2b7c4df4f3de Senthil Kumaran 2017-04-05 04:19:43
bpo-29649: Improve struct.pack_into() boundary error messages (#424) f78b119364b521307237a1484ba5f43f42300898 Andrew Nester 2017-04-04 10:46:25
bpo-29972: Skip tests known to fail on AIX (#979) 5de85a17029356084b96db63e04d9eb150efd9c0 Victor Stinner 2017-04-04 08:35:15
bpo-29725: DOC: add text for arraysize in sqlite3.Cursor (#947) 02e12138000da834f23719521a011fa93763384d csabella 2017-04-04 05:16:14
Commit 64c8f705c0121a4b45ca2c3bc7b47b282e9efcd8 - bpo-29951: Include function name for some error messages in `PyArg_ParseTuple*` (#916)
Also changed format specifier for function name from "%s" to "%.200s"
and exception messages should start with lowercase letter.
Author: Michael Seifert
Author date (UTC): 2017-04-09 07:47
Committer name: Serhiy Storchaka
Committer date (UTC): 2017-04-09 07:47
Parent(s): a2a9ddd923a849124bdd1c484f70f02df6fde0e9
Signer:
Signing key:
Signing status: N
Tree: 5f58baf5aa8ab19a167688c1710016291f5758ca
File Lines added Lines deleted
Lib/test/test_capi.py 4 4
Lib/test/test_exceptions.py 1 1
Lib/test/test_getargs2.py 7 6
Python/getargs.c 42 22
File Lib/test/test_capi.py changed (mode: 100644) (index 2a53f3d081..6e14248a12)
... ... class SkipitemTest(unittest.TestCase):
533 533 parse((1, 2, 3), {}, b'OOO', ['', '', 'a']) parse((1, 2, 3), {}, b'OOO', ['', '', 'a'])
534 534 parse((1, 2), {'a': 3}, b'OOO', ['', '', 'a']) parse((1, 2), {'a': 3}, b'OOO', ['', '', 'a'])
535 535 with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(TypeError,
536 r'Function takes at least 2 positional arguments \(1 given\)'):
536 r'function takes at least 2 positional arguments \(1 given\)'):
537 537 parse((1,), {'a': 3}, b'OOO', ['', '', 'a']) parse((1,), {'a': 3}, b'OOO', ['', '', 'a'])
538 538 parse((1,), {}, b'O|OO', ['', '', 'a']) parse((1,), {}, b'O|OO', ['', '', 'a'])
539 539 with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(TypeError,
540 r'Function takes at least 1 positional arguments \(0 given\)'):
540 r'function takes at least 1 positional arguments \(0 given\)'):
541 541 parse((), {}, b'O|OO', ['', '', 'a']) parse((), {}, b'O|OO', ['', '', 'a'])
542 542 parse((1, 2), {'a': 3}, b'OO$O', ['', '', 'a']) parse((1, 2), {'a': 3}, b'OO$O', ['', '', 'a'])
543 543 with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(TypeError,
544 r'Function takes exactly 2 positional arguments \(1 given\)'):
544 r'function takes exactly 2 positional arguments \(1 given\)'):
545 545 parse((1,), {'a': 3}, b'OO$O', ['', '', 'a']) parse((1,), {'a': 3}, b'OO$O', ['', '', 'a'])
546 546 parse((1,), {}, b'O|O$O', ['', '', 'a']) parse((1,), {}, b'O|O$O', ['', '', 'a'])
547 547 with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(TypeError,
548 r'Function takes at least 1 positional arguments \(0 given\)'):
548 r'function takes at least 1 positional arguments \(0 given\)'):
549 549 parse((), {}, b'O|O$O', ['', '', 'a']) parse((), {}, b'O|O$O', ['', '', 'a'])
550 550 with self.assertRaisesRegex(SystemError, r'Empty parameter name after \$'): with self.assertRaisesRegex(SystemError, r'Empty parameter name after \$'):
551 551 parse((1,), {}, b'O|$OO', ['', '', 'a']) parse((1,), {}, b'O|$OO', ['', '', 'a'])
File Lib/test/test_exceptions.py changed (mode: 100644) (index e6fa34610d..3378ceb701)
... ... class ImportErrorTests(unittest.TestCase):
1090 1090 self.assertEqual(exc.name, 'somename') self.assertEqual(exc.name, 'somename')
1091 1091 self.assertEqual(exc.path, 'somepath') self.assertEqual(exc.path, 'somepath')
1092 1092
1093 msg = "'invalid' is an invalid keyword argument for this function"
1093 msg = "'invalid' is an invalid keyword argument for ImportError"
1094 1094 with self.assertRaisesRegex(TypeError, msg): with self.assertRaisesRegex(TypeError, msg):
1095 1095 ImportError('test', invalid='keyword') ImportError('test', invalid='keyword')
1096 1096
File Lib/test/test_getargs2.py changed (mode: 100644) (index e5d9aa64ee..86df3a4750)
... ... class Keywords_TestCase(unittest.TestCase):
553 553 try: try:
554 554 getargs_keywords(arg1=(1,2)) getargs_keywords(arg1=(1,2))
555 555 except TypeError as err: except TypeError as err:
556 self.assertEqual(str(err), "Required argument 'arg2' (pos 2) not found")
556 self.assertEqual(
557 str(err), "function missing required argument 'arg2' (pos 2)")
557 558 else: else:
558 559 self.fail('TypeError should have been raised') self.fail('TypeError should have been raised')
559 560
 
... ... class KeywordOnly_TestCase(unittest.TestCase):
626 627 ) )
627 628 # required arg missing # required arg missing
628 629 with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(TypeError,
629 r"Required argument 'required' \(pos 1\) not found"):
630 r"function missing required argument 'required' \(pos 1\)"):
630 631 getargs_keyword_only(optional=2) getargs_keyword_only(optional=2)
631 632
632 633 with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(TypeError,
633 r"Required argument 'required' \(pos 1\) not found"):
634 r"function missing required argument 'required' \(pos 1\)"):
634 635 getargs_keyword_only(keyword_only=3) getargs_keyword_only(keyword_only=3)
635 636
636 637 def test_too_many_args(self): def test_too_many_args(self):
637 638 with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(TypeError,
638 r"Function takes at most 2 positional arguments \(3 given\)"):
639 r"function takes at most 2 positional arguments \(3 given\)"):
639 640 getargs_keyword_only(1, 2, 3) getargs_keyword_only(1, 2, 3)
640 641
641 642 with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(TypeError,
 
... ... class PositionalOnlyAndKeywords_TestCase(unittest.TestCase):
674 675 self.assertEqual(self.getargs(1), (1, -1, -1)) self.assertEqual(self.getargs(1), (1, -1, -1))
675 676 # required positional arg missing # required positional arg missing
676 677 with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(TypeError,
677 r"Function takes at least 1 positional arguments \(0 given\)"):
678 r"function takes at least 1 positional arguments \(0 given\)"):
678 679 self.getargs() self.getargs()
679 680
680 681 with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(TypeError,
681 r"Function takes at least 1 positional arguments \(0 given\)"):
682 r"function takes at least 1 positional arguments \(0 given\)"):
682 683 self.getargs(keyword=3) self.getargs(keyword=3)
683 684
684 685 def test_empty_keyword(self): def test_empty_keyword(self):
File Python/getargs.c changed (mode: 100644) (index 8cb672d6ab..58c9a998ff)
... ... PyArg_ValidateKeywordArguments(PyObject *kwargs)
1584 1584 } }
1585 1585 if (!_PyDict_HasOnlyStringKeys(kwargs)) { if (!_PyDict_HasOnlyStringKeys(kwargs)) {
1586 1586 PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
1587 "keyword arguments must be strings");
1587 "keywords must be strings");
1588 1588 return 0; return 0;
1589 1589 } }
1590 1590 return 1; return 1;
 
... ... vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
1655 1655 nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs); nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs);
1656 1656 if (nargs + nkwargs > len) { if (nargs + nkwargs > len) {
1657 1657 PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
1658 "%s%s takes at most %d argument%s (%zd given)",
1658 "%.200s%s takes at most %d argument%s (%zd given)",
1659 1659 (fname == NULL) ? "function" : fname, (fname == NULL) ? "function" : fname,
1660 1660 (fname == NULL) ? "" : "()", (fname == NULL) ? "" : "()",
1661 1661 len, len,
 
... ... vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
1705 1705 } }
1706 1706 if (max < nargs) { if (max < nargs) {
1707 1707 PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
1708 "Function takes %s %d positional arguments"
1708 "%.200s%s takes %s %d positional arguments"
1709 1709 " (%d given)", " (%d given)",
1710 (fname == NULL) ? "function" : fname,
1711 (fname == NULL) ? "" : "()",
1710 1712 (min != INT_MAX) ? "at most" : "exactly", (min != INT_MAX) ? "at most" : "exactly",
1711 1713 max, nargs); max, nargs);
1712 1714 return cleanreturn(0, &freelist); return cleanreturn(0, &freelist);
 
... ... vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
1752 1754 * or the end of the format. */ * or the end of the format. */
1753 1755 } }
1754 1756 else { else {
1755 PyErr_Format(PyExc_TypeError, "Required argument "
1756 "'%s' (pos %d) not found",
1757 PyErr_Format(PyExc_TypeError, "%.200s%s missing required "
1758 "argument '%s' (pos %d)",
1759 (fname == NULL) ? "function" : fname,
1760 (fname == NULL) ? "" : "()",
1757 1761 kwlist[i], i+1); kwlist[i], i+1);
1758 1762 return cleanreturn(0, &freelist); return cleanreturn(0, &freelist);
1759 1763 } }
 
... ... vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
1779 1783
1780 1784 if (skip) { if (skip) {
1781 1785 PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
1782 "Function takes %s %d positional arguments"
1786 "%.200s%s takes %s %d positional arguments"
1783 1787 " (%d given)", " (%d given)",
1788 (fname == NULL) ? "function" : fname,
1789 (fname == NULL) ? "" : "()",
1784 1790 (Py_MIN(pos, min) < i) ? "at least" : "exactly", (Py_MIN(pos, min) < i) ? "at least" : "exactly",
1785 1791 Py_MIN(pos, min), nargs); Py_MIN(pos, min), nargs);
1786 1792 return cleanreturn(0, &freelist); return cleanreturn(0, &freelist);
 
... ... vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
1802 1808 if (current_arg) { if (current_arg) {
1803 1809 /* arg present in tuple and in dict */ /* arg present in tuple and in dict */
1804 1810 PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
1805 "Argument given by name ('%s') "
1811 "argument for %.200s%s given by name ('%s') "
1806 1812 "and position (%d)", "and position (%d)",
1813 (fname == NULL) ? "function" : fname,
1814 (fname == NULL) ? "" : "()",
1807 1815 kwlist[i], i+1); kwlist[i], i+1);
1808 1816 return cleanreturn(0, &freelist); return cleanreturn(0, &freelist);
1809 1817 } }
 
... ... vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
1826 1834 if (!match) { if (!match) {
1827 1835 PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
1828 1836 "'%U' is an invalid keyword " "'%U' is an invalid keyword "
1829 "argument for this function",
1830 key);
1837 "argument for %.200s%s",
1838 key,
1839 (fname == NULL) ? "this function" : fname,
1840 (fname == NULL) ? "" : "()");
1831 1841 return cleanreturn(0, &freelist); return cleanreturn(0, &freelist);
1832 1842 } }
1833 1843 } }
 
... ... vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs,
2060 2070 } }
2061 2071 if (nargs + nkwargs > len) { if (nargs + nkwargs > len) {
2062 2072 PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
2063 "%s%s takes at most %d argument%s (%zd given)",
2073 "%.200s%s takes at most %d argument%s (%zd given)",
2064 2074 (parser->fname == NULL) ? "function" : parser->fname, (parser->fname == NULL) ? "function" : parser->fname,
2065 2075 (parser->fname == NULL) ? "" : "()", (parser->fname == NULL) ? "" : "()",
2066 2076 len, len,
 
... ... vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs,
2070 2080 } }
2071 2081 if (parser->max < nargs) { if (parser->max < nargs) {
2072 2082 PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
2073 "Function takes %s %d positional arguments (%d given)",
2083 "%200s%s takes %s %d positional arguments (%d given)",
2084 (parser->fname == NULL) ? "function" : parser->fname,
2085 (parser->fname == NULL) ? "" : "()",
2074 2086 (parser->min != INT_MAX) ? "at most" : "exactly", (parser->min != INT_MAX) ? "at most" : "exactly",
2075 2087 parser->max, nargs); parser->max, nargs);
2076 2088 return cleanreturn(0, &freelist); return cleanreturn(0, &freelist);
 
... ... vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs,
2115 2127 if (i < pos) { if (i < pos) {
2116 2128 Py_ssize_t min = Py_MIN(pos, parser->min); Py_ssize_t min = Py_MIN(pos, parser->min);
2117 2129 PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
2118 "Function takes %s %d positional arguments"
2130 "%.200s%s takes %s %d positional arguments"
2119 2131 " (%d given)", " (%d given)",
2132 (parser->fname == NULL) ? "function" : parser->fname,
2133 (parser->fname == NULL) ? "" : "()",
2120 2134 min < parser->max ? "at least" : "exactly", min < parser->max ? "at least" : "exactly",
2121 2135 min, nargs); min, nargs);
2122 2136 } }
2123 2137 else { else {
2124 2138 keyword = PyTuple_GET_ITEM(kwtuple, i - pos); keyword = PyTuple_GET_ITEM(kwtuple, i - pos);
2125 PyErr_Format(PyExc_TypeError, "Required argument "
2126 "'%U' (pos %d) not found",
2139 PyErr_Format(PyExc_TypeError, "%.200s%s missing required "
2140 "argument '%U' (pos %d)",
2141 (parser->fname == NULL) ? "function" : parser->fname,
2142 (parser->fname == NULL) ? "" : "()",
2127 2143 keyword, i+1); keyword, i+1);
2128 2144 } }
2129 2145 return cleanreturn(0, &freelist); return cleanreturn(0, &freelist);
 
... ... vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs,
2153 2169 if (current_arg) { if (current_arg) {
2154 2170 /* arg present in tuple and in dict */ /* arg present in tuple and in dict */
2155 2171 PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
2156 "Argument given by name ('%U') "
2172 "argument for %.200s%s given by name ('%U') "
2157 2173 "and position (%d)", "and position (%d)",
2174 (parser->fname == NULL) ? "function" : parser->fname,
2175 (parser->fname == NULL) ? "" : "()",
2158 2176 keyword, i+1); keyword, i+1);
2159 2177 return cleanreturn(0, &freelist); return cleanreturn(0, &freelist);
2160 2178 } }
 
... ... vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs,
2184 2202 if (!match) { if (!match) {
2185 2203 PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
2186 2204 "'%U' is an invalid keyword " "'%U' is an invalid keyword "
2187 "argument for this function",
2188 keyword);
2205 "argument for %.200s%s",
2206 keyword,
2207 (parser->fname == NULL) ? "this function" : parser->fname,
2208 (parser->fname == NULL) ? "" : "()");
2189 2209 } }
2190 2210 return cleanreturn(0, &freelist); return cleanreturn(0, &freelist);
2191 2211 } }
 
... ... unpack_stack(PyObject **args, Py_ssize_t nargs, const char *name,
2365 2385 if (name != NULL) if (name != NULL)
2366 2386 PyErr_Format( PyErr_Format(
2367 2387 PyExc_TypeError, PyExc_TypeError,
2368 "%s expected %s%zd arguments, got %zd",
2388 "%.200s expected %s%zd arguments, got %zd",
2369 2389 name, (min == max ? "" : "at least "), min, nargs); name, (min == max ? "" : "at least "), min, nargs);
2370 2390 else else
2371 2391 PyErr_Format( PyErr_Format(
 
... ... unpack_stack(PyObject **args, Py_ssize_t nargs, const char *name,
2384 2404 if (name != NULL) if (name != NULL)
2385 2405 PyErr_Format( PyErr_Format(
2386 2406 PyExc_TypeError, PyExc_TypeError,
2387 "%s expected %s%zd arguments, got %zd",
2407 "%.200s expected %s%zd arguments, got %zd",
2388 2408 name, (min == max ? "" : "at most "), max, nargs); name, (min == max ? "" : "at most "), max, nargs);
2389 2409 else else
2390 2410 PyErr_Format( PyErr_Format(
 
... ... _PyArg_NoKeywords(const char *funcname, PyObject *kwargs)
2469 2489 return 1; return 1;
2470 2490 } }
2471 2491
2472 PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments",
2492 PyErr_Format(PyExc_TypeError, "%.200s does not take keyword arguments",
2473 2493 funcname); funcname);
2474 2494 return 0; return 0;
2475 2495 } }
 
... ... _PyArg_NoStackKeywords(const char *funcname, PyObject *kwnames)
2486 2506 return 1; return 1;
2487 2507 } }
2488 2508
2489 PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments",
2509 PyErr_Format(PyExc_TypeError, "%.200s does not take keyword arguments",
2490 2510 funcname); funcname);
2491 2511 return 0; return 0;
2492 2512 } }
 
... ... _PyArg_NoPositional(const char *funcname, PyObject *args)
2504 2524 if (PyTuple_GET_SIZE(args) == 0) if (PyTuple_GET_SIZE(args) == 0)
2505 2525 return 1; return 1;
2506 2526
2507 PyErr_Format(PyExc_TypeError, "%s does not take positional arguments",
2527 PyErr_Format(PyExc_TypeError, "%.200s does not take positional arguments",
2508 2528 funcname); funcname);
2509 2529 return 0; return 0;
2510 2530 } }
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/benf_wspdigital/cpython

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/benf_wspdigital/cpython

Clone this repository using git:
git clone git://git.rocketgit.com/user/benf_wspdigital/cpython

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main