Skip to content

Commit

Permalink
instr: allow LOAD_FAST to refer to FreeVar in Python 3.13
Browse files Browse the repository at this point in the history
  • Loading branch information
MatthieuDartiailh committed Oct 17, 2024
1 parent b14092a commit 4fb730f
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 3 deletions.
9 changes: 7 additions & 2 deletions src/bytecode/concrete.py
Original file line number Diff line number Diff line change
Expand Up @@ -989,9 +989,11 @@ def to_bytecode(
cells_lookup = [CellVar(n) for n in self.cellvars]

# In Python 3.13+ LOAD_FAST can be used to retrieve cell values
locals_lookup: Sequence[Union[str, CellVar]]
locals_lookup: Sequence[Union[str, CellVar, FreeVar]]
if PY313:
locals_lookup = cells_lookup
locals_lookup = cells_lookup + [
FreeVar(n) for n in self.freevars if n not in self.varnames
]
else:
locals_lookup = self.varnames

Expand Down Expand Up @@ -1282,6 +1284,9 @@ def concrete_instructions(self) -> None:
elif PY313 and isinstance(arg, CellVar):
cell_instrs.append(len(self.instructions))
arg = self.bytecode.cellvars.index(arg.name)
elif PY313 and isinstance(arg, FreeVar):
free_instrs.append(len(self.instructions))
arg = self.bytecode.freevars.index(arg.name)
else:
assert isinstance(arg, str)
arg = self.add(self.varnames, arg)
Expand Down
6 changes: 5 additions & 1 deletion src/bytecode/instr.py
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,11 @@ def _check_arg(self, name: str, opcode: int, arg: InstrArg) -> None:
"got %s (value=%s)" % (name, type(arg).__name__, str(arg))
)

elif PY313 and opcode in _opcode.haslocal and isinstance(arg, CellVar):
elif (
PY313
and opcode in _opcode.haslocal
and isinstance(arg, (CellVar, FreeVar))
):
# Cell vars can be accessed using locals in Python 3.13+
pass

Expand Down

0 comments on commit 4fb730f

Please sign in to comment.