summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_b1.py11
-rw-r--r--Lib/test/test_extcall.py12
-rw-r--r--Python/ceval.c37
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;