]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-115999: Move specializer test from test_dis to test_opcache (gh-126498)
authorDonghee Na <donghee.na@python.org>
Wed, 6 Nov 2024 20:23:47 +0000 (05:23 +0900)
committerGitHub <noreply@github.com>
Wed, 6 Nov 2024 20:23:47 +0000 (05:23 +0900)
Lib/test/test_dis.py
Lib/test/test_opcache.py

index 337ee3bbb05136bcd99f44ec9072250cc8e5dc70..f26411ace8fa732824eb27d60308980a1e7a4b74 100644 (file)
@@ -10,8 +10,7 @@ import sys
 import types
 import unittest
 from test.support import (captured_stdout, requires_debug_ranges,
-                          requires_specialization, requires_specialization_ft,
-                          cpython_only)
+                          requires_specialization, cpython_only)
 from test.support.bytecode_helper import BytecodeTestCase
 
 import opcode
@@ -1261,27 +1260,6 @@ class DisTests(DisTestBase):
         got = self.get_disassembly(load_test, adaptive=True)
         self.do_disassembly_compare(got, dis_load_test_quickened_code)
 
-    @cpython_only
-    @requires_specialization_ft
-    def test_binary_specialize(self):
-        binary_op_quicken = """\
-  0           RESUME_CHECK             0
-
-  1           LOAD_NAME                0 (a)
-              LOAD_NAME                1 (b)
-              %s
-              RETURN_VALUE
-"""
-        co_int = compile('a + b', "<int>", "eval")
-        self.code_quicken(lambda: exec(co_int, {}, {'a': 1, 'b': 2}))
-        got = self.get_disassembly(co_int, adaptive=True)
-        self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_INT        0 (+)")
-
-        co_unicode = compile('a + b', "<unicode>", "eval")
-        self.code_quicken(lambda: exec(co_unicode, {}, {'a': 'a', 'b': 'b'}))
-        got = self.get_disassembly(co_unicode, adaptive=True)
-        self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_UNICODE    0 (+)")
-
     @cpython_only
     @requires_specialization
     def test_binary_subscr_specialize(self):
@@ -1335,27 +1313,6 @@ class DisTests(DisTestBase):
         got = self.get_disassembly(co, adaptive=True)
         self.do_disassembly_compare(got, call_quicken)
 
-    @cpython_only
-    @requires_specialization_ft
-    def test_contains_specialize(self):
-        contains_op_quicken = """\
-  0           RESUME_CHECK             0
-
-  1           LOAD_NAME                0 (a)
-              LOAD_NAME                1 (b)
-              %s
-              RETURN_VALUE
-"""
-        co_dict = compile('a in b', "<dict>", "eval")
-        self.code_quicken(lambda: exec(co_dict, {}, {'a': 1, 'b': {1: 5}}))
-        got = self.get_disassembly(co_dict, adaptive=True)
-        self.do_disassembly_compare(got, contains_op_quicken % "CONTAINS_OP_DICT         0 (in)")
-
-        co_set = compile('a in b', "<set>", "eval")
-        self.code_quicken(lambda: exec(co_set, {}, {'a': 1.0, 'b': {1, 2, 3}}))
-        got = self.get_disassembly(co_set, adaptive=True)
-        self.do_disassembly_compare(got, contains_op_quicken % "CONTAINS_OP_SET          0 (in)")
-
     @cpython_only
     @requires_specialization
     def test_loop_quicken(self):
index cdcddb0d717f23ab07825a61f850e166ee69e976..78e4bf44f7ea0c62fb7686d4e7ea58dfbefd8e32 100644 (file)
@@ -4,7 +4,9 @@ import dis
 import threading
 import types
 import unittest
-from test.support import threading_helper, check_impl_detail, requires_specialization
+from test.support import (threading_helper, check_impl_detail,
+                          requires_specialization, requires_specialization_ft,
+                          cpython_only)
 from test.support.import_helper import import_module
 
 # Skip this module on other interpreters, it is cpython specific:
@@ -34,6 +36,11 @@ class TestBase(unittest.TestCase):
         opnames = {instruction.opname for instruction in instructions}
         self.assertIn(opname, opnames)
 
+    def assert_no_opcode(self, f, opname):
+        instructions = dis.get_instructions(f, adaptive=True)
+        opnames = {instruction.opname for instruction in instructions}
+        self.assertNotIn(opname, opnames)
+
 
 class TestLoadSuperAttrCache(unittest.TestCase):
     def test_descriptor_not_double_executed_on_spec_fail(self):
@@ -1200,5 +1207,55 @@ class TestInstanceDict(unittest.TestCase):
         self.assertEqual(test_obj.b, 0)
 
 
+class TestSpecializer(TestBase):
+
+    @cpython_only
+    @requires_specialization_ft
+    def test_binary_op(self):
+        def f():
+            for _ in range(100):
+                a, b = 1, 2
+                c = a + b
+                self.assertEqual(c, 3)
+
+        f()
+        self.assert_specialized(f, "BINARY_OP_ADD_INT")
+        self.assert_no_opcode(f, "BINARY_OP")
+
+        def g():
+            for _ in range(100):
+                a, b = "foo", "bar"
+                c = a + b
+                self.assertEqual(c, "foobar")
+
+        g()
+        self.assert_specialized(g, "BINARY_OP_ADD_UNICODE")
+        self.assert_no_opcode(g, "BINARY_OP")
+
+    @cpython_only
+    @requires_specialization_ft
+    def test_contain_op(self):
+        def f():
+            for _ in range(100):
+                a, b = 1, {1: 2, 2: 5}
+                self.assertTrue(a in b)
+                self.assertFalse(3 in b)
+
+        f()
+        self.assert_specialized(f, "CONTAINS_OP_DICT")
+        self.assert_no_opcode(f, "CONTAINS_OP")
+
+        def g():
+            for _ in range(100):
+                a, b = 1, {1, 2}
+                self.assertTrue(a in b)
+                self.assertFalse(3 in b)
+
+        g()
+        self.assert_specialized(g, "CONTAINS_OP_SET")
+        self.assert_no_opcode(g, "CONTAINS_OP")
+
+
+
 if __name__ == "__main__":
     unittest.main()