changeset: 100911:bd665613ed67 user: Martin Panter date: Mon Apr 11 00:38:12 2016 +0000 files: Doc/library/socket.rst Doc/whatsnew/3.6.rst Lib/test/test_pty.py Lib/test/test_socket.py Misc/NEWS Modules/socketmodule.c description: Issue #26685: Raise OSError if closing a socket fails diff -r d758c5965199 -r bd665613ed67 Doc/library/socket.rst --- a/Doc/library/socket.rst Sun Apr 10 18:12:01 2016 +0300 +++ b/Doc/library/socket.rst Mon Apr 11 00:38:12 2016 +0000 @@ -868,6 +868,10 @@ it is recommended to :meth:`close` them explicitly, or to use a :keyword:`with` statement around them. + .. versionchanged:: 3.6 + :exc:`OSError` is now raised if an error occurs when the underlying + :c:func:`close` call is made. + .. note:: :meth:`close()` releases the resource associated with a connection but diff -r d758c5965199 -r bd665613ed67 Doc/whatsnew/3.6.rst --- a/Doc/whatsnew/3.6.rst Sun Apr 10 18:12:01 2016 +0300 +++ b/Doc/whatsnew/3.6.rst Mon Apr 11 00:38:12 2016 +0000 @@ -514,6 +514,10 @@ * :func:`spwd.getspnam` now raises a :exc:`PermissionError` instead of :exc:`KeyError` if the user doesn't have privileges. +* The :meth:`socket.socket.close` method now raises an exception if + an error (e.g. EBADF) was reported by the underlying system call. + See :issue:`26685`. + Changes in the C API -------------------- diff -r d758c5965199 -r bd665613ed67 Lib/test/test_pty.py --- a/Lib/test/test_pty.py Sun Apr 10 18:12:01 2016 +0300 +++ b/Lib/test/test_pty.py Mon Apr 11 00:38:12 2016 +0000 @@ -277,7 +277,6 @@ socketpair = self._socketpair() masters = [s.fileno() for s in socketpair] - os.close(masters[1]) socketpair[1].close() os.close(write_to_stdin_fd) diff -r d758c5965199 -r bd665613ed67 Lib/test/test_socket.py --- a/Lib/test/test_socket.py Sun Apr 10 18:12:01 2016 +0300 +++ b/Lib/test/test_socket.py Mon Apr 11 00:38:12 2016 +0000 @@ -1161,6 +1161,17 @@ sock.close() self.assertRaises(OSError, sock.send, b"spam") + def testCloseException(self): + sock = socket.socket() + socket.socket(fileno=sock.fileno()).close() + try: + sock.close() + except OSError as err: + # Winsock apparently raises ENOTSOCK + self.assertIn(err.errno, (errno.EBADF, errno.ENOTSOCK)) + else: + self.fail("close() should raise EBADF/ENOTSOCK") + def testNewAttributes(self): # testing .family, .type and .protocol diff -r d758c5965199 -r bd665613ed67 Misc/NEWS --- a/Misc/NEWS Sun Apr 10 18:12:01 2016 +0300 +++ b/Misc/NEWS Mon Apr 11 00:38:12 2016 +0000 @@ -240,6 +240,8 @@ Library ------- +- Issue #26685: Raise OSError if closing a socket fails. + - Issue #16329: Add .webm to mimetypes.types_map. Patch by Giampaolo Rodola'. - Issue #13952: Add .csv to mimetypes.types_map. Patch by Geoff Wilson. diff -r d758c5965199 -r bd665613ed67 Modules/socketmodule.c --- a/Modules/socketmodule.c Sun Apr 10 18:12:01 2016 +0300 +++ b/Modules/socketmodule.c Mon Apr 11 00:38:12 2016 +0000 @@ -2576,6 +2576,7 @@ sock_close(PySocketSockObject *s) { SOCKET_T fd; + int res; fd = s->sock_fd; if (fd != -1) { @@ -2586,8 +2587,11 @@ http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html for more details. */ Py_BEGIN_ALLOW_THREADS - (void) SOCKETCLOSE(fd); + res = SOCKETCLOSE(fd); Py_END_ALLOW_THREADS + if (res < 0) { + return s->errorhandler(); + } } Py_INCREF(Py_None); return Py_None;