[Python-checkins] bpo-27340: Use memoryview in SSLSocket.sendall() (#3384)

Christian Heimes webhook-mailer at python.org
Thu Sep 7 18:26:38 EDT 2017


https://github.com/python/cpython/commit/888bbdc192ec4db888a294ef758cf5510442dc9a
commit: 888bbdc192ec4db888a294ef758cf5510442dc9a
branch: master
author: Christian Heimes <christian at python.org>
committer: GitHub <noreply at github.com>
date: 2017-09-07T14:18:21-07:00
summary:

bpo-27340: Use memoryview in SSLSocket.sendall() (#3384)

* bpo-27340: Use memoryview in SSLSocket.sendall()

SSLSocket.sendall() now uses memoryview to create slices of data. This fix
support for all bytes-like object. It is also more efficient and avoids
costly copies.

Signed-off-by: Christian Heimes <christian at python.org>

* Cast view to bytes, fix typo

Signed-off-by: Christian Heimes <christian at python.org>

files:
A Misc/NEWS.d/next/Library/2017-09-06-06-50-41.bpo-27340.GgekV5.rst
M Lib/ssl.py
M Lib/test/test_ssl.py

diff --git a/Lib/ssl.py b/Lib/ssl.py
index 8ad4a339a93..7a574dcb2b1 100644
--- a/Lib/ssl.py
+++ b/Lib/ssl.py
@@ -959,11 +959,12 @@ def sendall(self, data, flags=0):
                 raise ValueError(
                     "non-zero flags not allowed in calls to sendall() on %s" %
                     self.__class__)
-            amount = len(data)
             count = 0
-            while (count < amount):
-                v = self.send(data[count:])
-                count += v
+            with memoryview(data) as view, view.cast("B") as byte_view:
+                amount = len(byte_view)
+                while count < amount:
+                    v = self.send(byte_view[count:])
+                    count += v
         else:
             return socket.sendall(self, data, flags)
 
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index 89b4609282f..747661bc6d0 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -18,6 +18,10 @@
 import weakref
 import platform
 import functools
+try:
+    import ctypes
+except ImportError:
+    ctypes = None
 
 ssl = support.import_module("ssl")
 
@@ -2891,6 +2895,13 @@ def _recvfrom_into():
             self.assertEqual(s.read(-1, buffer), len(data))
             self.assertEqual(buffer, data)
 
+            # sendall accepts bytes-like objects
+            if ctypes is not None:
+                ubyte = ctypes.c_ubyte * len(data)
+                byteslike = ubyte.from_buffer_copy(data)
+                s.sendall(byteslike)
+                self.assertEqual(s.read(), data)
+
             # Make sure sendmsg et al are disallowed to avoid
             # inadvertent disclosure of data and/or corruption
             # of the encrypted data stream
@@ -2898,7 +2909,6 @@ def _recvfrom_into():
             self.assertRaises(NotImplementedError, s.recvmsg, 100)
             self.assertRaises(NotImplementedError,
                               s.recvmsg_into, bytearray(100))
-
             s.write(b"over\n")
 
             self.assertRaises(ValueError, s.recv, -1)
diff --git a/Misc/NEWS.d/next/Library/2017-09-06-06-50-41.bpo-27340.GgekV5.rst b/Misc/NEWS.d/next/Library/2017-09-06-06-50-41.bpo-27340.GgekV5.rst
new file mode 100644
index 00000000000..2d05e10fc14
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2017-09-06-06-50-41.bpo-27340.GgekV5.rst
@@ -0,0 +1,3 @@
+SSLSocket.sendall() now uses memoryview to create slices of data. This fixes
+support for all bytes-like object. It is also more efficient and avoids
+costly copies.



More information about the Python-checkins mailing list