The instruction pointer f_lasti points under some conditions to a CACHE opcode.
This is not completely wrong, because this cache opcode comes after the expected CALL opcode, but the documetation says that CACHE opcodes should be skipped. Which it is not in this case.
script:
importinspectimportdisframe=inspect.currentframe()
classTester:
def__call__(self, f):
deco(f)
tester=Tester()
defdeco(f):
assertf.__name__=="foo"instructions=list(dis.get_instructions(frame.f_code, show_caches=True))
opname=instructions[frame.f_lasti//2].opnameprint(f"{frame.f_lasti=}\n{opname=}")
assertopname=="CALL", opnameprint("correct")
@testerdeffoo():
passprint()
print("incorrect")
@decodeffoo():
passoutput (Python 3.11.0rc2+):
correctframe.f_lasti=132opname='CALL'incorrectframe.f_lasti=204opname='CACHE'Traceback (mostrecentcalllast):
File"/home/frank/projects/executing/example.py", line35, in<module>
@deco^^^^File"/home/frank/projects/executing/example.py", line20, indecoassertopname=="CALL", opnameAssertionError: CACHE
The instruction pointer
f_lastipoints under some conditions to a CACHE opcode.This is not completely wrong, because this cache opcode comes after the expected
CALLopcode, but the documetation says that CACHE opcodes should be skipped. Which it is not in this case.script:
output (Python 3.11.0rc2+):