From 3fe64d0c5ca5f1dc9723b9ef436d033f390b19f0 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Thu, 18 Feb 2016 17:34:00 +0200 Subject: [PATCH] Issue #16915: Clarify that mode parameter of socket.makefile() does not accept the same values as open(). --- Doc/library/socket.rst | 3 ++- Lib/socket.py | 6 +++--- Lib/test/test_socket.py | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 4276478489..a0b02c032f 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -1006,7 +1006,8 @@ to sockets. Return a :term:`file object` associated with the socket. The exact returned type depends on the arguments given to :meth:`makefile`. These arguments are - interpreted the same way as by the built-in :func:`open` function. + interpreted the same way as by the built-in :func:`open` function, except + the only supported *mode* values are ``'r'`` (default), ``'w'`` and ``'b'``. The socket must be in blocking mode; it can have a timeout, but the file object's internal buffer may end up in an inconsistent state if a timeout diff --git a/Lib/socket.py b/Lib/socket.py index ed1b10a254..95ce9eb61c 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -209,10 +209,10 @@ class socket(_socket.socket): 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, - except the only mode characters supported are 'r', 'w' and 'b'. - The semantics are similar too. (XXX refactor to share code?) + The arguments are as for io.open() after the filename, except the only + supported mode values are 'r' (default), 'w' and 'b'. """ + # XXX refactor to share code? if not set(mode) <= {"r", "w", "b"}: raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,)) writing = "w" in mode diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 1e355ea8fe..3d6d205e02 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -1374,6 +1374,20 @@ class GeneralModuleTests(unittest.TestCase): self.assertRaises(ValueError, fp.writable) self.assertRaises(ValueError, fp.seekable) + def test_makefile_mode(self): + for mode in 'r', 'rb', 'rw', 'w', 'wb': + with self.subTest(mode=mode): + with socket.socket() as sock: + with sock.makefile(mode) as fp: + self.assertEqual(fp.mode, mode) + + def test_makefile_invalid_mode(self): + for mode in 'rt', 'x', '+', 'a': + with self.subTest(mode=mode): + with socket.socket() as sock: + with self.assertRaisesRegex(ValueError, 'invalid mode'): + sock.makefile(mode) + def test_pickle(self): sock = socket.socket() with sock: -- 2.40.0