]> granicus.if.org Git - python/commitdiff
[3.6] bpo-27340: Use memoryview in SSLSocket.sendall() (GH-3384) (#3434)
authorChristian Heimes <christian@python.org>
Thu, 7 Sep 2017 23:59:17 +0000 (16:59 -0700)
committerGitHub <noreply@github.com>
Thu, 7 Sep 2017 23:59:17 +0000 (16:59 -0700)
* 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@python.org>
* Cast view to bytes, fix typo

Signed-off-by: Christian Heimes <christian@python.org>.
(cherry picked from commit 888bbdc192ec4db888a294ef758cf5510442dc9a)

Lib/ssl.py
Lib/test/test_ssl.py
Misc/NEWS.d/next/Library/2017-09-06-06-50-41.bpo-27340.GgekV5.rst [new file with mode: 0644]

index 8ad4a339a933d726b5027899b4d3cf1923c233a7..7a574dcb2b1e5a1368aa8dfb495613ba9eb5855d 100644 (file)
@@ -959,11 +959,12 @@ class SSLSocket(socket):
                 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)
 
index 4191d9036e4cb84360f91cfad27b32ef2bf4679a..157e6ced01b9dc349ac8580483e6104f03ffa3b9 100644 (file)
@@ -18,6 +18,10 @@ import asyncore
 import weakref
 import platform
 import functools
+try:
+    import ctypes
+except ImportError:
+    ctypes = None
 
 ssl = support.import_module("ssl")
 
@@ -2882,7 +2886,13 @@ if _have_threads:
                 s.send(data)
                 buffer = bytearray(len(data))
                 self.assertEqual(s.read(-1, buffer), len(data))
-                self.assertEqual(buffer, 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
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 (file)
index 0000000..2d05e10
--- /dev/null
@@ -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.