-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
Closed as not planned
Labels
3.11only security fixesonly security fixes3.12only security fixesonly security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
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:
import inspect
import dis
frame = inspect.currentframe()
class Tester:
def __call__(self, f):
deco(f)
tester = Tester()
def deco(f):
assert f.__name__ == "foo"
instructions = list(dis.get_instructions(frame.f_code, show_caches=True))
opname = instructions[frame.f_lasti // 2].opname
print(f"{frame.f_lasti = }\n{opname = }")
assert opname == "CALL", opname
print("correct")
@tester
def foo():
pass
print()
print("incorrect")
@deco
def foo():
pass
output (Python 3.11.0rc2+):
correct
frame.f_lasti = 132
opname = 'CALL'
incorrect
frame.f_lasti = 204
opname = 'CACHE'
Traceback (most recent call last):
File "/home/frank/projects/executing/example.py", line 35, in <module>
@deco
^^^^
File "/home/frank/projects/executing/example.py", line 20, in deco
assert opname == "CALL", opname
AssertionError: CACHE
Metadata
Metadata
Assignees
Labels
3.11only security fixesonly security fixes3.12only security fixesonly security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error