Skip to content

Instantly share code, notes, and snippets.

@vsajip
Created June 18, 2013 13:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vsajip/5805215 to your computer and use it in GitHub Desktop.
Save vsajip/5805215 to your computer and use it in GitHub Desktop.
Better warning diagnostics in unit tests
WARNING py.warnings reswarn.py:54: ResourceWarning: unclosed file <_io.TextIOWrapper name='/tmp/scratch/tmp.txt' mode='w' encoding='UTF-8'>
subsubfunc()
Stack (most recent call last):
File "reswarn.py", line 76, in <module>
unittest.main()
File "/usr/lib/python3.2/unittest/main.py", line 124, in __init__
self.runTests()
File "/usr/lib/python3.2/unittest/main.py", line 270, in runTests
self.result = testRunner.run(self.test)
File "/usr/lib/python3.2/unittest/runner.py", line 168, in run
test(result)
File "/usr/lib/python3.2/unittest/suite.py", line 67, in __call__
return self.run(*args, **kwds)
File "/usr/lib/python3.2/unittest/suite.py", line 105, in run
test(result)
File "/usr/lib/python3.2/unittest/suite.py", line 67, in __call__
return self.run(*args, **kwds)
File "/usr/lib/python3.2/unittest/suite.py", line 105, in run
test(result)
File "/usr/lib/python3.2/unittest/case.py", line 477, in __call__
return self.run(*args, **kwds)
File "/usr/lib/python3.2/unittest/case.py", line 425, in run
self._executeTestPart(testMethod, outcome, isTest=True)
File "/usr/lib/python3.2/unittest/case.py", line 370, in _executeTestPart
function()
File "reswarn.py", line 70, in test_basic
func()
File "reswarn.py", line 57, in func
subfunc()
File "reswarn.py", line 54, in subfunc
subsubfunc()
File "reswarn.py", line 28, in _showwarning
logger.warning("%s", s, stack_info=1)
import logging
import sys
import unittest
import warnings
#
# The following code is copied from logging/__init__.py. The only real change
# is to add stack_info=1 to the logger.warning() call.
#
_warnings_showwarning = None
def _showwarning(message, category, filename, lineno, file=None, line=None):
"""
Implementation of showwarnings which redirects to logging, which will first
check to see if the file parameter is None. If a file is specified, it will
delegate to the original warnings implementation of showwarning. Otherwise,
it will call warnings.formatwarning and will log the resulting string to a
warnings logger named "py.warnings" with level logging.WARNING.
"""
if file is not None:
if _warnings_showwarning is not None:
_warnings_showwarning(message, category, filename, lineno, file, line)
else:
s = warnings.formatwarning(message, category, filename, lineno, line)
logger = logging.getLogger("py.warnings")
if not logger.handlers:
logger.addHandler(logging.NullHandler())
logger.warning("%s", s, stack_info=1)
def captureWarnings(capture):
"""
If capture is true, redirect all warnings to the logging package.
If capture is False, ensure that warnings are not redirected to logging
but to their original destinations.
"""
global _warnings_showwarning
if capture:
if _warnings_showwarning is None:
_warnings_showwarning = warnings.showwarning
warnings.showwarning = _showwarning
else:
if _warnings_showwarning is not None:
warnings.showwarning = _warnings_showwarning
_warnings_showwarning = None
#
# end of code copied from logging.
#
def subsubfunc():
f = open('/tmp/scratch/tmp.txt', 'w')
def subfunc():
subsubfunc()
def func():
subfunc()
class TestCase(unittest.TestCase):
def setUp(self):
self.saved_filters = warnings.filters
warnings.resetwarnings()
captureWarnings(True)
def tearDown(self):
captureWarnings(False)
warnings.filters = self.saved_filters
def test_basic(self):
func()
if __name__ == '__main__':
logging.basicConfig(filename='reswarn.log', filemode='w',
format='%(levelname)-8s %(name)s %(message)s')
unittest.main()
sys.exit(rc)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment