Search code examples
pythonxlrd

Python xlrd: suppress warning messages


I am using xlrd to process Excel files. I am running a script on a folder that contains many files, and I am printing messages related to the files. However, for each file I run, I get the following xlrd-generated error message as well:

WARNING *** OLE2 inconsistency: SSCS size is 0 but SSAT size is non-zero

Is there a way to suppress this error message, so the CLI will only print the message I want it to?


Solution

  • Check out the relevant part of the xlrd docs. The 2nd arg of the open_workbook function is logfile which should be an open file object or act-alike. All it needs to support is a write method. It defaults to sys.stdout.

    So, something like this (untested) should do the job:

    class MyFilter(object):
        def __init__(self, mylogfile=sys.stdout):
            self.f = mylogfile
        def write(self, data):
            if "WARNING *** OLE2 inconsistency" not in data:
                self.f.write(data)
    
    #start up
    log = open("the_log_file.txt", "w")
    log_filter = MyFilter(log)
    book = xlrd.open_workbook("foo.xls", logfile=log_filter)
    
    # shut down
    log.close()
    # or use a "with" statement
    

    Update in response to answer by @DaniloBargen:

    It's not xlrd that's writing the newline separately, it's the Python print statement/function. This script:

    class FakeFile(object):
        def write(self, data):
            print repr(data)
    
    ff = FakeFile()
    for x in "foo bar baz".split():
        print >> ff, x
    

    produces this output for all Pythons 2.2 to 2.7 both inclusive:

    'foo'
    '\n'
    'bar'
    '\n'
    'baz'
    '\n'
    

    A suitably modernised script (print as a function instead of a statement) produces identical output for 2.6, 2.7, 3.1, 3.2, and 3.3. You can work around this with a more complicated filter class. The following example additionally allows a sequence of phrases to be checked for:

    import sys, glob, xlrd
    
    class MyFilter(object):
        def __init__(self, mylogfile=sys.stdout, skip_list=()):
            self.f = mylogfile
            self.state = 0
            self.skip_list = skip_list
        def write(self, data):
            if self.state == 0:
                found = any(x in data for x in self.skip_list)
                if not found:
                    self.f.write(data)
                    return
                if data[-1] != '\n':
                    self.state = 1
            else:
                if data != '\n':
                    self.f.write(data)
                self.state = 0
    
    logf = open("the_log_file.txt", "w")
    skip_these = (
        "WARNING *** OLE2 inconsistency",
        )
    try:        
        log_filter = MyFilter(logf, skip_these)
        for fname in glob.glob(sys.argv[1]):
            logf.write("=== %s ===\n" % fname)
            book = xlrd.open_workbook(fname, logfile=log_filter)
    finally:
        logf.close()