Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Patching Python code at runtime

A rather dirty way to patch module code at runtime.

import b
class A(object):
def call_to_b(self, s):
myb = b.B()
myb.fn(s)
class B(object):
def fn(self, s):
"""This function needs to be patched.
"""
print s
import inspect
import textwrap
# `A` uses `B` and we want `B` to be altered
import b
b_B_fn_source = inspect.getsource(b.B.fn)
# Alternatively, can use getsourcelines to get an array of lines
b_B_fn_source = textwrap.dedent(b_B_fn_source)
# Make sure the source looks as we expect it to
assert('print s' in b_B_fn_source)
# Patch the code
b_B_fn_source = b_B_fn_source.replace('def fn(', 'def patched_fn(')
b_B_fn_source = b_B_fn_source.replace('print s', 'print "patched", s')
# This creates the function `patched_fn`
exec(b_B_fn_source)
# Replace the original function
b.B.fn = patched_fn
# Now module `a` will use the patched code
import a
my_a = a.A()
my_a.call_to_b('ohhi')
# expect: >>> patched ohhi
@alexandernst
Copy link

alexandernst commented Jun 16, 2018

Note that this won't work with magic methods (methods that start with __)

@CNG
Copy link

CNG commented Apr 28, 2019

Thanks for this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment