]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-84443: SSLSocket.recv_into() now support buffer protocol with itemsize...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 27 Nov 2023 17:30:53 +0000 (18:30 +0100)
committerGitHub <noreply@github.com>
Mon, 27 Nov 2023 17:30:53 +0000 (17:30 +0000)
It is also no longer use __len__().

(cherry picked from commit 812360fddda86d7aff5823f529ab720f57ddc411)

Co-authored-by: Zackery Spytz <zspytz@gmail.com>
Co-authored-by: Serhiy Storchaka <storchaka@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 c4c5a4ca894ee578bf0b5d080cd8ff6a5f242ca1..3586d3adf9e93bd4e25ab6f0500207cb8a2f785d 100644 (file)
@@ -1237,10 +1237,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 d8ae7b75e1815031ac90c982386738a83b743584..330515a42b3ab83fe6ab3160a2df5b85e175c1b4 100644 (file)
@@ -10,6 +10,7 @@ from test.support import socket_helper
 from test.support import threading_helper
 from test.support import warnings_helper
 from test.support import asyncore
+import array
 import re
 import socket
 import select
@@ -3517,6 +3518,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.