diff options
-rw-r--r-- | Lib/test/test_b1.py | 11 | ||||
-rw-r--r-- | Lib/test/test_extcall.py | 12 | ||||
-rw-r--r-- | Python/ceval.c | 37 |
3 files changed, 41 insertions, 19 deletions
diff --git a/Lib/test/test_b1.py b/Lib/test/test_b1.py index 6d6aa6f..9511079 100644 --- a/Lib/test/test_b1.py +++ b/Lib/test/test_b1.py @@ -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 diff --git a/Lib/test/test_extcall.py b/Lib/test/test_extcall.py index 7dddabc..cc42818 100644 --- a/Lib/test/test_extcall.py +++ b/Lib/test/test_extcall.py @@ -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' diff --git a/Python/ceval.c b/Python/ceval.c index dd626e5..1559456 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -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; |