Skip to content

Commit 79ddf75

Browse files
authored
gh-122712: Test CALL_ALLOC_AND_ENTER_INIT handles reassignment of __code__ (GH-122713)
1 parent ec89620 commit 79ddf75

File tree

1 file changed

+32
-7
lines changed

1 file changed

+32
-7
lines changed

Lib/test/test_opcache.py

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ def wrapper(*args, **kwargs):
2828
return wrapper
2929

3030

31+
class TestBase(unittest.TestCase):
32+
def assert_specialized(self, f, opname):
33+
instructions = dis.get_instructions(f, adaptive=True)
34+
opnames = {instruction.opname for instruction in instructions}
35+
self.assertIn(opname, opnames)
36+
37+
3138
class TestLoadSuperAttrCache(unittest.TestCase):
3239
def test_descriptor_not_double_executed_on_spec_fail(self):
3340
calls = []
@@ -479,7 +486,7 @@ def f():
479486
self.assertFalse(f())
480487

481488

482-
class TestCallCache(unittest.TestCase):
489+
class TestCallCache(TestBase):
483490
def test_too_many_defaults_0(self):
484491
def f():
485492
pass
@@ -507,22 +514,40 @@ def f(x, y):
507514
f(None)
508515
f()
509516

517+
@disabling_optimizer
518+
@requires_specialization
519+
def test_assign_init_code(self):
520+
class MyClass:
521+
def __init__(self):
522+
pass
523+
524+
def instantiate():
525+
return MyClass()
526+
527+
# Trigger specialization
528+
for _ in range(1025):
529+
instantiate()
530+
self.assert_specialized(instantiate, "CALL_ALLOC_AND_ENTER_INIT")
531+
532+
def count_args(self, *args):
533+
self.num_args = len(args)
534+
535+
# Set MyClass.__init__.__code__ to a code object that uses different
536+
# args
537+
MyClass.__init__.__code__ = count_args.__code__
538+
instantiate()
539+
510540

511541
@threading_helper.requires_working_threading()
512542
@requires_specialization
513-
class TestRacesDoNotCrash(unittest.TestCase):
543+
class TestRacesDoNotCrash(TestBase):
514544
# Careful with these. Bigger numbers have a higher chance of catching bugs,
515545
# but you can also burn through a *ton* of type/dict/function versions:
516546
ITEMS = 1000
517547
LOOPS = 4
518548
WARMUPS = 2
519549
WRITERS = 2
520550

521-
def assert_specialized(self, f, opname):
522-
instructions = dis.get_instructions(f, adaptive=True)
523-
opnames = {instruction.opname for instruction in instructions}
524-
self.assertIn(opname, opnames)
525-
526551
@disabling_optimizer
527552
def assert_races_do_not_crash(
528553
self, opname, get_items, read, write, *, check_items=False

0 commit comments

Comments
 (0)