summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2016-12-15 16:21:23 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2016-12-15 16:21:23 (GMT)
commitccda5c41df456ce6b6b40198233b83e1b18b78db (patch)
tree6a098c96df5086a49a8069defa8ad906bc7a7253 /Lib/test
parent5e65a5f4efeca3b656779973c465abe756e86a67 (diff)
downloadcpython-ccda5c41df456ce6b6b40198233b83e1b18b78db.zip
cpython-ccda5c41df456ce6b6b40198233b83e1b18b78db.tar.gz
cpython-ccda5c41df456ce6b6b40198233b83e1b18b78db.tar.bz2
Fix a memory leak in split-table dictionaries
Issue #28147: Fix a memory leak in split-table dictionaries: setattr() must not convert combined table into split table. Patch written by INADA Naoki. (grafted from 85be9dcc16a81d3ccd1f67b056255a7f206edd47)
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/test_dict.py30
1 files changed, 30 insertions, 0 deletions
diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py
index cd077ff..832bb9c 100644
--- a/Lib/test/test_dict.py
+++ b/Lib/test/test_dict.py
@@ -933,6 +933,36 @@ class DictTest(unittest.TestCase):
self.assertEqual(list(a), ['x', 'y'])
self.assertEqual(list(b), ['x', 'y', 'z'])
+ @support.cpython_only
+ def test_splittable_setattr_after_pop(self):
+ """setattr() must not convert combined table into split table."""
+ # Issue 28147
+ import _testcapi
+
+ class C:
+ pass
+ a = C()
+
+ a.a = 1
+ self.assertTrue(_testcapi.dict_hassplittable(a.__dict__))
+
+ # dict.pop() convert it to combined table
+ a.__dict__.pop('a')
+ self.assertFalse(_testcapi.dict_hassplittable(a.__dict__))
+
+ # But C should not convert a.__dict__ to split table again.
+ a.a = 1
+ self.assertFalse(_testcapi.dict_hassplittable(a.__dict__))
+
+ # Same for popitem()
+ a = C()
+ a.a = 2
+ self.assertTrue(_testcapi.dict_hassplittable(a.__dict__))
+ a.__dict__.popitem()
+ self.assertFalse(_testcapi.dict_hassplittable(a.__dict__))
+ a.a = 3
+ self.assertFalse(_testcapi.dict_hassplittable(a.__dict__))
+
def test_iterator_pickling(self):
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
data = {1:"a", 2:"b", 3:"c"}