from types import FunctionType from typing import Callable def func1(pstr: str) -> None: def foo() -> None: print(f"{pstr = }") foo() def shoehorn(f: Callable) -> Callable: code = f.__code__.replace( co_nlocals=2, co_varnames=("pstr", "foo"), ) return FunctionType( name=f.__name__, code=code, globals=func1.__globals__, ) @shoehorn def func2(pstr: str) -> None: foo() def func_info(f: Callable) -> None: print(f"{f.__name__ } = {f}, {f.__code__.co_varnames = }") f("bar") f("baz") if __name__ == "__main__": func_info(func1) func_info(func2) import json print(json.dumps({ name: repr(getattr(func2.__code__, name)) for name in dir(func2.__code__) }, indent=2))