summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
authorPablo Galindo <Pablogsal@gmail.com>2020-09-01 20:40:48 (GMT)
committerGitHub <noreply@github.com>2020-09-01 20:40:48 (GMT)
commit77f4000ae0d43a2685face80e7f14d4aba053973 (patch)
tree1d49556219c04d147c74ccbe6eb3937b8d893363 /Lib/test
parent38e32872eb3cf0dc9dd8cef9b05e47ba03638d34 (diff)
downloadcpython-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.py30
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):