Skip to content

Instantly share code, notes, and snippets.

@adam-p
Created October 1, 2014 13:50
Show Gist options
  • Select an option

  • Save adam-p/63aaae093a71a844150e to your computer and use it in GitHub Desktop.

Select an option

Save adam-p/63aaae093a71a844150e to your computer and use it in GitHub Desktop.
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
Copy Markdown

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

@CNG

CNG commented Apr 28, 2019

Copy link
Copy Markdown

Thanks for this!

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