From: Tian Gao Date: Thu, 23 Nov 2023 18:18:17 +0000 (-0800) Subject: [3.12] GH-109052: Use the base opcode when comparing code objects (GH-112329) X-Git-Tag: v3.12.1~100 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3210e3c6cc87d08cee3f61b4bdb322f0427070da;p=thirdparty%2FPython%2Fcpython.git [3.12] GH-109052: Use the base opcode when comparing code objects (GH-112329) --- diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index ca06a39f5df1..de91acfa3549 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -498,6 +498,25 @@ class CodeTest(unittest.TestCase): self.assertNotEqual(c, c1) self.assertNotEqual(hash(c), hash(c1)) + @cpython_only + def test_code_equal_with_instrumentation(self): + """ GH-109052 + + Make sure the instrumentation doesn't affect the code equality + The validity of this test relies on the fact that "x is x" and + "x in x" have only one different instruction and the instructions + have the same argument. + + """ + code1 = compile("x is x", "example.py", "eval") + code2 = compile("x in x", "example.py", "eval") + sys._getframe().f_trace_opcodes = True + sys.settrace(lambda *args: None) + exec(code1, {'x': []}) + exec(code2, {'x': []}) + self.assertNotEqual(code1, code2) + sys.settrace(None) + def isinterned(s): return s is sys.intern(('_' + s + '_')[1:-1]) diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-07-18-49-01.gh-issue-109052.TBU4nC.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-07-18-49-01.gh-issue-109052.TBU4nC.rst new file mode 100644 index 000000000000..175046c771cd --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-09-07-18-49-01.gh-issue-109052.TBU4nC.rst @@ -0,0 +1 @@ +Use the base opcode when comparing code objects to avoid interference from instrumentation diff --git a/Objects/codeobject.c b/Objects/codeobject.c index cda2d2f544ef..1be662156388 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1800,8 +1800,8 @@ code_richcompare(PyObject *self, PyObject *other, int op) for (int i = 0; i < Py_SIZE(co); i++) { _Py_CODEUNIT co_instr = _PyCode_CODE(co)[i]; _Py_CODEUNIT cp_instr = _PyCode_CODE(cp)[i]; - co_instr.op.code = _PyOpcode_Deopt[co_instr.op.code]; - cp_instr.op.code = _PyOpcode_Deopt[cp_instr.op.code]; + co_instr.op.code = _Py_GetBaseOpcode(co, i); + cp_instr.op.code = _Py_GetBaseOpcode(cp, i); eq = co_instr.cache == cp_instr.cache; if (!eq) { goto unequal;