Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you find where a print statement is located?

I have a program depending on a large code base that prints a lot of irrelevant and annoying messages. I would like to clean them up a bit, but since their content is dynamically generated, I can't just grep for them.

Is there a way to place a hook on the print statement? (I use python 2.4, but I would be interested in results for any version). Is there another way to find from which "print" statement the output comes?

like image 593
static_rtti Avatar asked Dec 27 '22 14:12

static_rtti


2 Answers

For CPython2.5 or older:

import sys
import inspect
import collections
_stdout = sys.stdout

Record = collections.namedtuple(
    'Record',
    'frame filename line_number function_name lines index')

class MyStream(object):
    def __init__(self, target):
        self.target = target
    def write(self, text):
        if text.strip():
            record = Record(*inspect.getouterframes(inspect.currentframe())[1])        
            self.target.write(
                '{f} {n}: '.format(f = record.filename, n = record.line_number))
        self.target.write(text)

sys.stdout = MyStream(sys.stdout)

def foo():
    print('Hi')

foo()

yields

/home/unutbu/pybin/test.py 20: Hi

For CPython2.6+ we can import the print function with

from __future__ import print_function

and then redirect it as we wish:

from __future__ import print_function
import sys
import inspect
import collections

Record = collections.namedtuple(
    'Record',
    'frame filename line_number function_name lines index')

def myprint(text):
    if text.strip():
        record = Record(*inspect.getouterframes(inspect.currentframe())[1])        
        sys.stdout.write('{f} {n}: '.format(f = record.filename, n = record.line_number))
    sys.stdout.write(text + '\n')

def foo():
    print('Hi')

print = myprint
foo()

Note that inspect.currentframe uses sys._getframe which is not part of all implementations of Python. So the solution above may only work for CPython.

like image 60
unutbu Avatar answered Dec 31 '22 13:12

unutbu


Strictly speaking, code base that you depend on, as in libraries, shouldn't contain any print statements. So, you should really just remove all of them.

Other than that, you can monkey-patch stdout: Adding a datetime stamp to Python print

like image 40
Deestan Avatar answered Dec 31 '22 12:12

Deestan