3

I have some function f which calls some library that generates quite a few unnecessary print statements. I cannot simply remove all values printed, as this would make debugging impossible. However there are certain things that are always printed out that I do want to ignore. Say I want to ignore (not display) any lines printed that include a substring 'substring'. Is there a a way to do something along the lines:

def g():
    print('why is this substring being printed')
    return 1
def f():
    print('this should be printed')
    return g()
# now run with magic function
with IgnorePrints(substring='substring'):
    result = f()

Such that if this code is run with IgnorePrints it will only result in:

this should be printed
SuperStormer
  • 4,997
  • 5
  • 25
  • 35
  • 1
    You could replace the `print` function with a function that checks the content of the string before outputting it. – khelwood May 22 '21 at 23:52
  • You could print the statements into a string with `io.StringIO`, or to a file and then use regular expressions to match the lines you want to print. – K D May 22 '21 at 23:58
  • You can invoke the thread as a sub-process. Then the main can intercept and filter `stdout` from that process. See [this question](https://stackoverflow.com/questions/53965917/streaming-read-from-subprocess) for some real-time help. – Prune May 23 '21 at 00:10
  • I should note that the function g is not available or modifiable. – Outstretched Pupil May 23 '21 at 04:09

1 Answers1

4

Using contextlib.redirect_stdout:

import sys
from contextlib import redirect_stdout

class PrintFilter:
    def __init__(self, stream, substring):
        self.stream = stream
        self.substring = substring

    def write(self, txt):
        if self.substring not in txt:
            self.stream.write(txt)


my_filter = PrintFilter(stream=sys.stdout, substring="substring")

with redirect_stdout(my_filter):
    result = f()
wim
  • 338,267
  • 99
  • 616
  • 750