diff options
author | Brandt Bucher <brandtbucher@microsoft.com> | 2022-06-17 17:26:20 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-17 17:26:20 (GMT) |
commit | 05d83a706c320792246cb4a06a1153c26475a578 (patch) | |
tree | 501919fb37ccd508c31747f8b28464d830fd0228 /Lib/test/test_dis.py | |
parent | 1353b8a4bcef22d985a0b6a186c96439fd540ea8 (diff) | |
download | cpython-05d83a706c320792246cb4a06a1153c26475a578.zip cpython-05d83a706c320792246cb4a06a1153c26475a578.tar.gz cpython-05d83a706c320792246cb4a06a1153c26475a578.tar.bz2 |
GH-91389: Fix dis position information for CACHEs (GH-93663) (GH-93921)
(cherry picked from commit f8e576be0a7cd38f753f31cf4178db81a602fc32)
Diffstat (limited to 'Lib/test/test_dis.py')
-rw-r--r-- | Lib/test/test_dis.py | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index edcac8e..e3e4a37 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -1060,8 +1060,10 @@ class DisTests(DisTestBase): caches = list(self.get_cached_values(quickened, adaptive)) for cache in caches: self.assertRegex(cache, pattern) - self.assertEqual(caches.count(""), 8) - self.assertEqual(len(caches), 25) + total_caches = 25 + empty_caches = 8 if adaptive and quickened else total_caches + self.assertEqual(caches.count(""), empty_caches) + self.assertEqual(len(caches), total_caches) class DisWithFileTests(DisTests): @@ -1629,6 +1631,36 @@ class InstructionTests(InstructionTestCase): self.assertIsNone(positions.col_offset) self.assertIsNone(positions.end_col_offset) + @requires_debug_ranges() + def test_co_positions_with_lots_of_caches(self): + def roots(a, b, c): + d = b**2 - 4 * a * c + yield (-b - cmath.sqrt(d)) / (2 * a) + if d: + yield (-b + cmath.sqrt(d)) / (2 * a) + code = roots.__code__ + ops = code.co_code[::2] + cache_opcode = opcode.opmap["CACHE"] + caches = sum(op == cache_opcode for op in ops) + non_caches = len(ops) - caches + # Make sure we have "lots of caches". If not, roots should be changed: + assert 1 / 3 <= caches / non_caches, "this test needs more caches!" + for show_caches in (False, True): + for adaptive in (False, True): + with self.subTest(f"{adaptive=}, {show_caches=}"): + co_positions = [ + positions + for op, positions in zip(ops, code.co_positions(), strict=True) + if show_caches or op != cache_opcode + ] + dis_positions = [ + instruction.positions + for instruction in dis.get_instructions( + code, adaptive=adaptive, show_caches=show_caches + ) + ] + self.assertEqual(co_positions, dis_positions) + # get_instructions has its own tests above, so can rely on it to validate # the object oriented API class BytecodeTests(InstructionTestCase, DisTestBase): |