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