8000 bpo-31062: Allow socket.makefile to handle line buffering properly · python/cpython@2eaecd5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2eaecd5

Browse files
committed
bpo-31062: Allow socket.makefile to handle line buffering properly
Line buffering is enabled by using the argument `buffering=1` as defined in `io.open`.
1 parent 5afb570 commit 2eaecd5

File tree

3 files changed

+30
-8
lines changed

3 files changed

+30
-8
lines changed

Lib/socket.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,12 @@ def makefile(self, mode="r", buffering=None, *,
320320
rawmode += "w"
321321
raw = SocketIO(self, rawmode)
322322
self._io_refs += 1
323+
line_buffering = False
323324
if buffering is None:
324325
buffering = -1
326+
if buffering == 1:
327+
buffering = -1
328+
line_buffering = True
325329
if buffering < 0:
326330
buffering = io.DEFAULT_BUFFER_SIZE
327331
if buffering == 0:
@@ -338,7 +342,8 @@ def makefile(self, mode="r", buffering=None, *,
338342
if binary:
339343
return buffer
340344
encoding = io.text_encoding(encoding)
341-
text = io.TextIOWrapper(buffer, encoding, errors, newline)
345+
text = io.TextIOWrapper(
346+
buffer, encoding, errors, newline, line_buffering)
342347
text.mode = mode
343348
return text
344349

Lib/test/test_socket.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4913,10 +4913,20 @@ def testReadline(self):
49134913
# Performing file readline test
49144914
line = self.read_file.readline()
49154915
self.assertEqual(line, self.read_msg)
4916+
# Readline mode
4917+
if self.bufsize == 1 and self.read_mode == "r":
4918+
self.assertTrue(self.read_file.line_buffering)
49164919

49174920
def _testReadline(self):
49184921
self.write_file.write(self.write_msg)
4919-
self.write_file.flush()
4922+
# Readline mode: no need to flush
4923+
if self.bufsize == 1 and self.write_mode == "w":
4924+
self.assertTrue(self.write_file.line_buffering)
4925+
else:
4926+
self.write_file.flush()
4927+
# Prevent garbage collection from flushing
4928+
# until the server has finished
4929+
self.assertTrue(self.serv_finished.wait(5.0))
49204930

49214931
def testCloseAfterMakefile(self):
49224932
# The file returned by makefile should keep the socket open.
@@ -5072,11 +5082,6 @@ def _testWriteNonBlocking(self):
50725082
self.serv_skipped = "failed to saturate the socket buffer"
50735083

50745084

5075-
class LineBufferedFileObjectClassTestCase(FileObjectClassTestCase):
5076-
5077-
bufsize = 1 # Default-buffered for reading; line-buffered for writing
5078-
5079-
50805085
class SmallBufferedFileObjectClassTestCase(FileObjectClassTestCase):
50815086

50825087
bufsize = 2 # Exercise the buffering code
@@ -5112,6 +5117,16 @@ class UnicodeReadWriteFileObjectClassTestCase(FileObjectClassTestCase):
51125117
newline = ''
51135118

51145119

5120+
class UnicodeLineBufferedFileObjectClassTestCase(FileObjectClassTestCase):
5121+
5122+
bufsize = 1 # Default-buffered for reading; line-buffered for writing
5123+
read_mode = 'r'
5124+
read_msg = MSG.decode('utf-8')
5125+
write_mode = 'w'
5126+
write_msg = MSG.decode('utf-8')
5127+
newline = ''
5128+
5129+
51155130
class NetworkConnectionTest(object):
51165131
"""Prove network connection."""
51175132

@@ -6649,11 +6664,11 @@ def test_main():
66496664
NonBlockingTCPTests,
66506665
FileObjectClassTestCase,
66516666
UnbufferedFileObjectClassTestCase,
6652-
LineBufferedFileObjectClassTestCase,
66536667
SmallBufferedFileObjectClassTestCase,
66546668
UnicodeReadFileObjectClassTestCase,
66556669
UnicodeWriteFileObjectClassTestCase,
66566670
UnicodeReadWriteFileObjectClassTestCase,
6671+
UnicodeLineBufferedFileObjectClassTestCase,
66576672
NetworkConnectionNoServer,
66586673
NetworkConnectionAttributesTest,
66596674
NetworkConnectionBehaviourTest,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Allow :meth:`socket.socket.makefile` to handle line buffering properly
2+
(``buffering=1``). This is done by mimicking the behavior of :func:`open`.

0 commit comments

Comments
 (0)
0