summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/socket.rst2
-rw-r--r--Lib/socket.py4
-rw-r--r--Lib/test/test_socket.py167
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS4
5 files changed, 117 insertions, 61 deletions
diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst
index 931dd14..391216e 100644
--- a/Doc/library/socket.rst
+++ b/Doc/library/socket.rst
@@ -588,7 +588,7 @@ correspond to Unix system calls applicable to sockets.
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
diff --git a/Lib/socket.py b/Lib/socket.py
index f94c469..d035061 100644
--- a/Lib/socket.py
+++ b/Lib/socket.py
@@ -121,7 +121,7 @@ class socket(_socket.socket):
return socket(self.family, self.type, self.proto, fileno=fd), addr
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
The arguments are as for io.open() after the filename,
@@ -159,7 +159,7 @@ class socket(_socket.socket):
buffer = io.BufferedWriter(raw, buffering)
if binary:
return buffer
- text = io.TextIOWrapper(buffer, encoding, newline)
+ text = io.TextIOWrapper(buffer, encoding, errors, newline)
text.mode = mode
return text
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index ea83cd1..c33c823 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -32,7 +32,7 @@ def try_address(host, port=0, family=socket.AF_INET):
return True
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)
class SocketTCPTest(unittest.TestCase):
@@ -870,120 +870,138 @@ class NonBlockingTCPTests(ThreadedTCPSocketTest):
class FileObjectClassTestCase(SocketConnectedTest):
"""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
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
to the client.
"""
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'):
SocketConnectedTest.__init__(self, methodName=methodName)
def 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):
- self.serv_file.close()
- self.assertTrue(self.serv_file.closed)
- self.serv_file = None
+ self.read_file.close()
+ self.assertTrue(self.read_file.closed)
+ self.read_file = None
SocketConnectedTest.tearDown(self)
def 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):
- self.cli_file.close()
- self.assertTrue(self.cli_file.closed)
- self.cli_file = None
+ self.write_file.close()
+ self.assertTrue(self.write_file.closed)
+ self.write_file = None
SocketConnectedTest.clientTearDown(self)
def testSmallRead(self):
# Performing small file read test
- first_seg = self.serv_file.read(len(MSG)-3)
- second_seg = self.serv_file.read(3)
+ first_seg = self.read_file.read(len(self.read_msg)-3)
+ second_seg = self.read_file.read(3)
msg = first_seg + second_seg
- self.assertEqual(msg, MSG)
+ self.assertEqual(msg, self.read_msg)
def _testSmallRead(self):
- self.cli_file.write(MSG)
- self.cli_file.flush()
+ self.write_file.write(self.write_msg)
+ self.write_file.flush()
def testFullRead(self):
# read until EOF
- msg = self.serv_file.read()
- self.assertEqual(msg, MSG)
+ msg = self.read_file.read()
+ self.assertEqual(msg, self.read_msg)
def _testFullRead(self):
- self.cli_file.write(MSG)
- self.cli_file.close()
+ self.write_file.write(self.write_msg)
+ self.write_file.close()
def testUnbufferedRead(self):
# Performing unbuffered file read test
- buf = b''
+ buf = type(self.read_msg)()
while 1:
- char = self.serv_file.read(1)
+ char = self.read_file.read(1)
if not char:
break
buf += char
- self.assertEqual(buf, MSG)
+ self.assertEqual(buf, self.read_msg)
def _testUnbufferedRead(self):
- self.cli_file.write(MSG)
- self.cli_file.flush()
+ self.write_file.write(self.write_msg)
+ self.write_file.flush()
def testReadline(self):
# Performing file readline test
- line = self.serv_file.readline()
- self.assertEqual(line, MSG)
+ line = self.read_file.readline()
+ self.assertEqual(line, self.read_msg)
def _testReadline(self):
- self.cli_file.write(MSG)
- self.cli_file.flush()
+ self.write_file.write(self.write_msg)
+ self.write_file.flush()
def testCloseAfterMakefile(self):
# The file returned by makefile should keep the socket open.
self.cli_conn.close()
# read until EOF
- msg = self.serv_file.read()
- self.assertEqual(msg, MSG)
+ msg = self.read_file.read()
+ self.assertEqual(msg, self.read_msg)
def _testCloseAfterMakefile(self):
- self.cli_file.write(MSG)
- self.cli_file.flush()
+ self.write_file.write(self.write_msg)
+ self.write_file.flush()
def testMakefileAfterMakefileClose(self):
- self.serv_file.close()
+ self.read_file.close()
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):
- self.cli_file.write(MSG)
- self.cli_file.flush()
+ self.write_file.write(self.write_msg)
+ self.write_file.flush()
def testClosedAttr(self):
- self.assertTrue(not self.serv_file.closed)
+ self.assertTrue(not self.read_file.closed)
def _testClosedAttr(self):
- self.assertTrue(not self.cli_file.closed)
+ self.assertTrue(not self.write_file.closed)
def testAttributes(self):
- self.assertEqual(self.serv_file.mode, 'rb')
- self.assertEqual(self.serv_file.name, self.cli_conn.fileno())
+ self.assertEqual(self.read_file.mode, self.read_mode)
+ self.assertEqual(self.read_file.name, self.cli_conn.fileno())
def _testAttributes(self):
- self.assertEqual(self.cli_file.mode, 'wb')
- self.assertEqual(self.cli_file.name, self.serv_conn.fileno())
+ self.assertEqual(self.write_file.mode, self.write_mode)
+ self.assertEqual(self.write_file.name, self.serv_conn.fileno())
def testRealClose(self):
- self.serv_file.close()
- self.assertRaises(ValueError, self.serv_file.fileno)
+ self.read_file.close()
+ self.assertRaises(ValueError, self.read_file.fileno)
self.cli_conn.close()
self.assertRaises(socket.error, self.cli_conn.getsockname)
@@ -1005,33 +1023,33 @@ class UnbufferedFileObjectClassTestCase(FileObjectClassTestCase):
def testUnbufferedReadline(self):
# Read a line, create a new file object, read another line with it
- line = self.serv_file.readline() # first line
- self.assertEqual(line, b"A. " + MSG) # first line
- self.serv_file = self.cli_conn.makefile('rb', 0)
- line = self.serv_file.readline() # second line
- self.assertEqual(line, b"B. " + MSG) # second line
+ line = self.read_file.readline() # first line
+ self.assertEqual(line, b"A. " + self.write_msg) # first line
+ self.read_file = self.cli_conn.makefile('rb', 0)
+ line = self.read_file.readline() # second line
+ self.assertEqual(line, b"B. " + self.write_msg) # second line
def _testUnbufferedReadline(self):
- self.cli_file.write(b"A. " + MSG)
- self.cli_file.write(b"B. " + MSG)
- self.cli_file.flush()
+ self.write_file.write(b"A. " + self.write_msg)
+ self.write_file.write(b"B. " + self.write_msg)
+ self.write_file.flush()
def testMakefileClose(self):
# The file returned by makefile should keep the socket open...
self.cli_conn.close()
msg = self.cli_conn.recv(1024)
- self.assertEqual(msg, MSG)
+ self.assertEqual(msg, self.read_msg)
# ...until the file is itself closed
- self.serv_file.close()
+ self.read_file.close()
self.assertRaises(socket.error, self.cli_conn.recv, 1024)
def _testMakefileClose(self):
- self.cli_file.write(MSG)
- self.cli_file.flush()
+ self.write_file.write(self.write_msg)
+ self.write_file.flush()
def testMakefileCloseSocketDestroy(self):
refcount_before = sys.getrefcount(self.cli_conn)
- self.serv_file.close()
+ self.read_file.close()
refcount_after = sys.getrefcount(self.cli_conn)
self.assertEqual(refcount_before - 1, refcount_after)
@@ -1049,6 +1067,36 @@ class SmallBufferedFileObjectClassTestCase(FileObjectClassTestCase):
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):
"""Prove network connection."""
@@ -1426,6 +1474,9 @@ def test_main():
UnbufferedFileObjectClassTestCase,
LineBufferedFileObjectClassTestCase,
SmallBufferedFileObjectClassTestCase,
+ UnicodeReadFileObjectClassTestCase,
+ UnicodeWriteFileObjectClassTestCase,
+ UnicodeReadWriteFileObjectClassTestCase,
NetworkConnectionNoServer,
NetworkConnectionAttributesTest,
NetworkConnectionBehaviourTest,
diff --git a/Misc/ACKS b/Misc/ACKS
index ece5f56..01d18ec 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -872,5 +872,6 @@ Artur Zaprzala
Mike Zarnstorff
Siebren van der Zee
Uwe Zessin
+Kai Zhu
Tarek Ziadé
Peter Ã…strand
diff --git a/Misc/NEWS b/Misc/NEWS
index f4ba9db..e3e7080 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -125,6 +125,10 @@ C-API
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
current directory was deleted. Patch written by W. Trevor King.