[issue23010] "unclosed file" warning when defining unused logging FileHandler in dictConfig
Walter Doekes
report at bugs.python.org
Tue Dec 9 09:10:03 CET 2014
Walter Doekes added the comment:
> The handlers are AFAIK referenced - if you peek at logging._handlerList or logging._handlers you should see them in there.
Aha. But that's the point. They aren't. If they were, I wouldn't have any problems with this. But I have this problem because the warnings are generated at startup of my program, not at cleanup.
Look at this:
$ PYTHONWARNINGS=default python3 problem.py 2>&1 | sed -e 's/^/ /'
2014-12-09 08:58:45.982258: starting
2014-12-09 08:58:46.011788: after dictconfig
/usr/lib/python3.4/importlib/_bootstrap.py:321: ResourceWarning: unclosed file <_io.FileIO name='/tmp/debug.log' mode='ab'>
return f(*args, **kwds)
imported once
2014-12-09 08:58:46.019327: after error
2014-12-09 08:58:51.024376: after sleep
_handlerList: []
_handlers: []
If what you say is true, the following wouldn't be:
- _handlerList is non-empty (wrong, see above)
- the warning would be generated at application shutdown (no, it's generated at importlib time, see the timestamps)
(See source below.)
> You could just leave out the handlers, since you're never using them; it's not logging's job to be overly restrictive about this sort of thing.
I could agree with you there. But in that case I still think we should call it illegal (and perhaps raise a more sensible warning).
Obviously you spot the problem immediately in my toy example. But in a large LOGGING dictionary, items may be shuffled around and changed. When that happens, and these warnings turn up out of the blue, that's distracting to put it mildly.
I expect that you'll reconsider your strict opinion after seeing that logging._handlers is indeed empty and the handlers are not referenced (and therefore should have been destroyed properly or not created at all).
Cheers,
Walter
Example source:
$ cat problem.py | sed -e 's/^/ /'
from datetime import datetime
from time import sleep
import sys
if __name__ == '__main__':
LOGGING = {
'version': 1,
'handlers': {
'logfile': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': '/tmp/debug.log',
},
},
}
print('%s: starting' % (datetime.now(),))
from logging.config import dictConfig
dictConfig(LOGGING)
print('%s: after dictconfig' % (datetime.now(),))
sys.stdout.flush()
# using importlib on a new file triggers the warnings
import importlib, shutil, os
shutil.copy(__file__, __file__ + '.new')
os.unlink(__file__)
os.rename(__file__ + '.new', __file__)
importlib.import_module('problem')
sys.stderr.flush()
print('%s: after error' % (datetime.now(),))
sys.stdout.flush()
sleep(5)
print('%s: after sleep' % (datetime.now(),))
# Vinay Sajip wrote:
# > The handlers are AFAIK referenced - if you peek at
# logging._handlerList or logging._handlers you should see them in
# there.
from logging import _handlerList, _handlers
print('_handlerList:', _handlerList)
print('_handlers:', [i for i in _handlers.values()])
else:
print('imported once')
----------
_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue23010>
_______________________________________
More information about the Python-bugs-list
mailing list