Created
June 18, 2013 13:11
-
-
Save vsajip/5805215 to your computer and use it in GitHub Desktop.
Better warning diagnostics in unit tests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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