Add default timeout functionality. This adds setdefaulttimeout() and
getdefaulttimeout() functions to the socket and _socket modules, and appropriate tests.
This commit is contained in:
parent
8b6ec79b74
commit
9d0c8cee66
|
@ -21,6 +21,8 @@ htons(), htonl() -- convert 16, 32 bit int from host to network byte order
|
|||
inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format
|
||||
inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89)
|
||||
ssl() -- secure socket layer support (only available if configured)
|
||||
socket.getdefaulttimeout() -- get the default timeout value
|
||||
socket.setdefaulttimeout() -- set the default timeout value
|
||||
|
||||
[*] not available on all platforms!
|
||||
|
||||
|
|
|
@ -297,6 +297,36 @@ class GeneralModuleTests(unittest.TestCase):
|
|||
except socket.error:
|
||||
pass
|
||||
|
||||
def testDefaultTimeout(self):
|
||||
"""Testing default timeout."""
|
||||
# The default timeout should initially be None
|
||||
self.assertEqual(socket.getdefaulttimeout(), None)
|
||||
s = socket.socket()
|
||||
self.assertEqual(s.gettimeout(), None)
|
||||
s.close()
|
||||
|
||||
# Set the default timeout to 10, and see if it propagates
|
||||
socket.setdefaulttimeout(10)
|
||||
self.assertEqual(socket.getdefaulttimeout(), 10)
|
||||
s = socket.socket()
|
||||
self.assertEqual(s.gettimeout(), 10)
|
||||
s.close()
|
||||
|
||||
# Reset the default timeout to None, and see if it propagates
|
||||
socket.setdefaulttimeout(None)
|
||||
self.assertEqual(socket.getdefaulttimeout(), None)
|
||||
s = socket.socket()
|
||||
self.assertEqual(s.gettimeout(), None)
|
||||
s.close()
|
||||
|
||||
# Check that setting it to an invalid value raises ValueError
|
||||
self.assertRaises(ValueError, socket.setdefaulttimeout, -1)
|
||||
|
||||
# Check that setting it to an invalid type raises TypeError
|
||||
self.assertRaises(TypeError, socket.setdefaulttimeout, "spam")
|
||||
|
||||
# XXX The following three don't test module-level functionality...
|
||||
|
||||
def testSockName(self):
|
||||
"""Testing getsockname()."""
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
|
|
@ -35,6 +35,8 @@ Module interface:
|
|||
- socket.AF_INET, socket.SOCK_STREAM, etc.: constants from <socket.h>
|
||||
- socket.inet_aton(IP address) -> 32-bit packed IP representation
|
||||
- socket.inet_ntoa(packed IP) -> IP address string
|
||||
- socket.getdefaulttimeout() -> None | float
|
||||
- socket.setdefaulttimeout(None | float)
|
||||
- an Internet socket address is a pair (hostname, port)
|
||||
where hostname can be anything recognized by gethostbyname()
|
||||
(including the dd.dd.dd.dd notation) and port is in host byte order
|
||||
|
@ -521,6 +523,8 @@ internal_select(PySocketSockObject *s, int writing)
|
|||
|
||||
/* Initialize a new socket object. */
|
||||
|
||||
static float defaulttimeout = -1.0; /* Default timeout for new sockets */
|
||||
|
||||
static void
|
||||
init_sockobject(PySocketSockObject *s,
|
||||
SOCKET_T fd, int family, int type, int proto)
|
||||
|
@ -532,9 +536,13 @@ init_sockobject(PySocketSockObject *s,
|
|||
s->sock_family = family;
|
||||
s->sock_type = type;
|
||||
s->sock_proto = proto;
|
||||
s->sock_timeout = -1.0; /* Start without timeout */
|
||||
s->sock_timeout = defaulttimeout;
|
||||
|
||||
s->errorhandler = &set_error;
|
||||
|
||||
if (defaulttimeout >= 0.0)
|
||||
internal_setblocking(s, 0);
|
||||
|
||||
#ifdef RISCOS
|
||||
if (taskwindow)
|
||||
socketioctl(s->sock_fd, 0x80046679, (u_long*)&block);
|
||||
|
@ -2725,6 +2733,58 @@ PyDoc_STRVAR(getnameinfo_doc,
|
|||
\n\
|
||||
Get host and port for a sockaddr.");
|
||||
|
||||
|
||||
/* Python API to getting and setting the default timeout value. */
|
||||
|
||||
static PyObject *
|
||||
socket_getdefaulttimeout(PyObject *self)
|
||||
{
|
||||
if (defaulttimeout < 0.0) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
else
|
||||
return PyFloat_FromDouble(defaulttimeout);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(getdefaulttimeout_doc,
|
||||
"socket.getdefaulttimeout() -> None | float\n\
|
||||
\n\
|
||||
Returns the default timeout in floating seconds for new socket objects.\n\
|
||||
A value of None indicates that new socket objects have no timeout.\n\
|
||||
When the socket module is first imported, the default is None.");
|
||||
|
||||
static PyObject *
|
||||
socket_setdefaulttimeout(PyObject *self, PyObject *arg)
|
||||
{
|
||||
double timeout;
|
||||
|
||||
if (arg == Py_None)
|
||||
timeout = -1.0;
|
||||
else {
|
||||
timeout = PyFloat_AsDouble(arg);
|
||||
if (timeout < 0.0) {
|
||||
if (!PyErr_Occurred())
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Timeout value out of range");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
defaulttimeout = timeout;
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(setdefaulttimeout_doc,
|
||||
"socket.setdefaulttimeout(None | float)\n\
|
||||
\n\
|
||||
Set the default timeout in floating seconds for new socket objects.\n\
|
||||
A value of None indicates that new socket objects have no timeout.\n\
|
||||
When the socket module is first imported, the default is None.");
|
||||
|
||||
|
||||
/* List of functions exported by this module. */
|
||||
|
||||
static PyMethodDef socket_methods[] = {
|
||||
|
@ -2760,6 +2820,10 @@ static PyMethodDef socket_methods[] = {
|
|||
METH_VARARGS, getaddrinfo_doc},
|
||||
{"getnameinfo", socket_getnameinfo,
|
||||
METH_VARARGS, getnameinfo_doc},
|
||||
{"getdefaulttimeout", socket_getdefaulttimeout,
|
||||
METH_NOARGS, getdefaulttimeout_doc},
|
||||
{"setdefaulttimeout", socket_setdefaulttimeout,
|
||||
METH_O, setdefaulttimeout_doc},
|
||||
{NULL, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue