[3.12] GH-109052: Use the base opcode when comparing code objects (GH-112329)

This commit is contained in:
Tian Gao 2023-11-23 10:18:17 -08:00 committed by GitHub
parent bfc6d91c78
commit 3210e3c6cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 2 deletions

View file

@ -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])

View file

@ -0,0 +1 @@
Use the base opcode when comparing code objects to avoid interference from instrumentation

View file

@ -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;