Skip to content

Instantly share code, notes, and snippets.

@pauldardeau
Created June 1, 2016 21:04
Show Gist options
  • Select an option

  • Save pauldardeau/ef990e90f9b6286e306093de2dec79d5 to your computer and use it in GitHub Desktop.

Select an option

Save pauldardeau/ef990e90f9b6286e306093de2dec79d5 to your computer and use it in GitHub Desktop.
import sys
source_code = \
"""
def print_message(s):
print(s)
def add_numbers(x,y):
return x + y
def main():
print_message('hello world')
sum = add_numbers(3,4)
print_message('sum of numbers = %s' % str(sum))
if __name__=='__main__':
main()
"""
def instrument(file_name, s):
source_lines = s.splitlines()
instrumented_lines = 'import instrumentation'
instrumented_lines += '\n'
instrumented_lines += '\n'
instrument_line = False
fn_name = ''
for source_line in source_lines:
stripped_source_line = source_line.strip()
if len(stripped_source_line) > 0 and stripped_source_line[0] == '#':
stripped_source_line = ''
if len(stripped_source_line) == 0:
instrumented_lines += source_line
instrumented_lines += '\n'
else:
if instrument_line:
num_whitespace_chars = len(source_line) - len(stripped_source_line)
whitespace = source_line[0:num_whitespace_chars]
injected_line = whitespace
injected_line += "instrumentation.trace_fn('%s','%s','%s')" % (file_name, '', fn_name)
instrumented_lines += injected_line
instrumented_lines += '\n'
instrument_line = False
fn_name = ''
pos_def = stripped_source_line.find('def ')
if pos_def == 0:
instrumented_lines += source_line
instrumented_lines += '\n'
pos_paren = stripped_source_line.find('(')
if pos_paren > 0:
fn_name = stripped_source_line[4:pos_paren]
instrument_line = True
else:
print('error: unable to parse python source')
sys.exit(1)
else:
instrumented_lines += source_line
instrumented_lines += '\n'
return instrumented_lines
def main():
instrumented_code = instrument('example.py', source_code)
print(instrumented_code)
if __name__=='__main__':
main()
class Trace:
def __init__(self, file_name, class_name, method_name):
self.file_name = file_name
self.class_name = class_name
self.method_name = method_name
def to_string(self):
s = 'file=%s, class=%s, method=%s' % (self.file_name, self.class_name, self.method_name)
return s
def file_trace_fn(trace):
pass
def print_trace_fn(trace):
print(trace.to_string())
def trace_fn(file_name, class_name, method_name):
trace = Trace(file_name, class_name, method_name)
print_trace_fn(trace)
file_trace_fn(trace)
@pauldardeau
Copy link
Copy Markdown
Author

python instrument.py > instrumented.py

python instrumented.py
trace_fn: file=example.py, class=, method=main
trace_fn: file=example.py, class=, method=print_message
hello world
trace_fn: file=example.py, class=, method=add_numbers
trace_fn: file=example.py, class=, method=print_message
sum of numbers = 7

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