diff options
author | Pablo Galindo <Pablogsal@gmail.com> | 2020-09-01 20:40:48 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-01 20:40:48 (GMT) |
commit | 77f4000ae0d43a2685face80e7f14d4aba053973 (patch) | |
tree | 1d49556219c04d147c74ccbe6eb3937b8d893363 /Lib/test | |
parent | 38e32872eb3cf0dc9dd8cef9b05e47ba03638d34 (diff) | |
download | cpython-77f4000ae0d43a2685face80e7f14d4aba053973.zip cpython-77f4000ae0d43a2685face80e7f14d4aba053973.tar.gz cpython-77f4000ae0d43a2685face80e7f14d4aba053973.tar.bz2 |
[3.8] [3.9] bpo-41654: Fix deallocator of MemoryError to account for subclasses (GH-22020) (GH-22046)
When allocating MemoryError classes, there is some logic to use
pre-allocated instances in a freelist only if the type that is being
allocated is not a subclass of MemoryError. Unfortunately in the
destructor this logic is not present so the freelist is altered even
with subclasses of MemoryError..
(cherry picked from commit 9b648a95ccb4c3b14f1e87158f5c9f5dbb2f62c0)
Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>.
(cherry picked from commit 87e91ae2e5f81e096c32839f211c68a749a4435a)
Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
Diffstat (limited to 'Lib/test')
-rw-r--r-- | Lib/test/test_exceptions.py | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 3a32253..457b46e 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1,6 +1,7 @@ # Python test set -- part 5, built-in exceptions import copy +import gc import os import sys import unittest @@ -1297,6 +1298,35 @@ class ExceptionTests(unittest.TestCase): next(i) next(i) + def test_memory_error_subclasses(self): + # bpo-41654: MemoryError instances use a freelist of objects that are + # linked using the 'dict' attribute when they are inactive/dead. + # Subclasses of MemoryError should not participate in the freelist + # schema. This test creates a MemoryError object and keeps it alive + # (therefore advancing the freelist) and then it creates and destroys a + # subclass object. Finally, it checks that creating a new MemoryError + # succeeds, proving that the freelist is not corrupted. + + class TestException(MemoryError): + pass + + try: + raise MemoryError + except MemoryError as exc: + inst = exc + + try: + raise TestException + except Exception: + pass + + for _ in range(10): + try: + raise MemoryError + except MemoryError as exc: + pass + + gc_collect() class ImportErrorTests(unittest.TestCase): |