Commit 674f4009 authored by Antoine Pitrou's avatar Antoine Pitrou

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.
........
parent bc5d78d3
...@@ -588,7 +588,7 @@ correspond to Unix system calls applicable to sockets. ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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(): ...@@ -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 ...@@ -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 ...@@ -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.
......
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