[Python-Dev] Re: PEP 282 comments

Kevin Butler kbutler@campuspipeline.com
Fri, 22 Mar 2002 10:29:27 -0700


[Guido]
 > Here's another way to look at it.  To support the base functionality,
 > we need an X amount of code.  To add the feature of logging exceptions
 > at any level, we would need an additional Y amount.  The number Y is
 > much smaller than X, but not insignificant.  If the size of a subclass
 > that adds that feature is approximately equal to Y, I think it should
 > be kept out of the base class in this case, because you can easily
 > write that subclass for Zope.  If writing such a subclass would
 > require significantly more code than Y (the amount of code needed to
 > integrate it directly into the base class), I agree that the base
 > class needs to be reworked to make this easier to add, or even to
 > support it outright.  But I find that hard to believe in this case.

I quite like this standard in general.

Then I applied it to adding the **kwargs for exc_info to Vinay's logging 
module 0.4,
and found that adding **kwargs to the convenience methods saved 143 
bytes compared
to the 0.4 implementation with its single "logException" method.

Each convenience method:

    def fatal(self, msg, *args):
        """
        Log 'msg % args' with severity 'FATAL'.
        """
        if self.manager.disable >= FATAL:
            return
        if FATAL >= self.getChainedPriority():
            self._log(FATAL, msg, args, None)

gets **kwargs and replaces the final "None" with **kwargs:

    def fatal(self, msg, *args, **kwargs):
...
            self._log(FATAL, msg, args, **kwargs)

logException goes away, taking its "sore thumb" name & usage with it.

My experience suggests we use Vinay's exception( lvl, msg, *args )
to automagically call sys.exc_info() at different log levels, but including
that change skews the results because of Vinay's shorter comment.  :-)

The signature of _log changes from:

    def _log(self, lvl, msg, args, exc_info):

to:

    def _log(self, lvl, msg, args, exc_info=None):

Simple usage & test cases work exactly as they did before,
plus Jeremy & I are very happy with our "advanced" applications,
and the "simple subclass" now just needs to override _log to do
advanced things with other optional arguments.

If you can provide a simple standard that supports both simple
and advanced applications with equal facility, and you can save
code by doing it without sacrificing readability, why in the world would
you want to require multiple users to add subclasses that just duplicate
the standard library methods with such a slight change?

[Guido]
"/The joy of coding Python should be in seeing short, concise, readable
classes that express a lot of action in a small amount of clear code --
not in reams of trivial code that bores the reader to death./"

:-)

kb

PS. Adding the straightforward subclass LoggerX to provide the functionality
adds an extra 1.5K of code, all of it (except those negative 143 bytes) 
copied
directly from Logger.

Duplication of code is evil.