Patchy
Patchy is a Python library that allows patching the inner source code of Python functions at runtime. Unlike traditional monkey patching, which replaces function objects, Patchy modifies the function's `__code__` attribute, ensuring that all references to the function (even those imported elsewhere) reflect the new behavior. It achieves this by using the standard `patch` command-line utility to apply diffs to the function's source code. The current version is 2.10.0, and it generally follows a release cadence tied to bug fixes and feature enhancements, compatible with Python 3.9 to 3.14.
Warnings
- gotcha Patches are applied against the function's source code string. Any change to the original function, even adding a comment or reformatting, can cause the patch to fail due to context lines no longer matching. This will raise a `ValueError`.
- gotcha The `patch_text` argument needs careful formatting. It must be a triple-quoted string that starts with a backslash (e.g., `"""\ ...""")`) to correctly `textwrap.dedent()` the patch content without removing leading whitespace that is part of the patch.
- gotcha Patchy works by writing the function's source to a temporary file, calling the external `patch` command-line utility, recompiling the new source, and replacing the function's code object. This process can be relatively slow and introduces a dependency on an external system utility.
- gotcha Patchy is designed for patching the *source of python functions*. It does not support broader patching operations like file renaming, creation, removal, or complex directory tree operations, which some other patching tools might handle. Its scope is specifically limited to modifying existing function bodies.
Install
-
pip install patchy
Imports
- patch
import patchy def my_func(): return 1 patchy.patch(my_func, """\ def my_func(): - return 1 + return 9001 """)
Quickstart
import patchy
def sample():
return 1
print(f"Original output: {sample()}")
# Apply a patch to change the function's behavior
patchy.patch(
sample,
"""\
def sample():
- return 1
+ return 9001
""",
)
print(f"Patched output: {sample()}")