new file mode 100644
@@ -0,0 +1,257 @@
+From 3364e7e62fa24d0e19133fb0f90b1c24ef1110c5 Mon Sep 17 00:00:00 2001
+From: Victor Stinner <vstinner@python.org>
+Date: Wed, 25 Mar 2026 07:44:47 +0100
+Subject: [PATCH] gh-146207: Add support for OpenSSL 4.0.0 alpha1 (#146217)
+
+OpenSSL 4.0.0 alpha1 removed these functions:
+
+* SSLv3_method()
+* TLSv1_method()
+* TLSv1_1_method()
+* TLSv1_2_method()
+
+Other changes:
+
+* Update test_openssl_version().
+* Update multissltests.py for OpenSSL 4.
+* Add const qualifier to fix compiler warnings.
+
+Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
+Signed-off-by: Victor Stinner <vstinner@python.org>
+
+Upstream-Status: Backport [https://github.com/python/cpython/commit/3364e7e62fa24d0e19133fb0f90b1c24ef1110c5]
+Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
+---
+ Lib/test/test_ssl.py | 52 ++++++++++++++++++++------------------
+ Modules/_ssl.c | 27 ++++++++++++++++----
+ Modules/_ssl/cert.c | 3 ++-
+ Tools/ssl/multissltests.py | 7 ++++-
+ 4 files changed, 58 insertions(+), 31 deletions(-)
+
+diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
+index dc795c6bd8a..61355927296 100644
+--- a/Lib/test/test_ssl.py
++++ b/Lib/test/test_ssl.py
+@@ -395,7 +395,7 @@ def test_constants(self):
+ ssl.OP_NO_COMPRESSION
+ self.assertEqual(ssl.HAS_SNI, True)
+ self.assertEqual(ssl.HAS_ECDH, True)
+- self.assertEqual(ssl.HAS_TLSv1_2, True)
++ self.assertIsInstance(ssl.HAS_TLSv1_2, bool)
+ self.assertEqual(ssl.HAS_TLSv1_3, True)
+ ssl.OP_NO_SSLv2
+ ssl.OP_NO_SSLv3
+@@ -586,11 +586,11 @@ def test_openssl_version(self):
+ # Some sanity checks follow
+ # >= 1.1.1
+ self.assertGreaterEqual(n, 0x10101000)
+- # < 4.0
+- self.assertLess(n, 0x40000000)
++ # < 5.0
++ self.assertLess(n, 0x50000000)
+ major, minor, fix, patch, status = t
+ self.assertGreaterEqual(major, 1)
+- self.assertLess(major, 4)
++ self.assertLess(major, 5)
+ self.assertGreaterEqual(minor, 0)
+ self.assertLess(minor, 256)
+ self.assertGreaterEqual(fix, 0)
+@@ -656,12 +656,14 @@ def test_openssl111_deprecations(self):
+ ssl.OP_NO_TLSv1_2,
+ ssl.OP_NO_TLSv1_3
+ ]
+- protocols = [
+- ssl.PROTOCOL_TLSv1,
+- ssl.PROTOCOL_TLSv1_1,
+- ssl.PROTOCOL_TLSv1_2,
+- ssl.PROTOCOL_TLS
+- ]
++ protocols = []
++ if hasattr(ssl, 'PROTOCOL_TLSv1'):
++ protocols.append(ssl.PROTOCOL_TLSv1)
++ if hasattr(ssl, 'PROTOCOL_TLSv1_1'):
++ protocols.append(ssl.PROTOCOL_TLSv1_1)
++ if hasattr(ssl, 'PROTOCOL_TLSv1_2'):
++ protocols.append(ssl.PROTOCOL_TLSv1_2)
++ protocols.append(ssl.PROTOCOL_TLS)
+ versions = [
+ ssl.TLSVersion.SSLv3,
+ ssl.TLSVersion.TLSv1,
+@@ -1205,6 +1207,7 @@ def test_min_max_version(self):
+ ssl.TLSVersion.TLSv1,
+ ssl.TLSVersion.TLSv1_1,
+ ssl.TLSVersion.TLSv1_2,
++ ssl.TLSVersion.TLSv1_3,
+ ssl.TLSVersion.SSLv3,
+ }
+ )
+@@ -1218,7 +1221,7 @@ def test_min_max_version(self):
+ with self.assertRaises(ValueError):
+ ctx.minimum_version = 42
+
+- if has_tls_protocol(ssl.PROTOCOL_TLSv1_1):
++ if has_tls_protocol('PROTOCOL_TLSv1_1'):
+ ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_1)
+
+ self.assertIn(
+@@ -1675,23 +1678,24 @@ def test__create_stdlib_context(self):
+ self.assertFalse(ctx.check_hostname)
+ self._assert_context_options(ctx)
+
+- if has_tls_protocol(ssl.PROTOCOL_TLSv1):
++ if has_tls_protocol('PROTOCOL_TLSv1'):
+ with warnings_helper.check_warnings():
+ ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1)
+ self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
+ self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
+ self._assert_context_options(ctx)
+
+- with warnings_helper.check_warnings():
+- ctx = ssl._create_stdlib_context(
+- ssl.PROTOCOL_TLSv1_2,
+- cert_reqs=ssl.CERT_REQUIRED,
+- check_hostname=True
+- )
+- self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1_2)
+- self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
+- self.assertTrue(ctx.check_hostname)
+- self._assert_context_options(ctx)
++ if has_tls_protocol('PROTOCOL_TLSv1_2'):
++ with warnings_helper.check_warnings():
++ ctx = ssl._create_stdlib_context(
++ ssl.PROTOCOL_TLSv1_2,
++ cert_reqs=ssl.CERT_REQUIRED,
++ check_hostname=True
++ )
++ self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1_2)
++ self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
++ self.assertTrue(ctx.check_hostname)
++ self._assert_context_options(ctx)
+
+ ctx = ssl._create_stdlib_context(purpose=ssl.Purpose.CLIENT_AUTH)
+ self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLS_SERVER)
+@@ -3654,10 +3658,10 @@ def test_protocol_tlsv1_2(self):
+ client_options=ssl.OP_NO_TLSv1_2)
+
+ try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2')
+- if has_tls_protocol(ssl.PROTOCOL_TLSv1):
++ if has_tls_protocol('PROTOCOL_TLSv1'):
+ try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1, False)
+ try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_2, False)
+- if has_tls_protocol(ssl.PROTOCOL_TLSv1_1):
++ if has_tls_protocol('PROTOCOL_TLSv1_1'):
+ try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False)
+ try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_2, False)
+
+diff --git a/Modules/_ssl.c b/Modules/_ssl.c
+index b45295b4c0c..6f75af86113 100644
+--- a/Modules/_ssl.c
++++ b/Modules/_ssl.c
+@@ -164,6 +164,17 @@ static void _PySSLFixErrno(void) {
+ #error Unsupported OpenSSL version
+ #endif
+
++#if (OPENSSL_VERSION_NUMBER >= 0x40000000L)
++# define OPENSSL_NO_SSL3
++# define OPENSSL_NO_TLS1
++# define OPENSSL_NO_TLS1_1
++# define OPENSSL_NO_TLS1_2
++# define OPENSSL_NO_SSL3_METHOD
++# define OPENSSL_NO_TLS1_METHOD
++# define OPENSSL_NO_TLS1_1_METHOD
++# define OPENSSL_NO_TLS1_2_METHOD
++#endif
++
+ /* OpenSSL API 1.1.0+ does not include version methods */
+ #ifndef OPENSSL_NO_SSL3_METHOD
+ extern const SSL_METHOD *SSLv3_method(void);
+@@ -1151,7 +1162,7 @@ _asn1obj2py(_sslmodulestate *state, const ASN1_OBJECT *name, int no_name)
+
+ static PyObject *
+ _create_tuple_for_attribute(_sslmodulestate *state,
+- ASN1_OBJECT *name, ASN1_STRING *value)
++ const ASN1_OBJECT *name, const ASN1_STRING *value)
+ {
+ Py_ssize_t buflen;
+ PyObject *pyattr;
+@@ -1180,16 +1191,16 @@ _create_tuple_for_attribute(_sslmodulestate *state,
+ }
+
+ static PyObject *
+-_create_tuple_for_X509_NAME (_sslmodulestate *state, X509_NAME *xname)
++_create_tuple_for_X509_NAME(_sslmodulestate *state, const X509_NAME *xname)
+ {
+ PyObject *dn = NULL; /* tuple which represents the "distinguished name" */
+ PyObject *rdn = NULL; /* tuple to hold a "relative distinguished name" */
+ PyObject *rdnt;
+ PyObject *attr = NULL; /* tuple to hold an attribute */
+ int entry_count = X509_NAME_entry_count(xname);
+- X509_NAME_ENTRY *entry;
+- ASN1_OBJECT *name;
+- ASN1_STRING *value;
++ const X509_NAME_ENTRY *entry;
++ const ASN1_OBJECT *name;
++ const ASN1_STRING *value;
+ int index_counter;
+ int rdn_level = -1;
+ int retcode;
+@@ -6967,9 +6978,15 @@ sslmodule_init_constants(PyObject *m)
+ ADD_INT_CONST("PROTOCOL_TLS", PY_SSL_VERSION_TLS);
+ ADD_INT_CONST("PROTOCOL_TLS_CLIENT", PY_SSL_VERSION_TLS_CLIENT);
+ ADD_INT_CONST("PROTOCOL_TLS_SERVER", PY_SSL_VERSION_TLS_SERVER);
++#ifndef OPENSSL_NO_TLS1
+ ADD_INT_CONST("PROTOCOL_TLSv1", PY_SSL_VERSION_TLS1);
++#endif
++#ifndef OPENSSL_NO_TLS1_1
+ ADD_INT_CONST("PROTOCOL_TLSv1_1", PY_SSL_VERSION_TLS1_1);
++#endif
++#ifndef OPENSSL_NO_TLS1_2
+ ADD_INT_CONST("PROTOCOL_TLSv1_2", PY_SSL_VERSION_TLS1_2);
++#endif
+
+ #define ADD_OPTION(NAME, VALUE) if (sslmodule_add_option(m, NAME, (VALUE)) < 0) return -1
+
+diff --git a/Modules/_ssl/cert.c b/Modules/_ssl/cert.c
+index f2e7be89668..061b0fb3171 100644
+--- a/Modules/_ssl/cert.c
++++ b/Modules/_ssl/cert.c
+@@ -128,7 +128,8 @@ _ssl_Certificate_get_info_impl(PySSLCertificate *self)
+ }
+
+ static PyObject*
+-_x509name_print(_sslmodulestate *state, X509_NAME *name, int indent, unsigned long flags)
++_x509name_print(_sslmodulestate *state, const X509_NAME *name,
++ int indent, unsigned long flags)
+ {
+ PyObject *res;
+ BIO *biobuf;
+diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py
+index 3b4507c6771..48207e5330f 100755
+--- a/Tools/ssl/multissltests.py
++++ b/Tools/ssl/multissltests.py
+@@ -429,9 +429,11 @@ def _post_install(self):
+ def _post_install(self):
+ if self.version.startswith("3."):
+ self._post_install_3xx()
++ elif self.version.startswith("4."):
++ self._post_install_4xx()
+
+ def _build_src(self, config_args=()):
+- if self.version.startswith("3."):
++ if self.version.startswith(("3.", "4.")):
+ config_args += ("enable-fips",)
+ super()._build_src(config_args)
+
+@@ -447,6 +449,9 @@ def _post_install_3xx(self):
+ lib64 = self.lib_dir + "64"
+ os.symlink(lib64, self.lib_dir)
+
++ def _post_install_4xx(self):
++ self._post_install_3xx()
++
+ @property
+ def short_version(self):
+ """Short version for OpenSSL download URL"""
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,234 @@
+From 3c2a3014af7d73cc34f2498f60fdf863d9bc7c6c Mon Sep 17 00:00:00 2001
+From: Victor Stinner <vstinner@python.org>
+Date: Mon, 4 May 2026 13:52:57 +0200
+Subject: [PATCH] gh-148292: Update _ssl._SSLSocket for OpenSSL 4 (#149102)
+
+The _SSLSocket object now remembers if it gets an EOF error. In this
+case, read(), sendfile(), write() and do_handshake method calls fail
+with SSLEOFError without calling the underlying OpenSSL function.
+
+Co-authored-by: Gregory P. Smith <greg@krypto.org>
+(cherry picked from commit 7b7fa3f9bf3d7cdf3eb669d02b386e05b39c402a)
+
+Upstream-Status: Backport [https://github.com/python/cpython/commit/3c2a3014af7d]
+
+Note: This is from the unmerged CPython PR #149783 which backports
+OpenSSL 4.0 support to the 3.14 branch. Upstream deferred merging
+until after Python 3.15.1 is released.
+
+Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
+---
+ Lib/test/test_ssl.py | 82 +++++++++++++++++++
+ ...-04-28-17-47-55.gh-issue-148292.oIq3ml.rst | 7 ++
+ Modules/_ssl.c | 42 ++++++++++
+ 3 files changed, 131 insertions(+)
+ create mode 100644 Misc/NEWS.d/next/Library/2026-04-28-17-47-55.gh-issue-148292.oIq3ml.rst
+
+diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
+index 965dbc36f096499..03d9e3f9e5e96b5 100644
+--- a/Lib/test/test_ssl.py
++++ b/Lib/test/test_ssl.py
+@@ -2711,6 +2711,36 @@ def close(self):
+ def stop(self):
+ self.active = False
+
++class TestEOFServer(threading.Thread):
++ def __init__(self):
++ super().__init__()
++ self.listening = threading.Event()
++ self.address = None
++
++ def run(self):
++ context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
++ context.load_cert_chain(CERTFILE)
++ server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
++ with server_sock:
++ server_sock.settimeout(support.SHORT_TIMEOUT)
++ server_sock.bind((HOST, 0))
++ server_sock.listen(5)
++
++ self.address = server_sock.getsockname()
++ self.listening.set()
++
++ sock, addr = server_sock.accept()
++ sslconn = context.wrap_socket(sock, server_side=True)
++ with sslconn:
++ request = b''
++ while chunk := sslconn.recv(1024):
++ request += chunk
++ if b'\n' in chunk:
++ break
++
++ sslconn.sendall(b'server\n')
++ sslconn.shutdown(socket.SHUT_WR)
++
+ class AsyncoreEchoServer(threading.Thread):
+
+ # this one's based on asyncore.dispatcher
+@@ -4747,6 +4777,58 @@ def background(sock):
+ if cm.exc_value is not None:
+ raise cm.exc_value
+
++ def test_got_eof(self):
++ # gh-148292: Test that _ssl._SSLSocket behaves the same on all OpenSSL
++ # versions on calling methods after EOF (after the first SSLEOFError).
++
++ server = TestEOFServer()
++ server.start()
++ if not server.listening.wait(support.SHORT_TIMEOUT):
++ raise RuntimeError("server took too long")
++ self.addCleanup(server.join)
++
++ context = ssl.create_default_context(cafile=CERTFILE)
++ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
++ sock.settimeout(support.SHORT_TIMEOUT)
++ sock.connect(server.address)
++ sslsock = context.wrap_socket(sock, server_hostname='localhost')
++ with sslsock:
++ sslsock.sendall(b'client\n')
++ # test the _ssl._SSLSocket object, not ssl.SSLSocket
++ sslobj = sslsock._sslobj
++
++ data = sslobj.read(1024)
++ self.assertEqual(data, b'server\n')
++
++ # The second read gets EOF error and sets got_eof_error to 1
++ with self.assertRaises(ssl.SSLEOFError):
++ sslobj.read(1024)
++
++ # Following read(), sendfile(), write() and do_handshake() calls
++ # must raise SSLEOFError
++ with self.assertRaises(ssl.SSLEOFError):
++ # The _SSLSocket remembers the previous EOF error
++ # and raises again SSLEOFError
++ sslobj.read(1024)
++ if hasattr(sslobj, 'sendfile'):
++ with open(__file__, "rb") as fp:
++ with self.assertRaises(ssl.SSLEOFError):
++ sslobj.sendfile(fp.fileno(), 0, 1)
++ with self.assertRaises(ssl.SSLEOFError):
++ sslobj.write(b'client2\n')
++ with self.assertRaises(ssl.SSLEOFError):
++ sslsock.do_handshake()
++
++ self.assertEqual(sslsock.pending(), 0)
++ try:
++ sslsock.shutdown(socket.SHUT_WR)
++ except OSError as exc:
++ self.assertEqual(exc.errno, errno.ENOTCONN)
++ else:
++ # On Windows and on OpenSSL 1.1.1, shutdown() doesn't
++ # raise an error
++ pass
++
+
+ @unittest.skipUnless(has_tls_version('TLSv1_3') and ssl.HAS_PHA,
+ "Test needs TLS 1.3 PHA")
+diff --git a/Misc/NEWS.d/next/Library/2026-04-28-17-47-55.gh-issue-148292.oIq3ml.rst b/Misc/NEWS.d/next/Library/2026-04-28-17-47-55.gh-issue-148292.oIq3ml.rst
+new file mode 100644
+index 000000000000000..e1f308df5a678e6
+--- /dev/null
++++ b/Misc/NEWS.d/next/Library/2026-04-28-17-47-55.gh-issue-148292.oIq3ml.rst
+@@ -0,0 +1,7 @@
++:mod:`ssl`: Update :class:`ssl.SSLSocket` and :class:`ssl.SSLObject` for
++OpenSSL 4. The classes now remember if they get a :exc:`ssl.SSLEOFError`. In this
++case, following :meth:`~ssl.SSLSocket.read`, :meth:`!sendfile`,
++:meth:`~ssl.SSLSocket.write`, and :meth:`~ssl.SSLSocket.do_handshake` calls
++raise :exc:`ssl.SSLEOFError` without calling the underlying OpenSSL function.
++Thanks to that, :class:`ssl.SSLSocket` behaves the same on all OpenSSL versions
++on EOF. Patch by Victor Stinner.
+diff --git a/Modules/_ssl.c b/Modules/_ssl.c
+index 1603d0ffd559559..376df32b7cb4bd6 100644
+--- a/Modules/_ssl.c
++++ b/Modules/_ssl.c
+@@ -352,6 +352,16 @@ typedef struct {
+ * and shutdown methods check for chained exceptions.
+ */
+ PyObject *exc;
++ // gh-148292: If non-zero, read(), sendfile(), write() and do_handshake()
++ // methods raise SSLEOFError without calling the underlying OpenSSL
++ // function. Set to 1 on PY_SSL_ERROR_EOF error.
++ //
++ // On OpenSSL 4, if SSL_read_ex() fails with
++ // SSL_R_UNEXPECTED_EOF_WHILE_READING, the following SSL_read_ex() call
++ // fails with a generic protocol error (ERR_peek_last_error() returns 0).
++ // Use got_eof_error to have the same behavior on OpenSSL 4 and newer and
++ // on OpenSSL 3 and older.
++ int got_eof_error;
+ } PySSLSocket;
+
+ #define PySSLSocket_CAST(op) ((PySSLSocket *)(op))
+@@ -499,6 +509,10 @@ fill_and_set_sslerror(_sslmodulestate *state,
+ PyObject *init_value, *msg, *key;
+ PyUnicodeWriter *writer = NULL;
+
++ if (ssl_errno == PY_SSL_ERROR_EOF && sslsock != NULL) {
++ sslsock->got_eof_error = 1;
++ }
++
+ if (errcode != 0) {
+ int lib, reason;
+
+@@ -654,6 +668,18 @@ PySSL_ChainExceptions(PySSLSocket *sslsock) {
+ return -1;
+ }
+
++
++static void
++set_eof_error(PySSLSocket *sslsock)
++{
++ _sslmodulestate *state = get_state_sock(sslsock);
++ fill_and_set_sslerror(state, sslsock, state->PySSLEOFErrorObject,
++ PY_SSL_ERROR_EOF,
++ "EOF occurred in violation of protocol",
++ __LINE__, 0);
++}
++
++
+ static PyObject *
+ PySSL_SetError(PySSLSocket *sslsock, const char *filename, int lineno)
+ {
+@@ -901,6 +927,7 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
+ self->server_hostname = NULL;
+ self->err = err;
+ self->exc = NULL;
++ self->got_eof_error = 0;
+
+ /* Make sure the SSL error state is initialized */
+ ERR_clear_error();
+@@ -1041,6 +1068,11 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self)
+ BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking);
+ }
+
++ if (self->got_eof_error) {
++ set_eof_error(self);
++ goto error;
++ }
++
+ timeout = GET_SOCKET_TIMEOUT(sock);
+ has_timeout = (timeout > 0);
+ if (has_timeout) {
+@@ -2504,6 +2536,11 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b)
+ BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking);
+ }
+
++ if (self->got_eof_error) {
++ set_eof_error(self);
++ goto error;
++ }
++
+ timeout = GET_SOCKET_TIMEOUT(sock);
+ has_timeout = (timeout > 0);
+ if (has_timeout) {
+@@ -2644,6 +2681,11 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len,
+ Py_INCREF(sock);
+ }
+
++ if (self->got_eof_error) {
++ set_eof_error(self);
++ goto error;
++ }
++
+ if (!group_right_1) {
+ dest = PyBytes_FromStringAndSize(NULL, len);
+ if (dest == NULL)
new file mode 100644
@@ -0,0 +1,41 @@
+From 81911909bc439d6de8ce6a173b0691b3c58e9e1a Mon Sep 17 00:00:00 2001
+From: Victor Stinner <vstinner@python.org>
+Date: Mon, 4 May 2026 16:20:25 +0200
+Subject: [PATCH] gh-148292: Remove shutdown() test in test_ssl.test_got_eof()
+ (#149366)
+
+The shutdown() behavior depends too much on the operating system and
+it's unrelated to the got_eof_error change.
+
+(cherry picked from commit 1e21cf6fee3830012e458c0fe5dbc6fcd45ace92)
+
+Upstream-Status: Backport [https://github.com/python/cpython/commit/81911909bc43]
+
+Note: This is from the unmerged CPython PR #149783 which backports
+OpenSSL 4.0 support to the 3.14 branch. Upstream deferred merging
+until after Python 3.15.1 is released.
+
+Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
+---
+ Lib/test/test_ssl.py | 8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
+index 03d9e3f9e5e96b5..6445f122b4272be 100644
+--- a/Lib/test/test_ssl.py
++++ b/Lib/test/test_ssl.py
+@@ -4820,14 +4820,6 @@ def test_got_eof(self):
+ sslsock.do_handshake()
+
+ self.assertEqual(sslsock.pending(), 0)
+- try:
+- sslsock.shutdown(socket.SHUT_WR)
+- except OSError as exc:
+- self.assertEqual(exc.errno, errno.ENOTCONN)
+- else:
+- # On Windows and on OpenSSL 1.1.1, shutdown() doesn't
+- # raise an error
+- pass
+
+
+ @unittest.skipUnless(has_tls_version('TLSv1_3') and ssl.HAS_PHA,
@@ -22,6 +22,9 @@ SRC_URI = "http://www.python.org/ftp/python/${PV}/Python-${PV}.tar.xz \
file://0001-Avoid-shebang-overflow-on-python-config.py.patch \
file://0001-Update-test_sysconfig-for-posix_user-purelib.patch \
file://0001-prefer-valid-entrypoints.patch \
+ file://0001-gh-146207-Add-support-for-OpenSSL-4.0.0.patch \
+ file://0002-gh-148292-Update-_ssl._SSLSocket-for-OpenSSL-4.patch \
+ file://0003-gh-148292-Remove-shutdown-test-in-test_ssl.test_got_eof.patch \
"
SRC_URI:append:class-native = " \
file://0001-Lib-sysconfig.py-use-prefix-value-from-build-configu.patch \
Backport CPython commit 3364e7e62fa24d0e19133fb0f90b1c24ef1110c5: gh-146207: Add support for OpenSSL 4.0.0 alpha1 (#146217) OpenSSL 4.0.0 alpha1 removed these functions: * SSLv3_method() * TLSv1_method() * TLSv1_1_method() * TLSv1_2_method() Other changes: * Update test_openssl_version(). * Update multissltests.py for OpenSSL 4. * Add const qualifier to fix compiler warnings. Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Upstream-Status: Backport [https://github.com/python/cpython/commit/3364e7e62fa24d0e19133fb0f90b1c24ef1110c5] Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> --- ...146207-Add-support-for-OpenSSL-4.0.0.patch | 257 ++++++++++++++++++ ...Update-_ssl._SSLSocket-for-OpenSSL-4.patch | 234 ++++++++++++++++ ...utdown-test-in-test_ssl.test_got_eof.patch | 41 +++ .../recipes-devtools/python/python3_3.14.7.bb | 3 + 4 files changed, 535 insertions(+) create mode 100644 meta/recipes-devtools/python/python3/0001-gh-146207-Add-support-for-OpenSSL-4.0.0.patch create mode 100644 meta/recipes-devtools/python/python3/0002-gh-148292-Update-_ssl._SSLSocket-for-OpenSSL-4.patch create mode 100644 meta/recipes-devtools/python/python3/0003-gh-148292-Remove-shutdown-test-in-test_ssl.test_got_eof.patch