summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2009-01-20 14:21:16 (GMT)
committerBenjamin Peterson <benjamin@python.org>2009-01-20 14:21:16 (GMT)
commite18ef194d93afe9480ea7bd1da24d3636b81f2b3 (patch)
tree36597711edf34eaab5c4acac72b1b7d8834088a7 /Python
parent196a0f7a8aa4c0b3482bcdf08473c9e593e41be0 (diff)
downloadcpython-e18ef194d93afe9480ea7bd1da24d3636b81f2b3.zip
cpython-e18ef194d93afe9480ea7bd1da24d3636b81f2b3.tar.gz
cpython-e18ef194d93afe9480ea7bd1da24d3636b81f2b3.tar.bz2
allow unicode keyword arguments for the ** syntax #4978
Diffstat (limited to 'Python')
-rw-r--r--Python/ceval.c45
1 files changed, 33 insertions, 12 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 88483a5..92a7653 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -127,6 +127,7 @@ static void reset_exc_info(PyThreadState *);
static void format_exc_check_arg(PyObject *, char *, PyObject *);
static PyObject * string_concatenate(PyObject *, PyObject *,
PyFrameObject *, unsigned char *);
+static PyObject * kwd_as_string(PyObject *);
#define NAME_ERROR_MSG \
"name '%.200s' is not defined"
@@ -2932,7 +2933,8 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
PyObject *keyword = kws[2*i];
PyObject *value = kws[2*i + 1];
int j;
- if (keyword == NULL || !PyString_Check(keyword)) {
+ if (keyword == NULL || !(PyString_Check(keyword) ||
+ PyUnicode_Check(keyword))) {
PyErr_Format(PyExc_TypeError,
"%.200s() keywords must be strings",
PyString_AsString(co->co_name));
@@ -2961,11 +2963,15 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
goto fail;
if (j >= co->co_argcount) {
if (kwdict == NULL) {
- PyErr_Format(PyExc_TypeError,
- "%.200s() got an unexpected "
- "keyword argument '%.400s'",
- PyString_AsString(co->co_name),
- PyString_AsString(keyword));
+ PyObject *kwd_str = kwd_as_string(keyword);
+ if (kwd_str) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() got an unexpected "
+ "keyword argument '%.400s'",
+ PyString_AsString(co->co_name),
+ PyString_AsString(kwd_str));
+ Py_DECREF(kwd_str);
+ }
goto fail;
}
PyDict_SetItem(kwdict, keyword, value);
@@ -2973,12 +2979,16 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
}
kw_found:
if (GETLOCAL(j) != NULL) {
- PyErr_Format(PyExc_TypeError,
- "%.200s() got multiple "
- "values for keyword "
- "argument '%.400s'",
- PyString_AsString(co->co_name),
- PyString_AsString(keyword));
+ PyObject *kwd_str = kwd_as_string(keyword);
+ if (kwd_str) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() got multiple "
+ "values for keyword "
+ "argument '%.400s'",
+ PyString_AsString(co->co_name),
+ PyString_AsString(kwd_str));
+ Py_DECREF(kwd_str);
+ }
goto fail;
}
Py_INCREF(value);
@@ -3105,6 +3115,17 @@ fail: /* Jump here from prelude on failure */
}
+static PyObject *
+kwd_as_string(PyObject *kwd) {
+ if (PyString_Check(kwd)) {
+ Py_INCREF(kwd);
+ return kwd;
+ }
+ else
+ return _PyUnicode_AsDefaultEncodedString(kwd, "replace");
+}
+
+
/* Implementation notes for set_exc_info() and reset_exc_info():
- Below, 'exc_ZZZ' stands for 'exc_type', 'exc_value' and