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.
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)
{