]> granicus.if.org Git - python/commitdiff
Patch #642500 with slight modifications: allow keyword arguments in
authorJust van Rossum <just@letterror.com>
Sat, 23 Nov 2002 09:45:04 +0000 (09:45 +0000)
committerJust van Rossum <just@letterror.com>
Sat, 23 Nov 2002 09:45:04 +0000 (09:45 +0000)
dict() constructor. Example:
  >>> dict(a=1, b=2)
  {'a': 1, 'b': 2}
  >>>

Doc/lib/libfuncs.tex
Lib/test/test_descr.py
Misc/NEWS
Objects/dictobject.c

index 9fab9ba22c5f1d0f2a63a8d6f04018e3a99852de..169cfc7cc3ef95c53b3b3af664a5cb7f1b247ded 100644 (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}
index 2e1f5af04e12fa3fa4579e2fd50c2e3906745193..95940eee54c3cc4b251a453aff1506167397bf95 100644 (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 @@ 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:
index b2489708fdc4b11e680dc47c134fc1986d47a424..86cf16e378c05730cd350b55ea2ec466bbd131a9 100644 (file)
--- 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.
index e9726cf74c425248dc36ad2a05e9cfc819ffeb3d..2eaa20c26da83399b52057d036d2bdb4cca6685a 100644 (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)