summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Heimes <christian@python.org>2017-09-07 21:18:21 (GMT)
committerGitHub <noreply@github.com>2017-09-07 21:18:21 (GMT)
commit888bbdc192ec4db888a294ef758cf5510442dc9a (patch)
tree3b4be0554916502e37ef83efd8ea7e11e6ef8c70
parent17c9ac927b97472dd080174fde709d9234848195 (diff)
downloadcpython-888bbdc192ec4db888a294ef758cf5510442dc9a.zip
cpython-888bbdc192ec4db888a294ef758cf5510442dc9a.tar.gz
cpython-888bbdc192ec4db888a294ef758cf5510442dc9a.tar.bz2
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@python.org> * Cast view to bytes, fix typo Signed-off-by: Christian Heimes <christian@python.org>
-rw-r--r--Lib/ssl.py9
-rw-r--r--Lib/test/test_ssl.py12
-rw-r--r--Misc/NEWS.d/next/Library/2017-09-06-06-50-41.bpo-27340.GgekV5.rst3
3 files changed, 19 insertions, 5 deletions
diff --git a/Lib/ssl.py b/Lib/ssl.py
index 8ad4a33..7a574dc 100644
--- a/Lib/ssl.py
+++ b/Lib/ssl.py
@@ -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)
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index 89b4609..747661b 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -18,6 +18,10 @@ import asyncore
import weakref
import platform
import functools
+try:
+ import ctypes
+except ImportError:
+ ctypes = None
ssl = support.import_module("ssl")
@@ -2891,6 +2895,13 @@ class ThreadedTests(unittest.TestCase):
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 @@ class ThreadedTests(unittest.TestCase):
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 0000000..2d05e10
--- /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.