diff Python/ceval.c @ 15739:97821a46e000 legacy-trunk

When a PyCFunction that takes only positional parameters is called with an empty keywords dictionary (via apply() or the extended call syntax), the keywords dict should be ignored. If the keywords dict is not empty, TypeError should be raised. (Between the restructuring of the call machinery and this patch, an empty dict in this situation would trigger a SystemError via PyErr_BadInternalCall().) Added regression tests to detect errors for this.
author Fred Drake <fdrake@acm.org>
date Thu, 04 Jan 2001 22:33:02 +0000
parents 2481b5fe86d6
children f9772f87b13e
line wrap: on
line diff
--- a/Python/ceval.c	Thu Jan 04 20:30:56 2001 +0000
+++ b/Python/ceval.c	Thu Jan 04 22:33:02 2001 +0000
@@ -2607,23 +2607,30 @@
 	PyObject *self = PyCFunction_GET_SELF(func);
 	int flags = PyCFunction_GET_FLAGS(func);
 
-	if (flags & METH_KEYWORDS && kw == NULL) {
-		static PyObject *dict = NULL;
-		if (dict == NULL) {
-			dict = PyDict_New();
-			if (dict == NULL)
-				return NULL;
+	if (flags & METH_KEYWORDS) {
+		if (kw == NULL) {
+			static PyObject *dict = NULL;
+			if (dict == NULL) {
+				dict = PyDict_New();
+				if (dict == NULL)
+					return NULL;
+			}
+			kw = dict;
+			Py_INCREF(dict);
 		}
-		kw = dict;
-		Py_INCREF(dict);
+		return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
 	}
-	if (flags & METH_VARARGS && kw == NULL) {
+	if (kw != NULL && PyDict_Size(kw) != 0) {
+		PyErr_Format(PyExc_TypeError,
+			     "%.200s() takes no keyword arguments",
+			     f->m_ml->ml_name);
+		return NULL;
+	}
+	if (flags & METH_VARARGS) {
 		return (*meth)(self, arg);
 	}
-	if (flags & METH_KEYWORDS) {
-		return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
-	}
 	if (!(flags & METH_VARARGS)) {
+		/* the really old style */
 		int size = PyTuple_GET_SIZE(arg);
 		if (size == 1)
 			arg = PyTuple_GET_ITEM(arg, 0);
@@ -2631,12 +2638,6 @@
 			arg = NULL;
 		return (*meth)(self, arg);
 	}
-	if (kw != NULL && PyDict_Size(kw) != 0) {
-		PyErr_Format(PyExc_TypeError,
-			     "%.200s() takes no keyword arguments",
-			     f->m_ml->ml_name);
-		return NULL;
-	}
 	/* should never get here ??? */
 	PyErr_BadInternalCall();
 	return NULL;