Convert Python 3 ResourceWarnings to Exception

Is there a way to make Python 3 unittest crash, and not just display a warning on stderr if it calls any resource?

I tried the following:

import warnings warnings.simplefilter(action='error', category=ResourceWarning) 

The result of this result is unittest:

 my_test (__main__.MyTest) ... Exception ignored in: <socket.socket fd=9, family=AddressFamily.AF_INET, type=SocketType.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 54065), raddr=('127.0.0.1', 27017)> ResourceWarning: unclosed <socket.socket fd=9, family=AddressFamily.AF_INET, type=SocketType.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 54065), raddr=('127.0.0.1', 27017)> ok ---------------------------------------------------------------------- Ran 1 test in 0.110s 

Note the message "Exception ignored." I would prefer that the test fail, rather than requiring me to read its output in search of ResourceWarnings.

+7
python
source share
2 answers

Here's a unit test that fails if ResourceWarning generated by code in the with catch_warning() :

 #!/usr/bin/env python3 import gc import socket import unittest import warnings class Test(unittest.TestCase): def test_resource_warning(self): s = socket.socket() ####s.close() #XXX uncomment to pass the test # generate resource warning when s is deleted with warnings.catch_warnings(record=True) as w: warnings.resetwarnings() # clear all filters warnings.simplefilter('ignore') # ignore all warnings.simplefilter('always', ResourceWarning) # add filter del s # remove reference gc.collect() # run garbage collection (for pypy3) self.assertFalse(w and str(w[-1])) # test fails if there # are warnings if __name__=="__main__": unittest.main() 
+6
source share

Unfortunately, this is not possible. This โ€œException is ignored in:โ€ message is created by the CPython PyErr_WriteUnraisable function in Python/errors.c . The comment before this function reads:

 /* Call when an exception has occurred but there is no way for Python to handle it. Examples: exception in __del__ or during GC. */ 

ResourceWarning indeed generated during garbage collection, and Python displays a message because it has no way to throw an exception at this point. This is due to the core implementation of CPython, and there is nothing unittest can do to override it.

Update: while the above is the correct technical analysis, there is another approach that will actually solve the OP problem. For more information, see J. F. Sebastian.

+4
source share

All Articles