]> granicus.if.org Git - python/commitdiff
When a PyCFunction that takes only positional parameters is called with
authorFred Drake <fdrake@acm.org>
Thu, 4 Jan 2001 22:33:02 +0000 (22:33 +0000)
committerFred Drake <fdrake@acm.org>
Thu, 4 Jan 2001 22:33:02 +0000 (22:33 +0000)
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.

Lib/test/test_b1.py
Lib/test/test_extcall.py
Python/ceval.c

index 6d6aa6fcf1821d8ecbb493b4b1a85783184a9351..95110790f0a9f3cf84bb9efa2160a5030f239d9c 100644 (file)
@@ -39,6 +39,17 @@ apply(f1, (1,))
 apply(f2, (1, 2))
 apply(f3, (1, 2, 3))
 
+# A PyCFunction that takes only positional parameters should allow an
+# empty keyword dictionary to pass without a complaint, but raise a
+# TypeError if the dictionary is non-empty.
+apply(id, (1,), {})
+try:
+    apply(id, (1,), {"foo": 1})
+except TypeError:
+    pass
+else:
+    raise TestFailed, 'expected TypeError; no exception raised'
+
 print 'callable'
 if not callable(len):raise TestFailed, 'callable(len)'
 def f(): pass
index 7dddabca65c021fb07c66c39ac9ae2cb9b2d8195..cc42818c9a6ba61185471deb4b17d485a60a4b31 100644 (file)
@@ -1,4 +1,5 @@
 from UserList import UserList
+from test_support import TestFailed
 
 def f(*a, **k):
     print a, k
@@ -161,4 +162,13 @@ try:
 except TypeError, err:
     print err
 
-
+# A PyCFunction that takes only positional parameters should allow an
+# empty keyword dictionary to pass without a complaint, but raise a
+# TypeError if the dictionary is non-empty.
+id(1, **{})
+try:
+    id(1, **{"foo": 1})
+except TypeError:
+    pass
+else:
+    raise TestFailed, 'expected TypeError; no exception raised'
index dd626e5f88dd8e6a01404a2f2214ebe9f228959f..1559456e6bf9344721635ff20d4c8e3917c0f962 100644 (file)
@@ -2607,23 +2607,30 @@ call_cfunction(PyObject *func, PyObject *arg, PyObject *kw)
        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) {
-               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;
        }
-       if (flags & METH_KEYWORDS) {
-               return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
+       if (flags & METH_VARARGS) {
+               return (*meth)(self, arg);
        }
        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 @@ call_cfunction(PyObject *func, PyObject *arg, PyObject *kw)
                        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;