]> granicus.if.org Git - python/commitdiff
Optimize _PyFunction_FastCallDict() when kwargs is {}
authorVictor Stinner <victor.stinner@gmail.com>
Tue, 3 Jan 2017 01:01:42 +0000 (02:01 +0100)
committerVictor Stinner <victor.stinner@gmail.com>
Tue, 3 Jan 2017 01:01:42 +0000 (02:01 +0100)
Issue #28839: Optimize _PyFunction_FastCallDict() when kwargs is an empty
dictionary, avoid the creation of an useless empty tuple.

Python/ceval.c

index 5519ac7555a804813b251cc55f3b13e39ad7cb47..cd95642923718352567330c00c40b2105bf65b56 100644 (file)
@@ -5040,9 +5040,9 @@ _PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs,
         }
     }
 
-    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 @@ _PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs,
         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 @@ _PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs,
     else {
         kwtuple = NULL;
         k = NULL;
-        nk = 0;
     }
 
     kwdefs = PyFunction_GET_KW_DEFAULTS(func);