Skip to content

Commit

Permalink
[3.12] pythongh-109052: Use the base opcode when comparing code objec…
Browse files Browse the repository at this point in the history
  • Loading branch information
gaogaotiantian committed Nov 23, 2023
1 parent bfc6d91 commit 0c3bfbd
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 2 deletions.
19 changes: 19 additions & 0 deletions Lib/test/test_code.py
Expand Up @@ -498,6 +498,25 @@ def test_code_hash_uses_bytecode(self):
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])
Expand Down
@@ -0,0 +1 @@
Use the base opcode when comparing code objects to avoid interference from instrumentation
4 changes: 2 additions & 2 deletions Objects/codeobject.c
Expand Up @@ -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;
Expand Down

0 comments on commit 0c3bfbd

Please sign in to comment.