[Python-Dev] PEP282 and the warnings framework

Vinay Sajip vinay_sajip@red-dove.com
Thu, 16 May 2002 00:35:49 +0100

I've got some comments on Walter's suggestion and the various posts
responding to it. Most recently, both Holger Krekel and Kevin Butler have
made what I think of as reasonable comments. FWIW here are my thoughts:

A call to the logging API is essentially a statement by the developer about
an "event of interest". The difference between Walter's idea and the current
state of PEP282 (and my logging module) focuses on two points of interest:
"what happened?" and "how important is it?". In both cases, the "what
happened?" part is codified by a message (e.g. "disk full"). The "how
important is it?" part is codified in the case of PEP282/logging.py by an
integer, and in the case of Walter's idea by a class. This, as I see it, is
the core difference.

Given that an implementation already exists and is in use by quite a few
people, I don't think it's right to make changes of a fundamental nature
which would require users to rewrite their code, unless the reason is a
*really* good one. (the module is still in an "alpha" stage so I am not dead
against making changes of this type; I just need to know what the
justification is).

So far, I am not sure what benefit switching from the status quo of
integer-based levels to class-based levels will give. Certainly, the idea of
relative levels of importance of events must be preserved, since
severity-based filtering is a key function of logging. This could be in
theory be done using the inheritance hierarchy of message classes, but I
don't think this is particularly elegant here (though it's fine in "except"
clauses). And why bother, when integers do the job quite well? And if you
use some level attribute in message classes, what has really been gained by
using classes? There is also sometimes a possibility that a user-defined
handler or filter might, based on the application context and the
configuration selected by a developer, choose to change the severity of an
event dynamically. This is fine with integers, less so with classes. (I know
you can change the class of an instance dynamically, but I'm sure that
instances of assignments to __class__ should not be multiplied beyond
necessity. Other approaches such as wrapping exceptions are also possible,
but in many cases would just obscure the developer's intention, and seeming
like trying to "get around the system".)

It's not clear to me that class-based levels are a benefit over
integer-based levels. The existing implementation, using integer-based
levels, seems to offer all the flexibility mentioned by Holger in his post.
For example, expensive formatting operations are deferred until (and only
if) needed. Factory methods are in place where necessary to facilitate
creating user-defined Loggers, Handlers, Filters and LogRecords (the
analogue of the Message class). The present design also makes it much easier
for users to define their own levels, which can completely slot in and
replace the default levels provided (these are based on log4j's experience
and strongly recommended, but sometimes users just have to go their own
way - I don't like to be too prescriptive in this kind of area).

One more limitation of the class-based level idea surfaces from considering
how Python applications play in the wider world. Integer levels map quite
easily to Unix syslog, NT event log levels, etc. etc. It's easier to pickle
logging events and send them to a remote audience if they're integer based,
so you don't need a guarantee that the receiving system has the same classes
loaded as the sending system. You can send logging events to non-Python SOAP
and HTTP receivers which may not be able to deal with severities in terms of
classes. Why, you could even interoperate with log4j! Certainly in the
heterogeneous corporate world, interoperability is very important beyond the
language level. We don't want to put roadblocks to interoperability which
force developers to roll their own solutions.

In log4j, levels *are* classes, but they are not used in the same way as
Walter/Holger have advocated - they are not part of the exception hierarchy,
nor are they treated analogously.

So, while not wishing to sound abrupt, and respectful of the sentiments
which led Walter to make his suggestion, I say -1 invoking KISS, YAGNI and
inconvenience to existing users. I discussed with Trent Mick the gist of my
argument, and he is in broad agreement with the views expressed above.