summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJust van Rossum <just@letterror.com>2002-11-23 09:45:04 (GMT)
committerJust van Rossum <just@letterror.com>2002-11-23 09:45:04 (GMT)
commita797d8150dd6fd8336653d8e91db3c088f2c53ff (patch)
tree02fd69d522c9e7477b11e3cc530f7181d3d052f2
parente17af7b3dbb0ebc6fea7e55052833564ca59d104 (diff)
downloadcpython-a797d8150dd6fd8336653d8e91db3c088f2c53ff.zip
cpython-a797d8150dd6fd8336653d8e91db3c088f2c53ff.tar.gz
cpython-a797d8150dd6fd8336653d8e91db3c088f2c53ff.tar.bz2
Patch #642500 with slight modifications: allow keyword arguments in
dict() constructor. Example: >>> dict(a=1, b=2) {'a': 1, 'b': 2} >>>
-rw-r--r--Doc/lib/libfuncs.tex35
-rw-r--r--Lib/test/test_descr.py23
-rw-r--r--Misc/NEWS6
-rw-r--r--Objects/dictobject.c12
4 files changed, 46 insertions, 30 deletions
diff --git a/Doc/lib/libfuncs.tex b/Doc/lib/libfuncs.tex
index 9fab9ba..169cfc7 100644
--- a/Doc/lib/libfuncs.tex
+++ b/Doc/lib/libfuncs.tex
@@ -189,27 +189,34 @@ def my_import(name):
\end{funcdesc}
\begin{funcdesc}{dict}{\optional{mapping-or-sequence}}
- Return a new dictionary initialized from the optional argument.
- If an argument is not specified, return a new empty dictionary.
- If the argument is a mapping object, return a dictionary mapping the
- same keys to the same values as does the mapping object.
- Else the argument must be a sequence, a container that supports
- iteration, or an iterator object. The elements of the argument must
- each also be of one of those kinds, and each must in turn contain
+ Return a new dictionary initialized from an optional positional
+ argument or from a set of keyword arguments.
+ If no arguments are given, return a new empty dictionary.
+ If the positional argument is a mapping object, return a dictionary
+ mapping the same keys to the same values as does the mapping object.
+ Otherwise the positional argument must be a sequence, a container that
+ supports iteration, or an iterator object. The elements of the argument
+ must each also be of one of those kinds, and each must in turn contain
exactly two objects. The first is used as a key in the new dictionary,
and the second as the key's value. If a given key is seen more than
once, the last value associated with it is retained in the new
dictionary.
+
+ If keyword arguments are given, the keywords themselves with their
+ associated values are added as items to the dictionary. If a key
+ is specified both in the positional argument and as a keyword argument,
+ the value associated with the keyword is retained in the dictionary.
For example, these all return a dictionary equal to
- \code{\{1: 2, 2: 3\}}:
+ \code{\{"one": 2, "two": 3\}}:
\begin{itemize}
- \item \code{dict(\{1: 2, 2: 3\})}
- \item \code{dict(\{1: 2, 2: 3\}.items())}
- \item \code{dict(\{1: 2, 2: 3\}.iteritems())}
- \item \code{dict(zip((1, 2), (2, 3)))}
- \item \code{dict([[2, 3], [1, 2]])}
- \item \code{dict([(i-1, i) for i in (2, 3)])}
+ \item \code{dict(\{'one': 2, 'two': 3\})}
+ \item \code{dict(\{'one': 2, 'two': 3\}.items())}
+ \item \code{dict(\{'one': 2, 'two': 3\}.iteritems())}
+ \item \code{dict(zip(('one', 'two'), (2, 3)))}
+ \item \code{dict([['two', 3], ['one', 2]])}
+ \item \code{dict(one=2, two=3)}
+ \item \code{dict([(['one', 'two'][i-2], i) for i in (2, 3)])}
\end{itemize}
\versionadded{2.2}
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 2e1f5af..95940ee 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -184,12 +184,19 @@ def dict_constructor():
vereq(d, {})
d = dict({})
vereq(d, {})
- d = dict(items={})
+ d = dict({})
vereq(d, {})
d = dict({1: 2, 'a': 'b'})
vereq(d, {1: 2, 'a': 'b'})
vereq(d, dict(d.items()))
- vereq(d, dict(items=d.iteritems()))
+ vereq(d, dict(d.iteritems()))
+ d = dict({'one':1, 'two':2})
+ vereq(d, dict(one=1, two=2))
+ vereq(d, dict(**d))
+ vereq(d, dict({"one": 1}, two=2))
+ vereq(d, dict([("two", 2)], one=1))
+ vereq(d, dict([("one", 100), ("two", 200)], **d))
+ verify(d is not dict(**d))
for badarg in 0, 0L, 0j, "0", [0], (0,):
try:
dict(badarg)
@@ -205,12 +212,6 @@ def dict_constructor():
raise TestFailed("no TypeError from dict(%r)" % badarg)
else:
raise TestFailed("no TypeError from dict(%r)" % badarg)
- try:
- dict(senseless={})
- except TypeError:
- pass
- else:
- raise TestFailed("no TypeError from dict(senseless={})")
try:
dict({}, {})
@@ -232,7 +233,7 @@ def dict_constructor():
Mapping.keys = lambda self: self.dict.keys()
Mapping.__getitem__ = lambda self, i: self.dict[i]
- d = dict(items=Mapping())
+ d = dict(Mapping())
vereq(d, Mapping.dict)
# Init from sequence of iterable objects, each producing a 2-sequence.
@@ -2332,10 +2333,10 @@ def keywords():
vereq(unicode(string='abc', errors='strict'), u'abc')
vereq(tuple(sequence=range(3)), (0, 1, 2))
vereq(list(sequence=(0, 1, 2)), range(3))
- vereq(dict(items={1: 2}), {1: 2})
+ # note: as of Python 2.3, dict() no longer has an "items" keyword arg
for constructor in (int, float, long, complex, str, unicode,
- tuple, list, dict, file):
+ tuple, list, file):
try:
constructor(bogus_keyword_arg=1)
except TypeError:
diff --git a/Misc/NEWS b/Misc/NEWS
index b248970..86cf16e 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -11,6 +11,12 @@ What's New in Python 2.3 alpha 1?
Type/class unification and new-style classes
--------------------------------------------
+- dict() now accepts keyword arguments so that dict(one=1,two=2)
+ is the equivalent of dict([('one',1),('two',2)]). Accordingly,
+ the existing (but undocumented) 'items' keyword argument has
+ been eliminated. This means that dict(items=someMapping) now has
+ a different meaning than before.
+
- int() now returns a long object if the argument is outside the
integer range, so int("4"*1000), int(1e200) and int(1L<<1000) will
all return long objects instead of raising an OverflowError.
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index e9726cf..2eaa20c 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -1705,7 +1705,7 @@ static PyMethodDef mapp_methods[] = {
{"setdefault", (PyCFunction)dict_setdefault, METH_VARARGS,
setdefault_doc__},
{"pop", (PyCFunction)dict_pop, METH_O,
- pop__doc__},
+ pop__doc__},
{"popitem", (PyCFunction)dict_popitem, METH_NOARGS,
popitem__doc__},
{"keys", (PyCFunction)dict_keys, METH_NOARGS,
@@ -1781,11 +1781,9 @@ static int
dict_init(PyObject *self, PyObject *args, PyObject *kwds)
{
PyObject *arg = NULL;
- static char *kwlist[] = {"items", 0};
int result = 0;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:dict",
- kwlist, &arg))
+ if (!PyArg_ParseTuple(args, "|O:dict", &arg))
result = -1;
else if (arg != NULL) {
@@ -1794,6 +1792,8 @@ dict_init(PyObject *self, PyObject *args, PyObject *kwds)
else
result = PyDict_MergeFromSeq2(self, arg, 1);
}
+ if (result == 0 && kwds != NULL)
+ result = PyDict_Merge(self, kwds, 1);
return result;
}
@@ -1817,7 +1817,9 @@ PyDoc_STRVAR(dictionary_doc,
"dict(seq) -> new dictionary initialized as if via:\n"
" d = {}\n"
" for k, v in seq:\n"
-" d[k] = v");
+" d[k] = v\n"
+"dict(**kwargs) -> new dictionary initialized with the name=value pairs\n"
+" in the keyword argument list. For example: dict(one=1, two=2)");
PyTypeObject PyDict_Type = {
PyObject_HEAD_INIT(&PyType_Type)