]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] gh-84443: SSLSocket.recv_into() now support buffer protocol with itemsize...
authorSerhiy Storchaka <storchaka@gmail.com>
Mon, 27 Nov 2023 17:41:05 +0000 (19:41 +0200)
committerGitHub <noreply@github.com>
Mon, 27 Nov 2023 17:41:05 +0000 (17:41 +0000)
It is also no longer use __len__().

(cherry picked from commit 812360fddda86d7aff5823f529ab720f57ddc411)

Co-authored-by: Zackery Spytz <zspytz@gmail.com>
Lib/ssl.py
Lib/test/test_ssl.py
Misc/NEWS.d/next/Library/2020-05-21-23-32-46.bpo-40262.z4fQv1.rst [new file with mode: 0644]

index 48d229f810af28bb56da0ed902e6e5e4a5e351db..c0350a81b2f0eb638d4589c5909858c5dc9bb37e 100644 (file)
@@ -1299,10 +1299,14 @@ class SSLSocket(socket):
 
     def recv_into(self, buffer, nbytes=None, flags=0):
         self._checkClosed()
-        if buffer and (nbytes is None):
-            nbytes = len(buffer)
-        elif nbytes is None:
-            nbytes = 1024
+        if nbytes is None:
+            if buffer is not None:
+                with memoryview(buffer) as view:
+                    nbytes = view.nbytes
+                if not nbytes:
+                    nbytes = 1024
+            else:
+                nbytes = 1024
         if self._sslobj is not None:
             if flags != 0:
                 raise ValueError(
index b353f3265cbb9e0b1f15f05da722f8cd3c9f91de..1f881038c329b5c3e1c7e159275f9131d2442b41 100644 (file)
@@ -9,6 +9,7 @@ from test.support import os_helper
 from test.support import socket_helper
 from test.support import threading_helper
 from test.support import warnings_helper
+import array
 import re
 import socket
 import select
@@ -3765,6 +3766,27 @@ class ThreadedTests(unittest.TestCase):
         self.assertEqual(s.recv(0), b"")
         self.assertEqual(s.recv_into(bytearray()), 0)
 
+    def test_recv_into_buffer_protocol_len(self):
+        server = ThreadedEchoServer(CERTFILE)
+        self.enterContext(server)
+        s = socket.create_connection((HOST, server.port))
+        self.addCleanup(s.close)
+        s = test_wrap_socket(s, suppress_ragged_eofs=False)
+        self.addCleanup(s.close)
+
+        s.send(b"data")
+        buf = array.array('I', [0, 0])
+        self.assertEqual(s.recv_into(buf), 4)
+        self.assertEqual(bytes(buf)[:4], b"data")
+
+        class B(bytearray):
+            def __len__(self):
+                1/0
+        s.send(b"data")
+        buf = B(6)
+        self.assertEqual(s.recv_into(buf), 4)
+        self.assertEqual(bytes(buf), b"data\0\0")
+
     def test_nonblocking_send(self):
         server = ThreadedEchoServer(CERTFILE,
                                     certreqs=ssl.CERT_NONE,
diff --git a/Misc/NEWS.d/next/Library/2020-05-21-23-32-46.bpo-40262.z4fQv1.rst b/Misc/NEWS.d/next/Library/2020-05-21-23-32-46.bpo-40262.z4fQv1.rst
new file mode 100644 (file)
index 0000000..c017a1c
--- /dev/null
@@ -0,0 +1,2 @@
+The :meth:`ssl.SSLSocket.recv_into` method no longer requires the *buffer*
+argument to implement ``__len__`` and supports buffers with arbitrary item size.