Patch #642500 with slight modifications: allow keyword arguments in

dict() constructor. Example:
  >>> dict(a=1, b=2)
  {'a': 1, 'b': 2}
  >>>
This commit is contained in:
Just van Rossum 2002-11-23 09:45:04 +00:00
parent e17af7b3db
commit a797d8150d
4 changed files with 46 additions and 30 deletions

View File

@ -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}

View File

@ -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 @@ class Mapping:
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:

View File

@ -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.

View File

@ -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)