[Python-checkins] r68796 - in python/branches/release30-maint: Lib/socket.py Lib/test/test_socket.py Misc/NEWS

gregory.p.smith python-checkins at python.org
Tue Jan 20 05:02:33 CET 2009


Author: gregory.p.smith
Date: Tue Jan 20 05:02:33 2009
New Revision: 68796

Log:
Backport r68539, Fixes issue #3826 and #4791:
Have SocketIO objects update their reference count in the underlying
socket object on close() so that the underlying socket object is
closed immediately when the last user is done rather than at an
unknown later time when garbage collection can do it.


Modified:
   python/branches/release30-maint/Lib/socket.py
   python/branches/release30-maint/Lib/test/test_socket.py
   python/branches/release30-maint/Misc/NEWS

Modified: python/branches/release30-maint/Lib/socket.py
==============================================================================
--- python/branches/release30-maint/Lib/socket.py	(original)
+++ python/branches/release30-maint/Lib/socket.py	Tue Jan 20 05:02:33 2009
@@ -225,11 +225,12 @@
         return self._writing and not self.closed
 
     def fileno(self):
+        self._checkClosed()
         return self._sock.fileno()
 
     @property
     def name(self):
-        return self._sock.fileno()
+        return self.fileno()
 
     @property
     def mode(self):
@@ -239,9 +240,12 @@
         if self.closed:
             return
         io.RawIOBase.close(self)
+        self._sock._decref_socketios()
+        self._sock = None
 
     def __del__(self):
-        self._sock._decref_socketios()
+        if not self.closed:
+            self._sock._decref_socketios()
 
 
 def getfqdn(name=''):

Modified: python/branches/release30-maint/Lib/test/test_socket.py
==============================================================================
--- python/branches/release30-maint/Lib/test/test_socket.py	(original)
+++ python/branches/release30-maint/Lib/test/test_socket.py	Tue Jan 20 05:02:33 2009
@@ -860,6 +860,16 @@
         self.assertEqual(self.cli_file.mode, 'wb')
         self.assertEqual(self.cli_file.name, self.serv_conn.fileno())
 
+    def testRealClose(self):
+        self.serv_file.close()
+        self.assertRaises(ValueError, self.serv_file.fileno)
+        self.cli_conn.close()
+        self.assertRaises(socket.error, self.cli_conn.getsockname)
+
+    def _testRealClose(self):
+        pass
+
+
 class UnbufferedFileObjectClassTestCase(FileObjectClassTestCase):
 
     """Repeat the tests from FileObjectClassTestCase with bufsize==0.
@@ -885,6 +895,29 @@
         self.cli_file.write(b"B. " + MSG)
         self.cli_file.flush()
 
+    def testMakefileClose(self):
+        # The file returned by makefile should keep the socket open...
+        self.cli_conn.close()
+        msg = self.cli_conn.recv(1024)
+        self.assertEqual(msg, MSG)
+        # ...until the file is itself closed
+        self.serv_file.close()
+        self.assertRaises(socket.error, self.cli_conn.recv, 1024)
+
+    def _testMakefileClose(self):
+        self.cli_file.write(MSG)
+        self.cli_file.flush()
+
+    def testMakefileCloseSocketDestroy(self):
+        refcount_before = sys.getrefcount(self.cli_conn)
+        self.serv_file.close()
+        refcount_after = sys.getrefcount(self.cli_conn)
+        self.assertEqual(refcount_before - 1, refcount_after)
+
+    def _testMakefileCloseSocketDestroy(self):
+        pass
+
+
 class LineBufferedFileObjectClassTestCase(FileObjectClassTestCase):
 
     bufsize = 1 # Default-buffered for reading; line-buffered for writing

Modified: python/branches/release30-maint/Misc/NEWS
==============================================================================
--- python/branches/release30-maint/Misc/NEWS	(original)
+++ python/branches/release30-maint/Misc/NEWS	Tue Jan 20 05:02:33 2009
@@ -95,6 +95,10 @@
 Library
 -------
 
+- Issue #3826 and #4791: The socket module now closes the underlying socket
+  appropriately when it is being used via socket.makefile() objects
+  rather than delaying the close by waiting for garbage collection to do it.
+
 - Issue #4867: Fixed a crash in ctypes when passing a string to a
   function without defining argtypes.
 


More information about the Python-checkins mailing list