mirror of
https://github.com/python/cpython.git
synced 2025-07-29 06:05:00 +00:00
Merged revisions 85420 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r85420 | antoine.pitrou | 2010-10-13 18:17:14 +0200 (mer., 13 oct. 2010) | 5 lines Issue #10041: The signature of optional arguments in socket.makefile() didn't match that of io.open(), and they also didn't get forwarded properly to TextIOWrapper in text mode. Patch by Kai Zhu. ........
This commit is contained in:
parent
bc5d78d304
commit
674f40092a
5 changed files with 117 additions and 61 deletions
|
@ -588,7 +588,7 @@ correspond to Unix system calls applicable to sockets.
|
||||||
is system-dependent (usually 5).
|
is system-dependent (usually 5).
|
||||||
|
|
||||||
|
|
||||||
.. method:: socket.makefile(mode='r', buffering=None, *, encoding=None, newline=None)
|
.. method:: socket.makefile(mode='r', buffering=None, *, encoding=None, errors=None, newline=None)
|
||||||
|
|
||||||
.. index:: single: I/O control; buffering
|
.. index:: single: I/O control; buffering
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ class socket(_socket.socket):
|
||||||
return socket(self.family, self.type, self.proto, fileno=fd), addr
|
return socket(self.family, self.type, self.proto, fileno=fd), addr
|
||||||
|
|
||||||
def makefile(self, mode="r", buffering=None, *,
|
def makefile(self, mode="r", buffering=None, *,
|
||||||
encoding=None, newline=None):
|
encoding=None, errors=None, newline=None):
|
||||||
"""makefile(...) -> an I/O stream connected to the socket
|
"""makefile(...) -> an I/O stream connected to the socket
|
||||||
|
|
||||||
The arguments are as for io.open() after the filename,
|
The arguments are as for io.open() after the filename,
|
||||||
|
@ -159,7 +159,7 @@ class socket(_socket.socket):
|
||||||
buffer = io.BufferedWriter(raw, buffering)
|
buffer = io.BufferedWriter(raw, buffering)
|
||||||
if binary:
|
if binary:
|
||||||
return buffer
|
return buffer
|
||||||
text = io.TextIOWrapper(buffer, encoding, newline)
|
text = io.TextIOWrapper(buffer, encoding, errors, newline)
|
||||||
text.mode = mode
|
text.mode = mode
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ def try_address(host, port=0, family=socket.AF_INET):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
HOST = support.HOST
|
HOST = support.HOST
|
||||||
MSG = b'Michael Gilfix was here\n'
|
MSG = 'Michael Gilfix was here\u1234\r\n'.encode('utf8') ## test unicode string and carriage return
|
||||||
SUPPORTS_IPV6 = socket.has_ipv6 and try_address('::1', family=socket.AF_INET6)
|
SUPPORTS_IPV6 = socket.has_ipv6 and try_address('::1', family=socket.AF_INET6)
|
||||||
|
|
||||||
class SocketTCPTest(unittest.TestCase):
|
class SocketTCPTest(unittest.TestCase):
|
||||||
|
@ -870,120 +870,138 @@ class NonBlockingTCPTests(ThreadedTCPSocketTest):
|
||||||
class FileObjectClassTestCase(SocketConnectedTest):
|
class FileObjectClassTestCase(SocketConnectedTest):
|
||||||
"""Unit tests for the object returned by socket.makefile()
|
"""Unit tests for the object returned by socket.makefile()
|
||||||
|
|
||||||
self.serv_file is the io object returned by makefile() on
|
self.read_file is the io object returned by makefile() on
|
||||||
the client connection. You can read from this file to
|
the client connection. You can read from this file to
|
||||||
get output from the server.
|
get output from the server.
|
||||||
|
|
||||||
self.cli_file is the io object returned by makefile() on the
|
self.write_file is the io object returned by makefile() on the
|
||||||
server connection. You can write to this file to send output
|
server connection. You can write to this file to send output
|
||||||
to the client.
|
to the client.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
bufsize = -1 # Use default buffer size
|
bufsize = -1 # Use default buffer size
|
||||||
|
encoding = 'utf8'
|
||||||
|
errors = 'strict'
|
||||||
|
newline = None
|
||||||
|
|
||||||
|
read_mode = 'rb'
|
||||||
|
read_msg = MSG
|
||||||
|
write_mode = 'wb'
|
||||||
|
write_msg = MSG
|
||||||
|
|
||||||
def __init__(self, methodName='runTest'):
|
def __init__(self, methodName='runTest'):
|
||||||
SocketConnectedTest.__init__(self, methodName=methodName)
|
SocketConnectedTest.__init__(self, methodName=methodName)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
SocketConnectedTest.setUp(self)
|
SocketConnectedTest.setUp(self)
|
||||||
self.serv_file = self.cli_conn.makefile('rb', self.bufsize)
|
self.read_file = self.cli_conn.makefile(
|
||||||
|
self.read_mode, self.bufsize,
|
||||||
|
encoding = self.encoding,
|
||||||
|
errors = self.errors,
|
||||||
|
newline = self.newline)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.serv_file.close()
|
self.read_file.close()
|
||||||
self.assertTrue(self.serv_file.closed)
|
self.assertTrue(self.read_file.closed)
|
||||||
self.serv_file = None
|
self.read_file = None
|
||||||
SocketConnectedTest.tearDown(self)
|
SocketConnectedTest.tearDown(self)
|
||||||
|
|
||||||
def clientSetUp(self):
|
def clientSetUp(self):
|
||||||
SocketConnectedTest.clientSetUp(self)
|
SocketConnectedTest.clientSetUp(self)
|
||||||
self.cli_file = self.serv_conn.makefile('wb')
|
self.write_file = self.serv_conn.makefile(
|
||||||
|
self.write_mode, self.bufsize,
|
||||||
|
encoding = self.encoding,
|
||||||
|
errors = self.errors,
|
||||||
|
newline = self.newline)
|
||||||
|
|
||||||
def clientTearDown(self):
|
def clientTearDown(self):
|
||||||
self.cli_file.close()
|
self.write_file.close()
|
||||||
self.assertTrue(self.cli_file.closed)
|
self.assertTrue(self.write_file.closed)
|
||||||
self.cli_file = None
|
self.write_file = None
|
||||||
SocketConnectedTest.clientTearDown(self)
|
SocketConnectedTest.clientTearDown(self)
|
||||||
|
|
||||||
def testSmallRead(self):
|
def testSmallRead(self):
|
||||||
# Performing small file read test
|
# Performing small file read test
|
||||||
first_seg = self.serv_file.read(len(MSG)-3)
|
first_seg = self.read_file.read(len(self.read_msg)-3)
|
||||||
second_seg = self.serv_file.read(3)
|
second_seg = self.read_file.read(3)
|
||||||
msg = first_seg + second_seg
|
msg = first_seg + second_seg
|
||||||
self.assertEqual(msg, MSG)
|
self.assertEqual(msg, self.read_msg)
|
||||||
|
|
||||||
def _testSmallRead(self):
|
def _testSmallRead(self):
|
||||||
self.cli_file.write(MSG)
|
self.write_file.write(self.write_msg)
|
||||||
self.cli_file.flush()
|
self.write_file.flush()
|
||||||
|
|
||||||
def testFullRead(self):
|
def testFullRead(self):
|
||||||
# read until EOF
|
# read until EOF
|
||||||
msg = self.serv_file.read()
|
msg = self.read_file.read()
|
||||||
self.assertEqual(msg, MSG)
|
self.assertEqual(msg, self.read_msg)
|
||||||
|
|
||||||
def _testFullRead(self):
|
def _testFullRead(self):
|
||||||
self.cli_file.write(MSG)
|
self.write_file.write(self.write_msg)
|
||||||
self.cli_file.close()
|
self.write_file.close()
|
||||||
|
|
||||||
def testUnbufferedRead(self):
|
def testUnbufferedRead(self):
|
||||||
# Performing unbuffered file read test
|
# Performing unbuffered file read test
|
||||||
buf = b''
|
buf = type(self.read_msg)()
|
||||||
while 1:
|
while 1:
|
||||||
char = self.serv_file.read(1)
|
char = self.read_file.read(1)
|
||||||
if not char:
|
if not char:
|
||||||
break
|
break
|
||||||
buf += char
|
buf += char
|
||||||
self.assertEqual(buf, MSG)
|
self.assertEqual(buf, self.read_msg)
|
||||||
|
|
||||||
def _testUnbufferedRead(self):
|
def _testUnbufferedRead(self):
|
||||||
self.cli_file.write(MSG)
|
self.write_file.write(self.write_msg)
|
||||||
self.cli_file.flush()
|
self.write_file.flush()
|
||||||
|
|
||||||
def testReadline(self):
|
def testReadline(self):
|
||||||
# Performing file readline test
|
# Performing file readline test
|
||||||
line = self.serv_file.readline()
|
line = self.read_file.readline()
|
||||||
self.assertEqual(line, MSG)
|
self.assertEqual(line, self.read_msg)
|
||||||
|
|
||||||
def _testReadline(self):
|
def _testReadline(self):
|
||||||
self.cli_file.write(MSG)
|
self.write_file.write(self.write_msg)
|
||||||
self.cli_file.flush()
|
self.write_file.flush()
|
||||||
|
|
||||||
def testCloseAfterMakefile(self):
|
def testCloseAfterMakefile(self):
|
||||||
# The file returned by makefile should keep the socket open.
|
# The file returned by makefile should keep the socket open.
|
||||||
self.cli_conn.close()
|
self.cli_conn.close()
|
||||||
# read until EOF
|
# read until EOF
|
||||||
msg = self.serv_file.read()
|
msg = self.read_file.read()
|
||||||
self.assertEqual(msg, MSG)
|
self.assertEqual(msg, self.read_msg)
|
||||||
|
|
||||||
def _testCloseAfterMakefile(self):
|
def _testCloseAfterMakefile(self):
|
||||||
self.cli_file.write(MSG)
|
self.write_file.write(self.write_msg)
|
||||||
self.cli_file.flush()
|
self.write_file.flush()
|
||||||
|
|
||||||
def testMakefileAfterMakefileClose(self):
|
def testMakefileAfterMakefileClose(self):
|
||||||
self.serv_file.close()
|
self.read_file.close()
|
||||||
msg = self.cli_conn.recv(len(MSG))
|
msg = self.cli_conn.recv(len(MSG))
|
||||||
self.assertEqual(msg, MSG)
|
if isinstance(self.read_msg, str):
|
||||||
|
msg = msg.decode()
|
||||||
|
self.assertEqual(msg, self.read_msg)
|
||||||
|
|
||||||
def _testMakefileAfterMakefileClose(self):
|
def _testMakefileAfterMakefileClose(self):
|
||||||
self.cli_file.write(MSG)
|
self.write_file.write(self.write_msg)
|
||||||
self.cli_file.flush()
|
self.write_file.flush()
|
||||||
|
|
||||||
def testClosedAttr(self):
|
def testClosedAttr(self):
|
||||||
self.assertTrue(not self.serv_file.closed)
|
self.assertTrue(not self.read_file.closed)
|
||||||
|
|
||||||
def _testClosedAttr(self):
|
def _testClosedAttr(self):
|
||||||
self.assertTrue(not self.cli_file.closed)
|
self.assertTrue(not self.write_file.closed)
|
||||||
|
|
||||||
def testAttributes(self):
|
def testAttributes(self):
|
||||||
self.assertEqual(self.serv_file.mode, 'rb')
|
self.assertEqual(self.read_file.mode, self.read_mode)
|
||||||
self.assertEqual(self.serv_file.name, self.cli_conn.fileno())
|
self.assertEqual(self.read_file.name, self.cli_conn.fileno())
|
||||||
|
|
||||||
def _testAttributes(self):
|
def _testAttributes(self):
|
||||||
self.assertEqual(self.cli_file.mode, 'wb')
|
self.assertEqual(self.write_file.mode, self.write_mode)
|
||||||
self.assertEqual(self.cli_file.name, self.serv_conn.fileno())
|
self.assertEqual(self.write_file.name, self.serv_conn.fileno())
|
||||||
|
|
||||||
def testRealClose(self):
|
def testRealClose(self):
|
||||||
self.serv_file.close()
|
self.read_file.close()
|
||||||
self.assertRaises(ValueError, self.serv_file.fileno)
|
self.assertRaises(ValueError, self.read_file.fileno)
|
||||||
self.cli_conn.close()
|
self.cli_conn.close()
|
||||||
self.assertRaises(socket.error, self.cli_conn.getsockname)
|
self.assertRaises(socket.error, self.cli_conn.getsockname)
|
||||||
|
|
||||||
|
@ -1005,33 +1023,33 @@ class UnbufferedFileObjectClassTestCase(FileObjectClassTestCase):
|
||||||
|
|
||||||
def testUnbufferedReadline(self):
|
def testUnbufferedReadline(self):
|
||||||
# Read a line, create a new file object, read another line with it
|
# Read a line, create a new file object, read another line with it
|
||||||
line = self.serv_file.readline() # first line
|
line = self.read_file.readline() # first line
|
||||||
self.assertEqual(line, b"A. " + MSG) # first line
|
self.assertEqual(line, b"A. " + self.write_msg) # first line
|
||||||
self.serv_file = self.cli_conn.makefile('rb', 0)
|
self.read_file = self.cli_conn.makefile('rb', 0)
|
||||||
line = self.serv_file.readline() # second line
|
line = self.read_file.readline() # second line
|
||||||
self.assertEqual(line, b"B. " + MSG) # second line
|
self.assertEqual(line, b"B. " + self.write_msg) # second line
|
||||||
|
|
||||||
def _testUnbufferedReadline(self):
|
def _testUnbufferedReadline(self):
|
||||||
self.cli_file.write(b"A. " + MSG)
|
self.write_file.write(b"A. " + self.write_msg)
|
||||||
self.cli_file.write(b"B. " + MSG)
|
self.write_file.write(b"B. " + self.write_msg)
|
||||||
self.cli_file.flush()
|
self.write_file.flush()
|
||||||
|
|
||||||
def testMakefileClose(self):
|
def testMakefileClose(self):
|
||||||
# The file returned by makefile should keep the socket open...
|
# The file returned by makefile should keep the socket open...
|
||||||
self.cli_conn.close()
|
self.cli_conn.close()
|
||||||
msg = self.cli_conn.recv(1024)
|
msg = self.cli_conn.recv(1024)
|
||||||
self.assertEqual(msg, MSG)
|
self.assertEqual(msg, self.read_msg)
|
||||||
# ...until the file is itself closed
|
# ...until the file is itself closed
|
||||||
self.serv_file.close()
|
self.read_file.close()
|
||||||
self.assertRaises(socket.error, self.cli_conn.recv, 1024)
|
self.assertRaises(socket.error, self.cli_conn.recv, 1024)
|
||||||
|
|
||||||
def _testMakefileClose(self):
|
def _testMakefileClose(self):
|
||||||
self.cli_file.write(MSG)
|
self.write_file.write(self.write_msg)
|
||||||
self.cli_file.flush()
|
self.write_file.flush()
|
||||||
|
|
||||||
def testMakefileCloseSocketDestroy(self):
|
def testMakefileCloseSocketDestroy(self):
|
||||||
refcount_before = sys.getrefcount(self.cli_conn)
|
refcount_before = sys.getrefcount(self.cli_conn)
|
||||||
self.serv_file.close()
|
self.read_file.close()
|
||||||
refcount_after = sys.getrefcount(self.cli_conn)
|
refcount_after = sys.getrefcount(self.cli_conn)
|
||||||
self.assertEqual(refcount_before - 1, refcount_after)
|
self.assertEqual(refcount_before - 1, refcount_after)
|
||||||
|
|
||||||
|
@ -1049,6 +1067,36 @@ class SmallBufferedFileObjectClassTestCase(FileObjectClassTestCase):
|
||||||
bufsize = 2 # Exercise the buffering code
|
bufsize = 2 # Exercise the buffering code
|
||||||
|
|
||||||
|
|
||||||
|
class UnicodeReadFileObjectClassTestCase(FileObjectClassTestCase):
|
||||||
|
"""Tests for socket.makefile() in text mode (rather than binary)"""
|
||||||
|
|
||||||
|
read_mode = 'r'
|
||||||
|
read_msg = MSG.decode('utf8')
|
||||||
|
write_mode = 'wb'
|
||||||
|
write_msg = MSG
|
||||||
|
newline = ''
|
||||||
|
|
||||||
|
|
||||||
|
class UnicodeWriteFileObjectClassTestCase(FileObjectClassTestCase):
|
||||||
|
"""Tests for socket.makefile() in text mode (rather than binary)"""
|
||||||
|
|
||||||
|
read_mode = 'rb'
|
||||||
|
read_msg = MSG
|
||||||
|
write_mode = 'w'
|
||||||
|
write_msg = MSG.decode('utf8')
|
||||||
|
newline = ''
|
||||||
|
|
||||||
|
|
||||||
|
class UnicodeReadWriteFileObjectClassTestCase(FileObjectClassTestCase):
|
||||||
|
"""Tests for socket.makefile() in text mode (rather than binary)"""
|
||||||
|
|
||||||
|
read_mode = 'r'
|
||||||
|
read_msg = MSG.decode('utf8')
|
||||||
|
write_mode = 'w'
|
||||||
|
write_msg = MSG.decode('utf8')
|
||||||
|
newline = ''
|
||||||
|
|
||||||
|
|
||||||
class NetworkConnectionTest(object):
|
class NetworkConnectionTest(object):
|
||||||
"""Prove network connection."""
|
"""Prove network connection."""
|
||||||
|
|
||||||
|
@ -1426,6 +1474,9 @@ def test_main():
|
||||||
UnbufferedFileObjectClassTestCase,
|
UnbufferedFileObjectClassTestCase,
|
||||||
LineBufferedFileObjectClassTestCase,
|
LineBufferedFileObjectClassTestCase,
|
||||||
SmallBufferedFileObjectClassTestCase,
|
SmallBufferedFileObjectClassTestCase,
|
||||||
|
UnicodeReadFileObjectClassTestCase,
|
||||||
|
UnicodeWriteFileObjectClassTestCase,
|
||||||
|
UnicodeReadWriteFileObjectClassTestCase,
|
||||||
NetworkConnectionNoServer,
|
NetworkConnectionNoServer,
|
||||||
NetworkConnectionAttributesTest,
|
NetworkConnectionAttributesTest,
|
||||||
NetworkConnectionBehaviourTest,
|
NetworkConnectionBehaviourTest,
|
||||||
|
|
|
@ -872,5 +872,6 @@ Artur Zaprzala
|
||||||
Mike Zarnstorff
|
Mike Zarnstorff
|
||||||
Siebren van der Zee
|
Siebren van der Zee
|
||||||
Uwe Zessin
|
Uwe Zessin
|
||||||
|
Kai Zhu
|
||||||
Tarek Ziadé
|
Tarek Ziadé
|
||||||
Peter Åstrand
|
Peter Åstrand
|
||||||
|
|
|
@ -125,6 +125,10 @@ C-API
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #10041: The signature of optional arguments in socket.makefile()
|
||||||
|
didn't match that of io.open(), and they also didn't get forwarded
|
||||||
|
properly to TextIOWrapper in text mode. Patch by Kai Zhu.
|
||||||
|
|
||||||
- Issue #6612: Fix site and sysconfig to catch os.getcwd() error, eg. if the
|
- Issue #6612: Fix site and sysconfig to catch os.getcwd() error, eg. if the
|
||||||
current directory was deleted. Patch written by W. Trevor King.
|
current directory was deleted. Patch written by W. Trevor King.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue