There was an error while loading. Please reload this page.
1 parent bfc6d91 commit 3210e3cCopy full SHA for 3210e3c
3 files changed
Lib/test/test_code.py
@@ -498,6 +498,25 @@ def test_code_hash_uses_bytecode(self):
498
self.assertNotEqual(c, c1)
499
self.assertNotEqual(hash(c), hash(c1))
500
501
+ @cpython_only
502
+ def test_code_equal_with_instrumentation(self):
503
+ """ GH-109052
504
+
505
+ Make sure the instrumentation doesn't affect the code equality
506
+ The validity of this test relies on the fact that "x is x" and
507
+ "x in x" have only one different instruction and the instructions
508
+ have the same argument.
509
510
+ """
511
+ code1 = compile("x is x", "example.py", "eval")
512
+ code2 = compile("x in x", "example.py", "eval")
513
+ sys._getframe().f_trace_opcodes = True
514
+ sys.settrace(lambda *args: None)
515
+ exec(code1, {'x': []})
516
+ exec(code2, {'x': []})
517
+ self.assertNotEqual(code1, code2)
518
+ sys.settrace(None)
519
520
521
def isinterned(s):
522
return s is sys.intern(('_' + s + '_')[1:-1])
Misc/NEWS.d/next/Core and Builtins/2023-09-07-18-49-01.gh-issue-109052.TBU4nC.rst
@@ -0,0 +1 @@
1
+Use the base opcode when comparing code objects to avoid interference from instrumentation
Objects/codeobject.c
@@ -1800,8 +1800,8 @@ code_richcompare(PyObject *self, PyObject *other, int op)
1800
for (int i = 0; i < Py_SIZE(co); i++) {
1801
_Py_CODEUNIT co_instr = _PyCode_CODE(co)[i];
1802
_Py_CODEUNIT cp_instr = _PyCode_CODE(cp)[i];
1803
- co_instr.op.code = _PyOpcode_Deopt[co_instr.op.code];
1804
- 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);
1805
eq = co_instr.cache == cp_instr.cache;
1806
if (!eq) {
1807
goto unequal;
0 commit comments