[Python-checkins] r55495 - in python/trunk: Doc/ref/ref5.tex Lib/test/output/test_extcall Lib/test/test_extcall.py Misc/NEWS Python/ceval.c
georg.brandl
python-checkins at python.org
Mon May 21 22:34:22 CEST 2007
Author: georg.brandl
Date: Mon May 21 22:34:16 2007
New Revision: 55495
Modified:
python/trunk/Doc/ref/ref5.tex
python/trunk/Lib/test/output/test_extcall
python/trunk/Lib/test/test_extcall.py
python/trunk/Misc/NEWS
python/trunk/Python/ceval.c
Log:
Patch #1686487: you can now pass any mapping after '**' in function calls.
Modified: python/trunk/Doc/ref/ref5.tex
==============================================================================
--- python/trunk/Doc/ref/ref5.tex (original)
+++ python/trunk/Doc/ref/ref5.tex Mon May 21 22:34:16 2007
@@ -704,7 +704,7 @@
this confusion does not arise.
If the syntax \samp{**expression} appears in the function call,
-\samp{expression} must evaluate to a (subclass of) dictionary, the
+\samp{expression} must evaluate to a mapping, the
contents of which are treated as additional keyword arguments. In the
case of a keyword appearing in both \samp{expression} and as an
explicit keyword argument, a \exception{TypeError} exception is
Modified: python/trunk/Lib/test/output/test_extcall
==============================================================================
--- python/trunk/Lib/test/output/test_extcall (original)
+++ python/trunk/Lib/test/output/test_extcall Mon May 21 22:34:16 2007
@@ -9,6 +9,9 @@
(1, 2, 3) {'a': 4, 'b': 5}
(1, 2, 3, 4, 5) {'a': 6, 'b': 7}
(1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5}
+(1, 2, 3) {'a': 4, 'b': 5}
+(1, 2, 3, 4, 5) {'a': 6, 'b': 7}
+(1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5}
TypeError: g() takes at least 1 argument (0 given)
TypeError: g() takes at least 1 argument (0 given)
TypeError: g() takes at least 1 argument (0 given)
@@ -25,12 +28,12 @@
g() got multiple values for keyword argument 'b'
f() keywords must be strings
h() got an unexpected keyword argument 'e'
-h() argument after * must be a sequence
-dir() argument after * must be a sequence
-NoneType object argument after * must be a sequence
-h() argument after ** must be a dictionary
-dir() argument after ** must be a dictionary
-NoneType object argument after ** must be a dictionary
+h() argument after * must be a sequence, not function
+dir() argument after * must be a sequence, not function
+NoneType object argument after * must be a sequence, not function
+h() argument after ** must be a mapping, not function
+dir() argument after ** must be a mapping, not function
+NoneType object argument after ** must be a mapping, not function
dir() got multiple values for keyword argument 'b'
3 512 True
3
Modified: python/trunk/Lib/test/test_extcall.py
==============================================================================
--- python/trunk/Lib/test/test_extcall.py (original)
+++ python/trunk/Lib/test/test_extcall.py Mon May 21 22:34:16 2007
@@ -1,5 +1,6 @@
from test.test_support import verify, verbose, TestFailed, sortdict
from UserList import UserList
+from UserDict import UserDict
def e(a, b):
print a, b
@@ -25,6 +26,12 @@
f(1, 2, 3, *(4, 5), **{'a':6, 'b':7})
f(1, 2, 3, x=4, y=5, *(6, 7), **{'a':8, 'b':9})
+
+f(1, 2, 3, **UserDict(a=4, b=5))
+f(1, 2, 3, *(4, 5), **UserDict(a=6, b=7))
+f(1, 2, 3, x=4, y=5, *(6, 7), **UserDict(a=8, b=9))
+
+
# Verify clearing of SF bug #733667
try:
e(c=3)
Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS (original)
+++ python/trunk/Misc/NEWS Mon May 21 22:34:16 2007
@@ -12,6 +12,9 @@
Core and builtins
-----------------
+- Patch #1686487: you can now pass any mapping after '**' in function
+ calls.
+
- except clauses may now be spelled either "except E, target:" or
"except E as target:". This is to provide forwards compatibility with
Python 3.0.
Modified: python/trunk/Python/ceval.c
==============================================================================
--- python/trunk/Python/ceval.c (original)
+++ python/trunk/Python/ceval.c Mon May 21 22:34:16 2007
@@ -3790,13 +3790,31 @@
if (flags & CALL_FLAG_KW) {
kwdict = EXT_POP(*pp_stack);
- if (!(kwdict && PyDict_Check(kwdict))) {
- PyErr_Format(PyExc_TypeError,
- "%s%s argument after ** "
- "must be a dictionary",
- PyEval_GetFuncName(func),
- PyEval_GetFuncDesc(func));
- goto ext_call_fail;
+ if (!PyDict_Check(kwdict)) {
+ PyObject *d;
+ d = PyDict_New();
+ if (d == NULL)
+ goto ext_call_fail;
+ if (PyDict_Update(d, kwdict) != 0) {
+ Py_DECREF(d);
+ /* PyDict_Update raises attribute
+ * error (percolated from an attempt
+ * to get 'keys' attribute) instead of
+ * a type error if its second argument
+ * is not a mapping.
+ */
+ if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%.200s argument after ** "
+ "must be a mapping, not %.200s",
+ PyEval_GetFuncName(func),
+ PyEval_GetFuncDesc(func),
+ kwdict->ob_type->tp_name);
+ }
+ goto ext_call_fail;
+ }
+ Py_DECREF(kwdict);
+ kwdict = d;
}
}
if (flags & CALL_FLAG_VAR) {
@@ -3807,10 +3825,11 @@
if (t == NULL) {
if (PyErr_ExceptionMatches(PyExc_TypeError)) {
PyErr_Format(PyExc_TypeError,
- "%s%s argument after * "
- "must be a sequence",
+ "%.200s%.200s argument after * "
+ "must be a sequence, not %200s",
PyEval_GetFuncName(func),
- PyEval_GetFuncDesc(func));
+ PyEval_GetFuncDesc(func),
+ stararg->ob_type->tp_name);
}
goto ext_call_fail;
}
More information about the Python-checkins
mailing list