(original) (raw)
changeset: 105973:f9dd607dc04c user: Victor Stinner victor.stinner@gmail.com date: Tue Jan 03 02:01:42 2017 +0100 files: Python/ceval.c description: Optimize _PyFunction_FastCallDict() when kwargs is {} Issue #28839: Optimize _PyFunction_FastCallDict() when kwargs is an empty dictionary, avoid the creation of an useless empty tuple. diff -r 5f7cd3b6c9b1 -r f9dd607dc04c Python/ceval.c --- a/Python/ceval.c Tue Jan 03 01:58:17 2017 +0100 +++ b/Python/ceval.c Tue Jan 03 02:01:42 2017 +0100 @@ -5040,9 +5040,9 @@ } } - if (kwargs != NULL) { + nk = (kwargs != NULL) ? PyDict_GET_SIZE(kwargs) : 0; + if (nk != 0) { Py_ssize_t pos, i; - nk = PyDict_GET_SIZE(kwargs); kwtuple = PyTuple_New(2 * nk); if (kwtuple == NULL) { @@ -5052,6 +5052,9 @@ k = &PyTuple_GET_ITEM(kwtuple, 0); pos = i = 0; while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { + /* We must hold strong references because keyword arguments can be + indirectly modified while the function is called: + see issue #2016 and test_extcall */ Py_INCREF(k[i]); Py_INCREF(k[i+1]); i += 2; @@ -5061,7 +5064,6 @@ else { kwtuple = NULL; k = NULL; - nk = 0; } kwdefs = PyFunction_GET_KW_DEFAULTS(func); /victor.stinner@gmail.com