summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2014-06-27 21:57:19 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2014-06-27 21:57:19 (GMT)
commita81088ae129f251ad4d1c2cb208ffd2e8d52ea4a (patch)
tree15831806e742293faad56b1b3c880d1293cf2a4c
parentc3bc856f426d8c182b4ecbdf584717e27389c505 (diff)
parent4d4c69dc35154a9c21fed1b6b4088e741fbc6ae6 (diff)
downloadcpython-a81088ae129f251ad4d1c2cb208ffd2e8d52ea4a.zip
cpython-a81088ae129f251ad4d1c2cb208ffd2e8d52ea4a.tar.gz
cpython-a81088ae129f251ad4d1c2cb208ffd2e8d52ea4a.tar.bz2
(Merge 3.4) Issue #11453: asyncore: emit a ResourceWarning when an unclosed
file_wrapper object is destroyed. The destructor now closes the file if needed. The close() method can now be called twice: the second call does nothing.
-rw-r--r--Lib/asyncore.py8
-rw-r--r--Lib/test/test_asyncore.py16
-rw-r--r--Misc/NEWS4
3 files changed, 28 insertions, 0 deletions
diff --git a/Lib/asyncore.py b/Lib/asyncore.py
index 37efa9b..b2ee278 100644
--- a/Lib/asyncore.py
+++ b/Lib/asyncore.py
@@ -600,6 +600,11 @@ if os.name == 'posix':
def __init__(self, fd):
self.fd = os.dup(fd)
+ def __del__(self):
+ if self.fd >= 0:
+ warnings.warn("unclosed file %r" % self, ResourceWarning)
+ self.close()
+
def recv(self, *args):
return os.read(self.fd, *args)
@@ -618,7 +623,10 @@ if os.name == 'posix':
write = send
def close(self):
+ if self.fd < 0:
+ return
os.close(self.fd)
+ self.fd = -1
def fileno(self):
return self.fd
diff --git a/Lib/test/test_asyncore.py b/Lib/test/test_asyncore.py
index ef02c33..b4f474f 100644
--- a/Lib/test/test_asyncore.py
+++ b/Lib/test/test_asyncore.py
@@ -413,6 +413,22 @@ class FileWrapperTest(unittest.TestCase):
asyncore.loop(timeout=0.01, use_poll=True, count=2)
self.assertEqual(b"".join(data), self.d)
+ def test_resource_warning(self):
+ # Issue #11453
+ fd = os.open(support.TESTFN, os.O_RDONLY)
+ f = asyncore.file_wrapper(fd)
+ with support.check_warnings(('', ResourceWarning)):
+ f = None
+ support.gc_collect()
+
+ def test_close_twice(self):
+ fd = os.open(support.TESTFN, os.O_RDONLY)
+ f = asyncore.file_wrapper(fd)
+ f.close()
+ self.assertEqual(f.fd, -1)
+ # calling close twice should not fail
+ f.close()
+
class BaseTestHandler(asyncore.dispatcher):
diff --git a/Misc/NEWS b/Misc/NEWS
index ae99bec..f41ac62 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -103,6 +103,10 @@ Core and Builtins
Library
-------
+- Issue #11453: asyncore: emit a ResourceWarning when an unclosed file_wrapper
+ object is destroyed. The destructor now closes the file if needed. The
+ close() method can now be called twice: the second call does nothing.
+
- Issue #21858: Better handling of Python exceptions in the sqlite3 module.
- Issue #21476: Make sure the email.parser.BytesParser TextIOWrapper is