it is possible to monkeypatch a local variable introduced in a function body?
This is not possible as the variable does not exist ahead of time and py.test cannot hook into the creation of a local variable as far as i know.
With a little care, it would be possible to patch the consts in the function code object using ctypes.
import ctypes
from contextlib import contextmanager
def tuple_setitem(tup, index, item):
obj = ctypes.py_object(tup)
item = ctypes.py_object(item)
ref_count = ctypes.c_long.from_address(id(tup))
original_count = ref_count.value
if original_count != 1:
ref_count.value = 1
ctypes.pythonapi.Py_IncRef(item)
ctypes.pythonapi.PyTuple_SetItem(obj, ctypes.c_ssize_t(index), item)
ref_count.value = original_count
@contextmanager
def patch_tuple_item(tup, index, item):
old = tup[index]
try:
tuple_setitem(tup, index, item)
yield
finally:
tuple_setitem(tup, index, old)
Demo:
>>> def my_method():
... my_var = "foo"
... return my_var[:2]
...
>>> consts = my_method.__code__.co_consts
>>> consts
(None, 'foo', 2)
>>> with patch_tuple_item(consts, index=1, item="bar"):
... print(my_method())
...
ba
>>> print(my_method())
fo