Codefind
Codefind is a Python library (current version 0.1.7) designed for advanced code introspection, allowing users to find and manipulate code objects and their referents. It can locate code objects by filename and qualified name, identify all functions sharing a specific code object, and even modify the code of functions. This utility is notably used by the `jurigged` project for dynamic code updates. It maintains an active development status with regular, though not strictly scheduled, patch releases.
Warnings
- gotcha When using `find_code`, specifying `filename=__file__` or `module=__module__` is often critical, especially for finding functions defined in the current script or module. Without these, the search scope might be incorrect, leading to `None` being returned or incorrect code objects being found.
- breaking As a low-level introspection library currently in pre-1.0 development, `codefind`'s API is subject to change. Major breaking changes, including renaming or alteration of core functions (`find_code`, `get_functions`, `conform`), could occur in future minor or patch releases without extensive deprecation cycles.
- gotcha Modifying live code objects (e.g., using `conform`) can have significant and often unpredictable side effects, particularly in complex applications, multi-threaded environments, or long-running processes. This can lead to difficult-to-debug issues, unexpected behavior, or even crashes.
Install
-
pip install codefind
Imports
- find_code
from codefind import find_code
- get_functions
from codefind import get_functions
- conform
from codefind import conform
Quickstart
from codefind import find_code, get_functions, conform
def f(x): return x + x
def adder(x):
def f(y): return x + y
return f
add1 = adder(1)
add2 = adder(2)
add3 = adder(3)
# Find a code object
found_f_code = find_code("f", filename=__file__)
print(f"Code object for f: {found_f_code == f.__code__}")
# Find closure code
found_adder_f_code = find_code("adder", "f", filename=__file__)
print(f"Code object for adder's inner f: {found_adder_f_code == add1.__code__}")
# Get all functions using a code object
functions_with_add1_code = set(get_functions(add1.__code__))
print(f"Functions sharing add1's code: {functions_with_add1_code == {add1, add2, add3}}")
# Dynamically conform function code
def g(x): return x * x
print(f"f(5) before conform: {f(5)}")
conform(f, g)
print(f"f(5) after conform to g: {f(5)}")