Skip to content

Commit 2380fee

Browse files
author
Kristján Valur Jónsson
committed
issue #879399
Fix line buffering of socket._fileobject
1 parent 513e9b4 commit 2380fee

2 files changed

Lines changed: 61 additions & 3 deletions

File tree

Lib/socket.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,8 @@ def write(self, data):
319319
self._wbuf.append(data)
320320
self._wbuf_len += len(data)
321321
if (self._wbufsize == 0 or
322-
self._wbufsize == 1 and '\n' in data or
323-
self._wbuf_len >= self._wbufsize):
322+
(self._wbufsize == 1 and '\n' in data) or
323+
(self._wbufsize > 1 and self._wbuf_len >= self._wbufsize)):
324324
self.flush()
325325

326326
def writelines(self, list):

Lib/test/test_socket.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -962,8 +962,8 @@ def setUp(self):
962962
def tearDown(self):
963963
self.serv_file.close()
964964
self.assertTrue(self.serv_file.closed)
965-
self.serv_file = None
966965
SocketConnectedTest.tearDown(self)
966+
self.serv_file = None
967967

968968
def clientSetUp(self):
969969
SocketConnectedTest.clientSetUp(self)
@@ -1151,6 +1151,64 @@ class LineBufferedFileObjectClassTestCase(FileObjectClassTestCase):
11511151

11521152
bufsize = 1 # Default-buffered for reading; line-buffered for writing
11531153

1154+
class SocketMemo(object):
1155+
"""A wrapper to keep track of sent data, needed to examine write behaviour"""
1156+
def __init__(self, sock):
1157+
self._sock = sock
1158+
self.sent = []
1159+
1160+
def send(self, data, flags=0):
1161+
n = self._sock.send(data, flags)
1162+
self.sent.append(data[:n])
1163+
return n
1164+
1165+
def sendall(self, data, flags=0):
1166+
self._sock.sendall(data, flags)
1167+
self.sent.append(data)
1168+
1169+
def __getattr__(self, attr):
1170+
return getattr(self._sock, attr)
1171+
1172+
def getsent(self):
1173+
return [e.tobytes() if isinstance(e, memoryview) else e for e in self.sent]
1174+
1175+
def setUp(self):
1176+
FileObjectClassTestCase.setUp(self)
1177+
self.serv_file._sock = self.SocketMemo(self.serv_file._sock)
1178+
1179+
def testLinebufferedWrite(self):
1180+
# Write two lines, in small chunks
1181+
msg = MSG.strip()
1182+
print >> self.serv_file, msg,
1183+
print >> self.serv_file, msg
1184+
1185+
# second line:
1186+
print >> self.serv_file, msg,
1187+
print >> self.serv_file, msg,
1188+
print >> self.serv_file, msg
1189+
1190+
# third line
1191+
print >> self.serv_file, ''
1192+
1193+
self.serv_file.flush()
1194+
1195+
msg1 = "%s %s\n"%(msg, msg)
1196+
msg2 = "%s %s %s\n"%(msg, msg, msg)
1197+
msg3 = "\n"
1198+
self.assertEqual(self.serv_file._sock.getsent(), [msg1, msg2, msg3])
1199+
1200+
def _testLinebufferedWrite(self):
1201+
msg = MSG.strip()
1202+
msg1 = "%s %s\n"%(msg, msg)
1203+
msg2 = "%s %s %s\n"%(msg, msg, msg)
1204+
msg3 = "\n"
1205+
l1 = self.cli_file.readline()
1206+
self.assertEqual(l1, msg1)
1207+
l2 = self.cli_file.readline()
1208+
self.assertEqual(l2, msg2)
1209+
l3 = self.cli_file.readline()
1210+
self.assertEqual(l3, msg3)
1211+
11541212

11551213
class SmallBufferedFileObjectClassTestCase(FileObjectClassTestCase):
11561214

0 commit comments

Comments
 (0)