Index: Lib/test/test_socket.py =================================================================== --- Lib/test/test_socket.py (revision 59346) +++ Lib/test/test_socket.py (working copy) @@ -275,7 +275,66 @@ fqhn = socket.getfqdn(ip) if not fqhn in all_host_names: self.fail("Error testing host resolution mechanisms. (fqdn: %s, all: %s)" % (fqhn, repr(all_host_names))) + # Try call by named argument + ip2 = socket.gethostbyname(host=hostname) + self.assertEquals(ip, ip2) + + result2 = socket.gethostbyaddr(host=ip) + self.assertEquals((hname, aliases, ipaddrs), result2) + def testGetHostByNameEx(self): + hostname = socket.gethostname() + try: + hostname, aliaslist, iplist = socket.gethostbyname_ex(hostname) + except socket.error: + # Probably name lookup wasn't set up right; skip this test + return + for ip in iplist: + self.assert_(ip.find('.') >= 0, "Error resolving host to ip.") + # Try call by named argument + result2 = socket.gethostbyname_ex(host=hostname) + self.assertEquals((hostname, aliaslist, iplist), result2) + + def testGetAddrInfo(self): + # Find one service that exists, then check all the related interfaces. + # I've ordered this by protocols that have both a tcp and udp + # protocol, at least for modern Linuxes. + if sys.platform in ('linux2', 'freebsd4', 'freebsd5', 'freebsd6', + 'freebsd7', 'freebsd8', 'darwin'): + # avoid the 'echo' service on this platform, as there is an + # assumption breaking non-standard port/protocol entry + services = ('daytime', 'qotd', 'domain') + else: + services = ('echo', 'daytime', 'domain') + for service in services: + try: + port = socket.getservbyname(service, 'tcp') + break + except socket.error: + pass + else: + raise socket.error + + hostname = socket.gethostname() + result = socket.getaddrinfo(hostname, service) + self.assert_(len(result) > 1) + result = result[0] + self.assertEquals(result[0], socket.AF_INET) + ip = result[4][0] + # It should be a valid ip address + self.assert_(len(socket.inet_aton(ip)) > 0) + port2 = result[4][1] + self.assertEquals(port, port2) + + def testGetNameInfo(self): + hostname = socket.gethostname() + host, port = socket.getnameinfo((hostname, 1234), 0) + self.assertEquals(port, '1234') + + # Try with named parameters + result2 = socket.getnameinfo(sockaddr=(hostname, 1234), flags=0) + self.assertEquals((host, port), result2) + def testRefCountGetNameInfo(self): # Testing reference count for getnameinfo import sys @@ -347,6 +406,10 @@ # Try same call with optional protocol omitted port2 = socket.getservbyname(service) eq(port, port2) + # Try same call with named arguments + port3 = socket.getservbyname(servicename=service, protocolname='tcp') + eq(port, port3) + # Try udp, but don't barf it it doesn't exist try: udpport = socket.getservbyname(service, 'udp') @@ -357,6 +420,8 @@ # Now make sure the lookup by port returns the same service name eq(socket.getservbyport(port2), service) eq(socket.getservbyport(port, 'tcp'), service) + # Try same call with named arguments + eq(socket.getservbyport(port=port, protocolname='tcp'), service) if udpport is not None: eq(socket.getservbyport(udpport, 'udp'), service) @@ -567,6 +632,19 @@ def _testFromFd(self): self.serv_conn.send(MSG) + def testFromFdNamedArguments(self): + # Testing fromfd() + if not hasattr(socket, "fromfd"): + return # On Windows, this doesn't exist + fd = self.cli_conn.fileno() + sock = socket.fromfd(fd=fd, family=socket.AF_INET, + type=socket.SOCK_STREAM) + msg = sock.recv(1024) + self.assertEqual(msg, MSG) + + def _testFromFdNamedArguments(self): + self.serv_conn.send(MSG) + def testShutdown(self): # Testing shutdown() msg = self.cli_conn.recv(1024) @@ -638,6 +716,14 @@ msg = self.cli.recv(1024) self.assertEqual(msg, MSG) +class SocketPairArgumentsTest(BasicSocketPairTest): + + def setUp(self): + self.serv, self.cli = socket.socketpair(type=socket.SOCK_STREAM, + proto=0) + + + class NonBlockingTCPTests(ThreadedTCPSocketTest): def __init__(self, methodName='runTest'): @@ -1093,6 +1179,7 @@ ]) if hasattr(socket, "socketpair"): tests.append(BasicSocketPairTest) + tests.append(SocketPairArgumentsTest) if sys.platform == 'linux2': tests.append(TestLinuxAbstractNamespace) Index: Modules/socketmodule.c =================================================================== --- Modules/socketmodule.c (revision 59346) +++ Modules/socketmodule.c (working copy) @@ -945,7 +945,6 @@ The family field of the sockaddr structure is inspected to determine what kind of address it really is. */ -/*ARGSUSED*/ static PyObject * makesockaddr(int sockfd, struct sockaddr *addr, int addrlen, int proto) { @@ -2817,7 +2816,6 @@ /* Initialize a new socket object. */ -/*ARGSUSED*/ static int sock_initobj(PyObject *self, PyObject *args, PyObject *kwds) { @@ -2898,9 +2896,8 @@ /* Python interface to gethostname(). */ -/*ARGSUSED*/ static PyObject * -socket_gethostname(PyObject *self, PyObject *unused) +socket_gethostname(PyObject *self) { char buf[1024]; int res; @@ -2921,14 +2918,15 @@ /* Python interface to gethostbyname(name). */ -/*ARGSUSED*/ static PyObject * -socket_gethostbyname(PyObject *self, PyObject *args) +socket_gethostbyname(PyObject *self, PyObject *args, PyObject *kwds) { char *name; sock_addr_t addrbuf; - if (!PyArg_ParseTuple(args, "s:gethostbyname", &name)) + static char *keywords[] = {"host", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:gethostbyname", keywords, &name)) return NULL; if (setipaddr(name, SAS2SA(&addrbuf), sizeof(addrbuf), AF_INET) < 0) return NULL; @@ -3080,9 +3078,8 @@ /* Python interface to gethostbyname_ex(name). */ -/*ARGSUSED*/ static PyObject * -socket_gethostbyname_ex(PyObject *self, PyObject *args) +socket_gethostbyname_ex(PyObject *self, PyObject *args, PyObject *kwds) { char *name; struct hostent *h; @@ -3107,7 +3104,9 @@ #endif #endif /* HAVE_GETHOSTBYNAME_R */ - if (!PyArg_ParseTuple(args, "s:gethostbyname_ex", &name)) + static char *keywords[] = {"host", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:gethostbyname_ex", keywords, &name)) return NULL; if (setipaddr(name, (struct sockaddr *)&addr, sizeof(addr), AF_INET) < 0) return NULL; @@ -3152,9 +3151,8 @@ /* Python interface to gethostbyaddr(IP). */ -/*ARGSUSED*/ static PyObject * -socket_gethostbyaddr(PyObject *self, PyObject *args) +socket_gethostbyaddr(PyObject *self, PyObject *args, PyObject *kwds) { #ifdef ENABLE_IPV6 struct sockaddr_storage addr; @@ -3182,7 +3180,9 @@ int al; int af; - if (!PyArg_ParseTuple(args, "s:gethostbyaddr", &ip_num)) + static char *keywords[] = {"host", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:gethostbyaddr", keywords, &ip_num)) return NULL; af = AF_UNSPEC; if (setipaddr(ip_num, sa, sizeof(addr), af) < 0) @@ -3244,13 +3244,15 @@ This only returns the port number, since the other info is already known or not useful (like the list of aliases). */ -/*ARGSUSED*/ static PyObject * -socket_getservbyname(PyObject *self, PyObject *args) +socket_getservbyname(PyObject *self, PyObject *args, PyObject *kwds) { char *name, *proto=NULL; struct servent *sp; - if (!PyArg_ParseTuple(args, "s|s:getservbyname", &name, &proto)) + + static char *keywords[] = {"servicename", "protocolname", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s:getservbyname", keywords, &name, &proto)) return NULL; Py_BEGIN_ALLOW_THREADS sp = getservbyname(name, proto); @@ -3274,14 +3276,16 @@ This only returns the service name, since the other info is already known or not useful (like the list of aliases). */ -/*ARGSUSED*/ static PyObject * -socket_getservbyport(PyObject *self, PyObject *args) +socket_getservbyport(PyObject *self, PyObject *args, PyObject *kwds) { unsigned short port; char *proto=NULL; struct servent *sp; - if (!PyArg_ParseTuple(args, "H|s:getservbyport", &port, &proto)) + + static char *keywords[] = {"port", "protocolname", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "H|s:getservbyport", keywords, &port, &proto)) return NULL; Py_BEGIN_ALLOW_THREADS sp = getservbyport(htons(port), proto); @@ -3304,9 +3308,8 @@ This only returns the protocol number, since the other info is already known or not useful (like the list of aliases). */ -/*ARGSUSED*/ static PyObject * -socket_getprotobyname(PyObject *self, PyObject *args) +socket_getprotobyname(PyObject *self, PyObject *args, PyObject *kwds) { char *name; struct protoent *sp; @@ -3315,7 +3318,10 @@ PyErr_SetString(socket_error, "getprotobyname not supported"); return NULL; #else - if (!PyArg_ParseTuple(args, "s:getprotobyname", &name)) + + static char *keywords[] = {"name", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:getprotobyname", keywords, &name)) return NULL; Py_BEGIN_ALLOW_THREADS sp = getprotobyname(name); @@ -3339,9 +3345,8 @@ Arguments as for socket() except the default family is AF_UNIX if defined on the platform; otherwise, the default is AF_INET. */ -/*ARGSUSED*/ static PyObject * -socket_socketpair(PyObject *self, PyObject *args) +socket_socketpair(PyObject *self, PyObject *args, PyObject *kwds) { PySocketSockObject *s0 = NULL, *s1 = NULL; SOCKET_T sv[2]; @@ -3353,7 +3358,10 @@ #else family = AF_INET; #endif - if (!PyArg_ParseTuple(args, "|iii:socketpair", + + static char *keywords[] = {"family", "type", "proto", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iii:socketpair", keywords, &family, &type, &proto)) return NULL; /* Create a pair of socket fds */ @@ -3395,14 +3403,15 @@ Useful e.g. if stdin is a socket. Additional arguments as for socket(). */ -/*ARGSUSED*/ static PyObject * -socket_fromfd(PyObject *self, PyObject *args) +socket_fromfd(PyObject *self, PyObject *args, PyObject *kwds) { PySocketSockObject *s; SOCKET_T fd; int family, type, proto = 0; - if (!PyArg_ParseTuple(args, "iii|i:fromfd", + static char *keywords[] = {"fd", "family", "type", "proto", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "iii|i:fromfd", keywords, &fd, &family, &type, &proto)) return NULL; /* Dup the fd so it and the socket can be closed independently */ @@ -3773,9 +3782,8 @@ /* Python interface to getaddrinfo(host, port). */ -/*ARGSUSED*/ static PyObject * -socket_getaddrinfo(PyObject *self, PyObject *args) +socket_getaddrinfo(PyObject *self, PyObject *args, PyObject *kwds) { struct addrinfo hints, *res; struct addrinfo *res0 = NULL; @@ -3791,7 +3799,10 @@ family = socktype = protocol = flags = 0; family = AF_UNSPEC; - if (!PyArg_ParseTuple(args, "OO|iiii:getaddrinfo", + + static char *keywords[] = {"host", "port", "family", "socktype", "proto", "flags", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|iiii:getaddrinfo", keywords, &hobj, &pobj, &family, &socktype, &protocol, &flags)) { return NULL; @@ -3876,9 +3887,8 @@ /* Python interface to getnameinfo(sa, flags). */ -/*ARGSUSED*/ static PyObject * -socket_getnameinfo(PyObject *self, PyObject *args) +socket_getnameinfo(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *sa = (PyObject *)NULL; int flags; @@ -3890,7 +3900,10 @@ PyObject *ret = (PyObject *)NULL; flags = flowinfo = scope_id = 0; - if (!PyArg_ParseTuple(args, "Oi:getnameinfo", &sa, &flags)) + + static char *keywords[] = {"sockaddr", "flags", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi:getnameinfo", keywords, &sa, &flags)) return NULL; if (!PyArg_ParseTuple(sa, "si|ii", &hostp, &port, &flowinfo, &scope_id)) @@ -4010,27 +4023,27 @@ /* List of functions exported by this module. */ static PyMethodDef socket_methods[] = { - {"gethostbyname", socket_gethostbyname, - METH_VARARGS, gethostbyname_doc}, - {"gethostbyname_ex", socket_gethostbyname_ex, - METH_VARARGS, ghbn_ex_doc}, - {"gethostbyaddr", socket_gethostbyaddr, - METH_VARARGS, gethostbyaddr_doc}, - {"gethostname", socket_gethostname, - METH_NOARGS, gethostname_doc}, - {"getservbyname", socket_getservbyname, - METH_VARARGS, getservbyname_doc}, - {"getservbyport", socket_getservbyport, - METH_VARARGS, getservbyport_doc}, - {"getprotobyname", socket_getprotobyname, + {"gethostbyname", (PyCFunction)socket_gethostbyname, + METH_VARARGS|METH_KEYWORDS, gethostbyname_doc}, + {"gethostbyname_ex", (PyCFunction)socket_gethostbyname_ex, + METH_VARARGS|METH_KEYWORDS, ghbn_ex_doc}, + {"gethostbyaddr", (PyCFunction)socket_gethostbyaddr, + METH_VARARGS|METH_KEYWORDS, gethostbyaddr_doc}, + {"gethostname", (PyCFunction)socket_gethostname, + METH_NOARGS|METH_KEYWORDS, gethostname_doc}, + {"getservbyname", (PyCFunction)socket_getservbyname, + METH_VARARGS|METH_KEYWORDS, getservbyname_doc}, + {"getservbyport", (PyCFunction)socket_getservbyport, + METH_VARARGS|METH_KEYWORDS, getservbyport_doc}, + {"getprotobyname", (PyCFunction)socket_getprotobyname, METH_VARARGS, getprotobyname_doc}, #ifndef NO_DUP - {"fromfd", socket_fromfd, - METH_VARARGS, fromfd_doc}, + {"fromfd", (PyCFunction)socket_fromfd, + METH_VARARGS|METH_KEYWORDS, fromfd_doc}, #endif #ifdef HAVE_SOCKETPAIR - {"socketpair", socket_socketpair, - METH_VARARGS, socketpair_doc}, + {"socketpair", (PyCFunction)socket_socketpair, + METH_VARARGS|METH_KEYWORDS, socketpair_doc}, #endif {"ntohs", socket_ntohs, METH_VARARGS, ntohs_doc}, @@ -4050,10 +4063,10 @@ {"inet_ntop", socket_inet_ntop, METH_VARARGS, inet_ntop_doc}, #endif - {"getaddrinfo", socket_getaddrinfo, - METH_VARARGS, getaddrinfo_doc}, - {"getnameinfo", socket_getnameinfo, - METH_VARARGS, getnameinfo_doc}, + {"getaddrinfo", (PyCFunction)socket_getaddrinfo, + METH_VARARGS|METH_KEYWORDS, getaddrinfo_doc}, + {"getnameinfo", (PyCFunction)socket_getnameinfo, + METH_VARARGS|METH_KEYWORDS, getnameinfo_doc}, {"getdefaulttimeout", (PyCFunction)socket_getdefaulttimeout, METH_NOARGS, getdefaulttimeout_doc}, {"setdefaulttimeout", socket_setdefaulttimeout,