summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2016-10-30 17:25:45 +0200
committerSerhiy Storchaka <storchaka@gmail.com>2016-10-30 17:25:45 +0200
commit56b5bad0729a5fc8b685fbdd1958c87d603daa6a (patch)
tree6d12808e70907ff12b22e05459bf240d3d54bc52
parent139c5afe1a2b012799e718a1e573021125799882 (diff)
parentf6bad3cd8369461a6a4a84888be6c393cbcc13ad (diff)
downloadcpython-56b5bad0729a5fc8b685fbdd1958c87d603daa6a.tar.gz
Merge from 3.5.
-rw-r--r--Lib/test/test_ordered_dict.py59
-rw-r--r--Misc/NEWS3
-rw-r--r--Objects/odictobject.c29
3 files changed, 22 insertions, 69 deletions
diff --git a/Lib/test/test_ordered_dict.py b/Lib/test/test_ordered_dict.py
index 582ff563b3..a35ed12436 100644
--- a/Lib/test/test_ordered_dict.py
+++ b/Lib/test/test_ordered_dict.py
@@ -775,64 +775,5 @@ class CPythonSubclassMappingTests(mapping_tests.BasicTestMappingProtocol):
self.assertRaises(KeyError, d.popitem)
-class SimpleLRUCache:
-
- def __init__(self, size):
- super().__init__()
- self.size = size
-
- def __getitem__(self, item):
- value = super().__getitem__(item)
- self.move_to_end(item)
- return value
-
- def __setitem__(self, key, value):
- while key not in self and len(self) >= self.size:
- self.popitem(last=False)
- super().__setitem__(key, value)
- self.move_to_end(key)
-
-
-class SimpleLRUCacheTests:
-
- def test_add_after_full(self):
- c = self.type2test(2)
- c['t1'] = 1
- c['t2'] = 2
- c['t3'] = 3
- self.assertEqual(list(c), ['t2', 't3'])
-
- def test_popitem(self):
- c = self.type2test(3)
- for i in range(1, 4):
- c[i] = i
- self.assertEqual(c.popitem(last=False), (1, 1))
- self.assertEqual(c.popitem(last=True), (3, 3))
-
- def test_change_order_on_get(self):
- c = self.type2test(3)
- for i in range(1, 4):
- c[i] = i
- self.assertEqual(list(c), list(range(1, 4)))
- self.assertEqual(c[2], 2)
- self.assertEqual(list(c), [1, 3, 2])
-
-
-class PySimpleLRUCacheTests(SimpleLRUCacheTests, unittest.TestCase):
-
- class type2test(SimpleLRUCache, py_coll.OrderedDict):
- pass
-
-
-@unittest.skipUnless(c_coll, 'requires the C version of the collections module')
-class CSimpleLRUCacheTests(SimpleLRUCacheTests, unittest.TestCase):
-
- @classmethod
- def setUpClass(cls):
- class type2test(SimpleLRUCache, c_coll.OrderedDict):
- pass
- cls.type2test = type2test
-
-
if __name__ == "__main__":
unittest.main()
diff --git a/Misc/NEWS b/Misc/NEWS
index d49162babd..5d2c4838dd 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -31,9 +31,6 @@ Core and Builtins
Library
-------
-- Issue #27275: Fixed implementation of pop() and popitem() methods in
- subclasses of accelerated OrderedDict.
-
- Issue #18844: The various ways of specifing weights for random.choices()
now produce the same result sequences.
diff --git a/Objects/odictobject.c b/Objects/odictobject.c
index be61d4eadb..22b1f1dfed 100644
--- a/Objects/odictobject.c
+++ b/Objects/odictobject.c
@@ -1102,13 +1102,28 @@ _odict_popkey_hash(PyObject *od, PyObject *key, PyObject *failobj,
}
/* Now delete the value from the dict. */
- if (node != NULL) {
- value = _PyDict_GetItem_KnownHash(od, key, hash); /* borrowed */
- if (value != NULL) {
- Py_INCREF(value);
- if (_PyDict_DelItem_KnownHash(od, key, hash) < 0) {
- Py_DECREF(value);
- return NULL;
+ if (PyODict_CheckExact(od)) {
+ if (node != NULL) {
+ value = _PyDict_GetItem_KnownHash(od, key, hash); /* borrowed */
+ if (value != NULL) {
+ Py_INCREF(value);
+ if (_PyDict_DelItem_KnownHash(od, key, hash) < 0) {
+ Py_DECREF(value);
+ return NULL;
+ }
+ }
+ }
+ }
+ else {
+ int exists = PySequence_Contains(od, key);
+ if (exists < 0)
+ return NULL;
+ if (exists) {
+ value = PyObject_GetItem(od, key);
+ if (value != NULL) {
+ if (PyObject_DelItem(od, key) == -1) {
+ Py_CLEAR(value);
+ }
}
}
}