classification
Title: logging.basicConfig(level='DEBUG', ... and setLevel("DEBUG") result in no logging
Type: behavior Stage: patch review
Components: Library (Lib) Versions: Python 3.1, Python 3.2, Python 2.7, Python 2.6
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: vinay.sajip Nosy List: alexl, r.david.murray, vinay.sajip
Priority: normal Keywords: patch

Created on 2009-06-20 04:58 by alexl, last changed 2009-07-30 07:29 by vinay.sajip. This issue is now closed.

Files
File name Uploaded Description Edit
issue6314.patch r.david.murray, 2009-07-06 17:41
Messages (6)
msg89536 - (view) Author: alexl (alexl) Date: 2009-06-20 04:58
The following code runs w/o exceptions, but log file is empty:

import logging
logging.basicConfig(level='DEBUG', filename='log.txt')
logging.info('Oh hi!')

To avoid such silent error, basicConfig must either throw exception on 
invalid level parameter, or accept string values.
msg89569 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2009-06-21 17:58
Fix checked into trunk and py3k.
msg90184 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2009-07-06 17:41
There is still a problem here, though not something a typical user would
run into:

rdmurray@partner:~/python/trunk>./python
Python 2.7a0 (trunk:73845M, Jul  4 2009, 12:43:10)
[GCC 4.1.2 (Gentoo 4.1.2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import logging
>>> logging.basicConfig(level=object())
>>> logging.info("test")

However, I've expanded the title to cover a second way this bug can be
encountered that is more likely to bite someone (and thus I am reopening
it):

Python 2.7a0 (trunk:73845M, Jul  4 2009, 12:43:10) 
[GCC 4.1.2 (Gentoo 4.1.2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import logging
>>> logging.basicConfig(level=logging.DEBUG)
>>> logging.info('test')
INFO:root:test
>>> logging.getLogger().setLevel("DEBUG")
>>> logging.info('test')

Neither one of these is a problem in 3.x in the sense that if you pass a
string argument under 3.x, the result is not silence:

Python 3.2a0 (py3k:73867M, Jul  6 2009, 12:52:11) 
[GCC 4.1.2 (Gentoo 4.1.2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import logging
>>> logging.basicConfig(level=object())
>>> logging.info("foo")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/rdmurray/python/py3k/Lib/logging/__init__.py", line 1471,
in info
    root.info(msg, *args, **kwargs)
  File "/home/rdmurray/python/py3k/Lib/logging/__init__.py", line 1045,
in info
    if self.isEnabledFor(INFO):
  File "/home/rdmurray/python/py3k/Lib/logging/__init__.py", line 1236,
in isEnabledFor
    return level >= self.getEffectiveLevel()
TypeError: unorderable types: int() >= object()

However, it seems like it would be much better even in the 3.x case to
have the error occur when the level is set rather than when it is used.

To fix this bug I think setLevel should do a type check.  Log already
does a type check (isintance(level, int)), so that's what I think
setLevel should do.  One could alternatively enhance the logging API to
have setLevel accept a string.  That, however, is an enhancement and not
a bugfix, IMO.

I've included a patch that adds the isinstance check, and tests for
same, and reverts the basicConfig change.  Vinay, if you'd rather have
the level-name-lookup enhancement I'd be happy to do it and also do the
doc update, but I don't think the enhancement bits should be backported
to 2.6 or 3.1 so I would do it as a separate patch.

Oh, and one last note: I didn't do the raiseExceptions test in setLevel
the way 'log' does because I figure an error at the config level should
not be suppressed...but raiseExceptions doesn't seem to be documented
(at least, I couldn't find it) so I'm not sure if that's the right thing
to do.
msg90214 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2009-07-07 07:09
The change that I made was in the wrong place - it should have been in
the setLevel rather than in basicConfig itself. However, this would not
have covered setLevel for Handlers...

That setLevel behaves differently to basicConfig for the level argument
could be seen as a bug. ISTM I should add a function _checkLevel as follows:

def _checkLevel(level):
    if isinstance(level, int):
        rv = level
    elif str(level) == level:
        if level not in _levelNames:
            raise ValueError("Unknown level: %r" % level)
        rv = _levelNames[level]
    else:
        raise TypeError("Level not an integer or a valid string: %r" %
level)
    return rv


and then have all setLevel(level) methods do a "level =
_checkLevel(level)" before actually setting the level.
msg90477 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2009-07-13 11:29
Fixed checked into trunk & py3k as per msg90214.
msg91086 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2009-07-30 07:29
No feedback, closing.
History
Date User Action Args
2009-07-30 07:29:01vinay.sajipsetstatus: pending -> closed

messages: + msg91086
2009-07-13 11:29:40vinay.sajipsetstatus: open -> pending
resolution: fixed
messages: + msg90477
2009-07-07 07:09:59vinay.sajipsetmessages: + msg90214
2009-07-06 17:41:36r.david.murraysetstatus: closed -> open
files: + issue6314.patch


keywords: + patch
stage: patch review
title: logging.basicConfig(level='DEBUG', ... -> logging.basicConfig(level='DEBUG', ... and setLevel("DEBUG") result in no logging
nosy: + r.david.murray
versions: + Python 2.6, Python 2.7, Python 3.2
messages: + msg90184
priority: normal
resolution: fixed -> (no value)
2009-06-21 17:58:14vinay.sajipsetstatus: open -> closed
resolution: fixed
messages: + msg89569
2009-06-20 13:43:26benjamin.petersonsetassignee: vinay.sajip

nosy: + vinay.sajip
2009-06-20 04:58:47alexlcreate