diff options
author | mpage <mpage@meta.com> | 2024-08-22 07:38:04 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-22 07:38:04 (GMT) |
commit | 79ddf7571016a04f0e1d5f416ece2d45c4440b1b (patch) | |
tree | 0f520ad559bfa79439dc8cd77607f910a0b57c08 | |
parent | ec89620e5e147ba028a46dd695ef073a72000b84 (diff) | |
download | cpython-79ddf7571016a04f0e1d5f416ece2d45c4440b1b.zip cpython-79ddf7571016a04f0e1d5f416ece2d45c4440b1b.tar.gz cpython-79ddf7571016a04f0e1d5f416ece2d45c4440b1b.tar.bz2 |
gh-122712: Test `CALL_ALLOC_AND_ENTER_INIT` handles reassignment of `__code__` (GH-122713)
-rw-r--r-- | Lib/test/test_opcache.py | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/Lib/test/test_opcache.py b/Lib/test/test_opcache.py index 92a3411..acf8158 100644 --- a/Lib/test/test_opcache.py +++ b/Lib/test/test_opcache.py @@ -28,6 +28,13 @@ def disabling_optimizer(func): return wrapper +class TestBase(unittest.TestCase): + def assert_specialized(self, f, opname): + instructions = dis.get_instructions(f, adaptive=True) + opnames = {instruction.opname for instruction in instructions} + self.assertIn(opname, opnames) + + class TestLoadSuperAttrCache(unittest.TestCase): def test_descriptor_not_double_executed_on_spec_fail(self): calls = [] @@ -479,7 +486,7 @@ class TestLoadMethodCache(unittest.TestCase): self.assertFalse(f()) -class TestCallCache(unittest.TestCase): +class TestCallCache(TestBase): def test_too_many_defaults_0(self): def f(): pass @@ -507,10 +514,33 @@ class TestCallCache(unittest.TestCase): f(None) f() + @disabling_optimizer + @requires_specialization + def test_assign_init_code(self): + class MyClass: + def __init__(self): + pass + + def instantiate(): + return MyClass() + + # Trigger specialization + for _ in range(1025): + instantiate() + self.assert_specialized(instantiate, "CALL_ALLOC_AND_ENTER_INIT") + + def count_args(self, *args): + self.num_args = len(args) + + # Set MyClass.__init__.__code__ to a code object that uses different + # args + MyClass.__init__.__code__ = count_args.__code__ + instantiate() + @threading_helper.requires_working_threading() @requires_specialization -class TestRacesDoNotCrash(unittest.TestCase): +class TestRacesDoNotCrash(TestBase): # Careful with these. Bigger numbers have a higher chance of catching bugs, # but you can also burn through a *ton* of type/dict/function versions: ITEMS = 1000 @@ -518,11 +548,6 @@ class TestRacesDoNotCrash(unittest.TestCase): WARMUPS = 2 WRITERS = 2 - def assert_specialized(self, f, opname): - instructions = dis.get_instructions(f, adaptive=True) - opnames = {instruction.opname for instruction in instructions} - self.assertIn(opname, opnames) - @disabling_optimizer def assert_races_do_not_crash( self, opname, get_items, read, write, *, check_items=False |