]> granicus.if.org Git - python/commitdiff
Add Raymond Hettinger's d.pop(). See SF patch 539949.
authorGuido van Rossum <guido@python.org>
Fri, 12 Apr 2002 15:11:59 +0000 (15:11 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 12 Apr 2002 15:11:59 +0000 (15:11 +0000)
Doc/lib/libstdtypes.tex
Lib/test/test_types.py
Objects/dictobject.c

index f42f84e985f59c3401b8dc68412bc17596322c07..a619105cbaa37e98e4bbe831be98209e9c279327 100644 (file)
@@ -992,6 +992,9 @@ arbitrary objects):
           {\code{\var{a}[\var{k}]} if \code{\var{k} in \var{a}},
            else \var{x} (also setting it)}
           {(5)}
+  \lineiii{\var{a}.pop(\var{k})}
+          {remove specified \var{key} and return corresponding \var{value}}
+          {}                        
   \lineiii{\var{a}.popitem()}
           {remove and return an arbitrary (\var{key}, \var{value}) pair}
           {(6)}
index 26535c49050b03b3e4456f24205575564720c0d5..9d4508b16a651ef5cad09f02419a265dbc02906d 100644 (file)
@@ -476,6 +476,21 @@ try: d.popitem()
 except KeyError: pass
 else: raise TestFailed, "{}.popitem doesn't raise KeyError"
 
+# Tests for pop with specified key
+d.clear()
+k, v = 'abc', 'def'
+d[k] = v
+try: d.pop('ghi')
+except KeyError: pass
+else: raise TestFailed, "{}.pop(k) doesn't raise KeyError when k not in dictionary"
+
+if d.pop(k) != v: raise TestFailed, "{}.pop(k) doesn't find known key/value pair"
+if len(d) > 0: raise TestFailed, "{}.pop(k) failed to remove the specified pair"
+
+try: d.pop(k)
+except KeyError: pass
+else: raise TestFailed, "{}.pop(k) doesn't raise KeyError when dictionary is empty"
+
 d[1] = 1
 try:
     for i in d:
index ffc057933eb69fe7b0519d1430980d30c1a4d01e..1bd2f64143ac8dfe8429f478fef8787e24366064 100644 (file)
@@ -1494,6 +1494,39 @@ dict_clear(register dictobject *mp)
        return Py_None;
 }
 
+static PyObject *
+dict_pop(dictobject *mp, PyObject *key)
+{
+       long hash;
+       dictentry *ep;
+       PyObject *old_value, *old_key;
+
+       if (mp->ma_used == 0) {
+               PyErr_SetString(PyExc_KeyError,
+                               "pop(): dictionary is empty");
+               return NULL;
+       }
+       if (!PyString_CheckExact(key) ||
+           (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+               hash = PyObject_Hash(key);
+               if (hash == -1)
+                       return NULL;
+       }
+       ep = (mp->ma_lookup)(mp, key, hash);
+       if (ep->me_value == NULL) {
+               PyErr_SetObject(PyExc_KeyError, key);
+               return NULL;
+       }
+       old_key = ep->me_key;
+       Py_INCREF(dummy);
+       ep->me_key = dummy;
+       old_value = ep->me_value;
+       ep->me_value = NULL;
+       mp->ma_used--;
+       Py_DECREF(old_key);
+       return old_value;
+}
+
 static PyObject *
 dict_popitem(dictobject *mp)
 {
@@ -1636,6 +1669,9 @@ static char get__doc__[] =
 static char setdefault_doc__[] =
 "D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if not D.has_key(k)";
 
+static char pop__doc__[] =
+"D.pop(k) -> v, remove specified key and return the corresponding value";
+
 static char popitem__doc__[] =
 "D.popitem() -> (k, v), remove and return some (key, value) pair as a\n\
 2-tuple; but raise KeyError if D is empty";
@@ -1674,6 +1710,8 @@ static PyMethodDef mapp_methods[] = {
         get__doc__},
        {"setdefault",  (PyCFunction)dict_setdefault,   METH_VARARGS,
         setdefault_doc__},
+       {"pop",         (PyCFunction)dict_pop,          METH_O,
+        pop__doc__},   
        {"popitem",     (PyCFunction)dict_popitem,      METH_NOARGS,
         popitem__doc__},
        {"keys",        (PyCFunction)dict_keys,         METH_NOARGS,