gh-117680: make _PyInstructionSequence a PyObject and use it in tests (#117629)

This commit is contained in:
Irit Katriel 2024-04-17 16:42:04 +01:00 committed by GitHub
parent ae8dfd2761
commit c179c0e6cb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 838 additions and 242 deletions

View file

@ -2,6 +2,7 @@ import contextlib
import dis
import io
import math
import opcode
import os
import unittest
import sys
@ -11,6 +12,8 @@ import tempfile
import types
import textwrap
import warnings
import _testinternalcapi
from test import support
from test.support import (script_helper, requires_debug_ranges,
requires_specialization, get_c_recursion_limit)
@ -2419,6 +2422,49 @@ class TestStackSizeStability(unittest.TestCase):
"""
self.check_stack_size(snippet, async_=True)
class TestInstructionSequence(unittest.TestCase):
def compare_instructions(self, seq, expected):
self.assertEqual([(opcode.opname[i[0]],) + i[1:] for i in seq.get_instructions()],
expected)
def test_basics(self):
seq = _testinternalcapi.new_instruction_sequence()
def add_op(seq, opname, oparg, bl, bc=0, el=0, ec=0):
seq.addop(opcode.opmap[opname], oparg, bl, bc, el, el)
add_op(seq, 'LOAD_CONST', 1, 1)
add_op(seq, 'JUMP', lbl1 := seq.new_label(), 2)
add_op(seq, 'LOAD_CONST', 1, 3)
add_op(seq, 'JUMP', lbl2 := seq.new_label(), 4)
seq.use_label(lbl1)
add_op(seq, 'LOAD_CONST', 2, 4)
seq.use_label(lbl2)
add_op(seq, 'RETURN_VALUE', 0, 3)
expected = [('LOAD_CONST', 1, 1),
('JUMP', 4, 2),
('LOAD_CONST', 1, 3),
('JUMP', 5, 4),
('LOAD_CONST', 2, 4),
('RETURN_VALUE', None, 3),
]
self.compare_instructions(seq, [ex + (0,0,0) for ex in expected])
def test_nested(self):
seq = _testinternalcapi.new_instruction_sequence()
seq.addop(opcode.opmap['LOAD_CONST'], 1, 1, 0, 0, 0)
nested = _testinternalcapi.new_instruction_sequence()
nested.addop(opcode.opmap['LOAD_CONST'], 2, 2, 0, 0, 0)
self.compare_instructions(seq, [('LOAD_CONST', 1, 1, 0, 0, 0)])
self.compare_instructions(nested, [('LOAD_CONST', 2, 2, 0, 0, 0)])
seq.add_nested(nested)
self.compare_instructions(seq, [('LOAD_CONST', 1, 1, 0, 0, 0)])
self.compare_instructions(seq.get_nested()[0], [('LOAD_CONST', 2, 2, 0, 0, 0)])
if __name__ == "__main__":
unittest.main()