Commit 6e451df8 authored by Antoine Pitrou's avatar Antoine Pitrou

Followup to r83869 and issue #8524: rename socket.forget() to socket.detach()

and make it return the file descriptor.
parent 30e86a47
...@@ -538,6 +538,15 @@ correspond to Unix system calls applicable to sockets. ...@@ -538,6 +538,15 @@ correspond to Unix system calls applicable to sockets.
connects. connects.
.. method:: socket.detach()
Put the socket object into closed state without actually closing the
underlying file descriptor. The file descriptor is returned, and can
be reused for other purposes.
.. versionadded:: 3.2
.. method:: socket.fileno() .. method:: socket.fileno()
Return the socket's file descriptor (a small integer). This is useful with Return the socket's file descriptor (a small integer). This is useful with
...@@ -548,14 +557,6 @@ correspond to Unix system calls applicable to sockets. ...@@ -548,14 +557,6 @@ correspond to Unix system calls applicable to sockets.
this limitation. this limitation.
.. method:: socket.forget()
Put the socket object into closed state without actually closing the
underlying file descriptor. This allows the latter to be reused.
.. versionadded:: 3.2
.. method:: socket.getpeername() .. method:: socket.getpeername()
Return the remote address to which the socket is connected. This is useful to Return the remote address to which the socket is connected. This is useful to
......
...@@ -136,7 +136,7 @@ New, Improved, and Deprecated Modules ...@@ -136,7 +136,7 @@ New, Improved, and Deprecated Modules
(Contributed by Tarek Ziadé.) (Contributed by Tarek Ziadé.)
* Socket objects now have a :meth:`~socket.socket.forget()` method which * Socket objects now have a :meth:`~socket.socket.detach()` method which
puts the socket into closed state without actually closing the underlying puts the socket into closed state without actually closing the underlying
file descriptor. The latter can then be reused for other purposes. file descriptor. The latter can then be reused for other purposes.
......
...@@ -157,7 +157,7 @@ class SSLSocket(socket): ...@@ -157,7 +157,7 @@ class SSLSocket(socket):
raise raise
else: else:
connected = True connected = True
sock.forget() sock.detach()
elif fileno is not None: elif fileno is not None:
socket.__init__(self, fileno=fileno) socket.__init__(self, fileno=fileno)
else: else:
......
...@@ -655,17 +655,21 @@ class BasicTCPTest(SocketConnectedTest): ...@@ -655,17 +655,21 @@ class BasicTCPTest(SocketConnectedTest):
self.serv_conn.send(MSG) self.serv_conn.send(MSG)
self.serv_conn.shutdown(2) self.serv_conn.shutdown(2)
def testForget(self): def testDetach(self):
# Testing forget() # Testing detach()
f = self.cli_conn.fileno() fileno = self.cli_conn.fileno()
self.cli_conn.forget() f = self.cli_conn.detach()
self.assertEqual(f, fileno)
# cli_conn cannot be used anymore...
self.assertRaises(socket.error, self.cli_conn.recv, 1024) self.assertRaises(socket.error, self.cli_conn.recv, 1024)
self.cli_conn.close() self.cli_conn.close()
# ...but we can create another socket using the (still open)
# file descriptor
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, fileno=f) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, fileno=f)
msg = sock.recv(1024) msg = sock.recv(1024)
self.assertEqual(msg, MSG) self.assertEqual(msg, MSG)
def _testForget(self): def _testDetach(self):
self.serv_conn.send(MSG) self.serv_conn.send(MSG)
@unittest.skipUnless(thread, 'Threading required for this test.') @unittest.skipUnless(thread, 'Threading required for this test.')
......
...@@ -30,7 +30,7 @@ Core and Builtins ...@@ -30,7 +30,7 @@ Core and Builtins
Extensions Extensions
---------- ----------
- Issue #8524: Add a forget() method to socket objects, so as to put the - Issue #8524: Add a detach() method to socket objects, so as to put the
socket into the closed state without closing the underlying file socket into the closed state without closing the underlying file
descriptor. descriptor.
......
...@@ -1870,19 +1870,19 @@ PyDoc_STRVAR(close_doc, ...@@ -1870,19 +1870,19 @@ PyDoc_STRVAR(close_doc,
Close the socket. It cannot be used after this call."); Close the socket. It cannot be used after this call.");
static PyObject * static PyObject *
sock_forget(PySocketSockObject *s) sock_detach(PySocketSockObject *s)
{ {
SOCKET_T fd = s->sock_fd;
s->sock_fd = -1; s->sock_fd = -1;
Py_INCREF(Py_None); return PyLong_FromSocket_t(fd);
return Py_None;
} }
PyDoc_STRVAR(forget_doc, PyDoc_STRVAR(detach_doc,
"forget()\n\ "detach()\n\
\n\ \n\
Close the socket object without closing the underlying file descriptor.\ Close the socket object without closing the underlying file descriptor.\
The object cannot be used after this call, but the file descriptor\ The object cannot be used after this call, but the file descriptor\
can be reused for other purposes."); can be reused for other purposes. The file descriptor is returned.");
static int static int
internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen, internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
...@@ -2772,10 +2772,10 @@ static PyMethodDef sock_methods[] = { ...@@ -2772,10 +2772,10 @@ static PyMethodDef sock_methods[] = {
connect_doc}, connect_doc},
{"connect_ex", (PyCFunction)sock_connect_ex, METH_O, {"connect_ex", (PyCFunction)sock_connect_ex, METH_O,
connect_ex_doc}, connect_ex_doc},
{"detach", (PyCFunction)sock_detach, METH_NOARGS,
detach_doc},
{"fileno", (PyCFunction)sock_fileno, METH_NOARGS, {"fileno", (PyCFunction)sock_fileno, METH_NOARGS,
fileno_doc}, fileno_doc},
{"forget", (PyCFunction)sock_forget, METH_NOARGS,
forget_doc},
#ifdef HAVE_GETPEERNAME #ifdef HAVE_GETPEERNAME
{"getpeername", (PyCFunction)sock_getpeername, {"getpeername", (PyCFunction)sock_getpeername,
METH_NOARGS, getpeername_doc}, METH_NOARGS, getpeername_doc},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment