diff -r a42db4d56982 Lib/test/test_socket.py --- a/Lib/test/test_socket.py Fri Mar 12 15:30:26 2010 +0100 +++ b/Lib/test/test_socket.py Fri Mar 12 19:46:03 2010 +0100 @@ -1226,28 +1226,64 @@ def __init__(self, methodName='runTest'): SocketConnectedTest.__init__(self, methodName=methodName) - def testRecvInto(self): + def testRecvIntoArray(self): buf = array.array('c', ' '*1024) nbytes = self.cli_conn.recv_into(buf) self.assertEqual(nbytes, len(MSG)) msg = buf.tostring()[:len(MSG)] self.assertEqual(msg, MSG) - def _testRecvInto(self): + def _testRecvIntoArray(self): buf = buffer(MSG) self.serv_conn.send(buf) - def testRecvFromInto(self): + def testRecvIntoBytearray(self): + buf = bytearray(1024) + nbytes = self.cli_conn.recv_into(buf) + self.assertEqual(nbytes, len(MSG)) + msg = buf[:len(MSG)] + self.assertEqual(msg, MSG) + + _testRecvIntoBytearray = _testRecvIntoArray + + def testRecvIntoMemoryview(self): + buf = bytearray(1024) + nbytes = self.cli_conn.recv_into(memoryview(buf)) + self.assertEqual(nbytes, len(MSG)) + msg = buf[:len(MSG)] + self.assertEqual(msg, MSG) + + _testRecvIntoMemoryview = _testRecvIntoArray + + def testRecvFromIntoArray(self): buf = array.array('c', ' '*1024) nbytes, addr = self.cli_conn.recvfrom_into(buf) self.assertEqual(nbytes, len(MSG)) msg = buf.tostring()[:len(MSG)] self.assertEqual(msg, MSG) - def _testRecvFromInto(self): + def _testRecvFromIntoArray(self): buf = buffer(MSG) self.serv_conn.send(buf) + def testRecvFromIntoBytearray(self): + buf = bytearray(1024) + nbytes, addr = self.cli_conn.recvfrom_into(buf) + self.assertEqual(nbytes, len(MSG)) + msg = buf[:len(MSG)] + self.assertEqual(msg, MSG) + + _testRecvFromIntoBytearray = _testRecvFromIntoArray + + def testRecvFromIntoMemoryview(self): + buf = bytearray(1024) + nbytes, addr = self.cli_conn.recvfrom_into(memoryview(buf)) + self.assertEqual(nbytes, len(MSG)) + msg = buf[:len(MSG)] + self.assertEqual(msg, MSG) + + _testRecvFromIntoMemoryview = _testRecvFromIntoArray + TIPC_STYPE = 2000 TIPC_LOWER = 200 diff -r a42db4d56982 Modules/socketmodule.c --- a/Modules/socketmodule.c Fri Mar 12 15:30:26 2010 +0100 +++ b/Modules/socketmodule.c Fri Mar 12 19:46:03 2010 +0100 @@ -2449,19 +2449,20 @@ int recvlen = 0, flags = 0; ssize_t readlen; - char *buf; + Py_buffer buf; int buflen; /* Get the buffer's memory */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "w#|ii:recv_into", kwlist, - &buf, &buflen, &recvlen, &flags)) - return NULL; - assert(buf != 0 && buflen > 0); + if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ii:recv_into", kwlist, + &buf, &recvlen, &flags)) + return NULL; + buflen = buf.len; + assert(buf.buf != 0 && buflen > 0); if (recvlen < 0) { PyErr_SetString(PyExc_ValueError, "negative buffersize in recv_into"); - return NULL; + goto error; } if (recvlen == 0) { /* If nbytes was not specified, use the buffer's length */ @@ -2472,19 +2473,24 @@ if (buflen < recvlen) { PyErr_SetString(PyExc_ValueError, "buffer too small for requested bytes"); - return NULL; + goto error; } /* Call the guts */ - readlen = sock_recv_guts(s, buf, recvlen, flags); + readlen = sock_recv_guts(s, buf.buf, recvlen, flags); if (readlen < 0) { /* Return an error. */ - return NULL; - } - + goto error; + } + + PyBuffer_Release(&buf); /* Return the number of bytes read. Note that we do not do anything special here in the case that readlen < recvlen. */ return PyInt_FromSsize_t(readlen); + +error: + PyBuffer_Release(&buf); + return NULL; } PyDoc_STRVAR(recv_into_doc, @@ -2623,37 +2629,43 @@ int recvlen = 0, flags = 0; ssize_t readlen; - char *buf; + Py_buffer buf; int buflen; PyObject *addr = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "w#|ii:recvfrom_into", - kwlist, &buf, &buflen, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ii:recvfrom_into", + kwlist, &buf, &recvlen, &flags)) return NULL; - assert(buf != 0 && buflen > 0); + buflen = buf.len; + assert(buf.buf != 0 && buflen > 0); if (recvlen < 0) { PyErr_SetString(PyExc_ValueError, "negative buffersize in recvfrom_into"); - return NULL; + goto error; } if (recvlen == 0) { /* If nbytes was not specified, use the buffer's length */ recvlen = buflen; } - readlen = sock_recvfrom_guts(s, buf, recvlen, flags, &addr); + readlen = sock_recvfrom_guts(s, buf.buf, recvlen, flags, &addr); if (readlen < 0) { /* Return an error */ - Py_XDECREF(addr); - return NULL; - } - + goto error; + } + + PyBuffer_Release(&buf); /* Return the number of bytes read and the address. Note that we do not do anything special here in the case that readlen < recvlen. */ return Py_BuildValue("lN", readlen, addr); + +error: + Py_XDECREF(addr); + PyBuffer_Release(&buf); + return NULL; } PyDoc_STRVAR(recvfrom_into_doc,