summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_dis.py
diff options
context:
space:
mode:
authorBrandt Bucher <brandtbucher@microsoft.com>2022-06-17 17:26:20 (GMT)
committerGitHub <noreply@github.com>2022-06-17 17:26:20 (GMT)
commit05d83a706c320792246cb4a06a1153c26475a578 (patch)
tree501919fb37ccd508c31747f8b28464d830fd0228 /Lib/test/test_dis.py
parent1353b8a4bcef22d985a0b6a186c96439fd540ea8 (diff)
downloadcpython-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.py36
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):