Issue #10093: ResourceWarnings are now issued when files and sockets are
deallocated without explicit closing. These warnings are silenced by
default, except in pydebug mode.
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index 8784e34..7ce9753 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -29,6 +29,7 @@
import abc
import signal
import errno
+import warnings
from itertools import cycle, count
from collections import deque
from test import support
@@ -2525,6 +2526,46 @@
# baseline "io" module.
self._check_abc_inheritance(io)
+ def _check_warn_on_dealloc(self, *args, **kwargs):
+ f = open(*args, **kwargs)
+ r = repr(f)
+ with self.assertWarns(ResourceWarning) as cm:
+ f = None
+ support.gc_collect()
+ self.assertIn(r, str(cm.warning.args[0]))
+
+ def test_warn_on_dealloc(self):
+ self._check_warn_on_dealloc(support.TESTFN, "wb", buffering=0)
+ self._check_warn_on_dealloc(support.TESTFN, "wb")
+ self._check_warn_on_dealloc(support.TESTFN, "w")
+
+ def _check_warn_on_dealloc_fd(self, *args, **kwargs):
+ fds = []
+ try:
+ r, w = os.pipe()
+ fds += r, w
+ self._check_warn_on_dealloc(r, *args, **kwargs)
+ # When using closefd=False, there's no warning
+ r, w = os.pipe()
+ fds += r, w
+ with warnings.catch_warnings(record=True) as recorded:
+ open(r, *args, closefd=False, **kwargs)
+ support.gc_collect()
+ self.assertEqual(recorded, [])
+ finally:
+ for fd in fds:
+ try:
+ os.close(fd)
+ except EnvironmentError as e:
+ if e.errno != errno.EBADF:
+ raise
+
+ def test_warn_on_dealloc_fd(self):
+ self._check_warn_on_dealloc_fd("rb", buffering=0)
+ self._check_warn_on_dealloc_fd("rb")
+ self._check_warn_on_dealloc_fd("r")
+
+
class CMiscIOTest(MiscIOTest):
io = io
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 699efc0..e20364d 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -706,6 +706,23 @@
def test_sendall_interrupted_with_timeout(self):
self.check_sendall_interrupted(True)
+ def test_dealloc_warn(self):
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ r = repr(sock)
+ with self.assertWarns(ResourceWarning) as cm:
+ sock = None
+ support.gc_collect()
+ self.assertIn(r, str(cm.warning.args[0]))
+ # An open socket file object gets dereferenced after the socket
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ f = sock.makefile('rb')
+ r = repr(sock)
+ sock = None
+ support.gc_collect()
+ with self.assertWarns(ResourceWarning):
+ f = None
+ support.gc_collect()
+
@unittest.skipUnless(thread, 'Threading required for this test.')
class BasicTCPTest(SocketConnectedTest):