logging: local functions ==> loss of lineno

Peter Otten __peter__ at web.de
Wed Mar 24 05:34:31 EDT 2010


Vinay Sajip wrote:

> Sorry I'm a little late to this discussion. I could add a _findCaller
> function to the module (not part of the public API, but replaceable by
> someone who really needs to) which does the heavy lifting, and
> Logger.findCaller just calls it. Then those who need to can implement
> their own strategy, without needing to jump through hoops. Does that
> approach sound helpful?

You mean you'd have to monkey-patch logging._findCaller() instead of 
overriding logging.Logger.findCaller()? 

I don't see a big advantage in that.

Here's an alternative proposal: simplify findCaller() by moving part of the 
code into a generator:

    def callers(self):
        """
        Walk up the call stack.
        Helper for findCaller().
        """
        f = currentframe()
        #On some versions of IronPython, currentframe() returns None if
        #IronPython isn't run with -X:Frames.
        if f is not None:
            f = f.f_back
        while hasattr(f, "f_code"):
            co = f.f_code
            filename = os.path.normcase(co.co_filename)
            yield filename, f.f_lineno, co.co_name
            f = f.f_back
    
    
    def findCaller(self):
        """
        Find the stack frame of the caller so that we can note the source
        file name, line number and function name.
        """
        for filename, lineno, funcname in self.callers():
            if filename != _srcfile:
                return filename, lineno, funcname
        return UNKNOWN_CALLER

Another simplification might be to have setLoggerClass() implicitly set the 
root logger and to drop the distinct RootLogger class completely. 

Note that I have no strong opinion on all this. If you leave things as is 
I'm fine with that.

Peter



More information about the Python-list mailing list