import inspect
import logging
import os
import sys

def srcfile(fname):
    srcfile = fname
    if hasattr(sys, 'frozen'): #support for py2exe
        srcfile = fname
    elif fname.lower()[-4:] in ['.pyc', '.pyo']:
        srcfile = fname[:-4] + '.py'
    return os.path.normcase(srcfile)

class StackLogger(logging.Logger):
    """A logging channel.

    A StackLogger inspects the calling context of a :class:`logging.LogRecord`,
    adding useful information like the class where a method was defined to the
    standard :class:`logging.Formatter` 'funcName' attribute.
    """

    def callingframe(self, frame):
        """Return the first non-logging related frame from *frame*'s stack."""
        # Frames in these files are logging-related and should be skipped.
        logfiles = (logging._srcfile, srcfile(__file__))
        for frame in inspect.getouterframes(frame):
            filename = frame[1]
            if filename not in logfiles:
                return frame

    def framefunc(self, frame):
        """Return a string representation of the code object at *frame*.

        *frame* should be a Python interpreter stack frame with a current code
        object. If the code object is a method, :meth:`framefunc` will try to
        determine the class in which the method was defined.
        """
        rest = frame[1:]
        frame = frame[0]
        name = frame.f_code.co_name
        context = [name]

        # If the first argument to the frame's code is an instance, and that
        # instance has a method with the same name as the frame's code, assume
        # that the code is a method of that instance.
        try:
            instance = frame.f_locals[frame.f_code.co_varnames[0]]
            ismethod = getattr(instance, name, None).im_func.func_code == frame.f_code
        except (AttributeError, IndexError, KeyError):
            instance = None
            ismethod = False

        if instance and ismethod:
            context.insert(0, instance.__class__.__name__)
        return '.'.join(context)

    def makeRecord(self, name, level, fn, lno, msg, 
            args, exc_info, func=None, extra=None):
        """Build and return a :class:`logging.LogRecord`.

        This method inspects the calling stack to add more information to the
        usual :attr:`logging.LogRecord.funcName` attribute.
        """
        rv = logging.Logger.makeRecord(self, name, level, fn, lno, msg, args,
            exc_info, func, extra)
        funcName = rv.funcName
        frame = inspect.currentframe()
        try:
            frame = self.callingframe(frame)
            funcName = self.framefunc(frame)
        finally:
            # Make sure we don't leak a reference to the frame to prevent a
            # reference cycle.
            del(frame)

        rv.funcName = funcName
        return rv

@@ -73,105 +73,191 @@
     
-srcfile = f
+%22%22%22Sanitize a Python module's file
 name
+.%0A
 %0A    
-if hasattr(sys, 'frozen'): #support for py2exe%0A        s
+This function produces filenames similar to :data:%60logging._srcfile%60 and%0A    those returned by :func:%60inspect.getsou
 rc
+e
 file
- = fname
+%60.%0A    %22%22%22
 %0A    
-el
 if f
@@ -281,24 +281,24 @@
  in 
-%5B'
+(%22
 .pyc
-', '
+%22, %22
 .pyo
-'%5D
+%22)
 :%0A  
@@ -303,22 +303,20 @@
         
-srcfil
+fnam
 e = fnam
@@ -320,16 +320,24 @@
 name
+.lower()
 %5B:-4%5D + 
 '.py
@@ -336,13 +336,13 @@
 %5D + 
-'.py'
+%22.py%22
 %0A   
@@ -366,23 +366,38 @@
 ormcase(
-srcfile
+os.path.abspath(fname)
 )%0A%0Aclass

Document and simplify srcfile().