]> granicus.if.org Git - python/commitdiff
Issue #13521: dict.setdefault() now does only one lookup for the given key, making...
authorAntoine Pitrou <solipsis@pitrou.net>
Sun, 26 Feb 2012 23:59:34 +0000 (00:59 +0100)
committerAntoine Pitrou <solipsis@pitrou.net>
Sun, 26 Feb 2012 23:59:34 +0000 (00:59 +0100)
Patch by Filip GruszczyƄski.

1  2 
Misc/NEWS
Objects/dictobject.c

diff --cc Misc/NEWS
index be6f7004fcfa4a43ace9589b3a0256eb3372e420,b69eb4b60f66592021bdba7b5df8d442fb856591..5fdd7b2de345bf0047a5320433d87fdfc3c8a475
+++ b/Misc/NEWS
@@@ -10,26 -10,13 +10,29 @@@ What's New in Python 3.3 Alpha 1
  Core and Builtins
  -----------------
  
 -- Issue #13703: oCERT-2011-003: add -R command-line option and PYTHONHASHSEED
 -  environment variable, to provide an opt-in way to protect against denial of
 -  service attacks due to hash collisions within the dict and set types.  Patch
 -  by David Malcolm, based on work by Victor Stinner.
+ - Issue #13521: dict.setdefault() now does only one lookup for the given key,
+   making it "atomic" for many purposes.  Patch by Filip GruszczyƄski.
 +- PEP 409, Issue #6210: "raise X from None" is now supported as a means of
 +  suppressing the display of the chained exception context. The chained
 +  context still remains available as the __context__ attribute.
 +
 +- Issue #10181: New memoryview implementation fixes multiple ownership
 +  and lifetime issues of dynamically allocated Py_buffer members (#9990)
 +  as well as crashes (#8305, #7433). Many new features have been added
 +  (See whatsnew/3.3), and the documentation has been updated extensively.
 +  The ndarray test object from _testbuffer.c implements all aspects of
 +  PEP-3118, so further development towards the complete implementation
 +  of the PEP can proceed in a test-driven manner.
 +
 +  Thanks to Nick Coghlan, Antoine Pitrou and Pauli Virtanen for review
 +  and many ideas.
 +
 +- Issue #12834: Fix incorrect results of memoryview.tobytes() for
 +  non-contiguous arrays.
 +
 +- Issue #5231: Introduce memoryview.cast() method that allows changing
 +  format and shape without making a copy of the underlying memory.
  
  - Issue #14084: Fix a file descriptor leak when importing a module with a
    bad encoding.
index 5a8a8a7a09a755a1f1808cd8322cf09b80512837,27de10dc8dfcac2d9c77ffc5c905fb5a9e2bd0bf..83957ac05bf9dde28cdd4f244bd628b7e5e4aa57
@@@ -835,6 -826,36 +833,36 @@@ dict_set_item_by_hash_or_entry(registe
      return dictresize(mp, (mp->ma_used > 50000 ? 2 : 4) * mp->ma_used);
  }
  
 -        hash = ((PyUnicodeObject *) key)->hash;
+ /* CAUTION: PyDict_SetItem() must guarantee that it won't resize the
+  * dictionary if it's merely replacing the value for an existing key.
+  * This means that it's safe to loop over a dictionary with PyDict_Next()
+  * and occasionally replace a value -- but you can't insert new keys or
+  * remove them.
+  */
+ int
+ PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value)
+ {
+     register Py_hash_t hash;
+     if (!PyDict_Check(op)) {
+         PyErr_BadInternalCall();
+         return -1;
+     }
+     assert(key);
+     assert(value);
+     if (PyUnicode_CheckExact(key)) {
++        hash = ((PyASCIIObject *) key)->hash;
+         if (hash == -1)
+             hash = PyObject_Hash(key);
+     }
+     else {
+         hash = PyObject_Hash(key);
+         if (hash == -1)
+             return -1;
+     }
+     return dict_set_item_by_hash_or_entry(op, key, hash, NULL, value);
+ }
  int
  PyDict_DelItem(PyObject *op, PyObject *key)
  {