File 0003-Fix-compatibility-with-Python-3.7-ssl.SSLSocket-531.patch of Package python-eventlet

From a915bb642dd6cd4e92c959addff30509977a637c Mon Sep 17 00:00:00 2001
From: Junyi <xmaswillyou@gmail.com>
Date: Wed, 30 Jan 2019 00:10:31 -0800
Subject: [PATCH 3/3] Fix compatibility with Python 3.7 ssl.SSLSocket  (#531)

---
 eventlet/green/ssl.py | 86 ++++++++++++++++++++++++-------------------
 1 file changed, 49 insertions(+), 37 deletions(-)

diff --git a/eventlet/green/ssl.py b/eventlet/green/ssl.py
index 53dff70..9504aef 100644
--- a/eventlet/green/ssl.py
+++ b/eventlet/green/ssl.py
@@ -3,10 +3,7 @@ __ssl = __import__('ssl')
 from eventlet.patcher import slurp_properties
 slurp_properties(__ssl, globals(), srckeys=dir(__ssl))
 
-import errno
-import functools
 import sys
-
 from eventlet import greenio, hubs
 from eventlet.greenio import (
     set_nonblocking, GreenSocket, CONNECT_ERR, CONNECT_SUCCESS,
@@ -14,6 +11,8 @@ from eventlet.greenio import (
 from eventlet.hubs import trampoline, IOClosed
 from eventlet.support import get_errno, PY33
 import six
+from contextlib import contextmanager
+
 orig_socket = __import__('socket')
 socket = orig_socket.socket
 timeout_exc = SSLError
@@ -24,6 +23,21 @@ __patched__ = [
 
 _original_sslsocket = __ssl.SSLSocket
 _original_wrap_socket = __ssl.wrap_socket
+_original_sslcontext = getattr(__ssl, 'SSLContext', None)
+_is_under_py_3_7 = sys.version_info < (3, 7)
+
+
+@contextmanager
+def _original_ssl_context(*args, **kwargs):
+    tmp_sslcontext = _original_wrap_socket.__globals__.get('SSLContext', None)
+    tmp_sslsocket = _original_sslsocket._create.__globals__.get('SSLSocket', None)
+    _original_sslsocket._create.__globals__['SSLSocket'] = _original_sslsocket
+    _original_wrap_socket.__globals__['SSLContext'] = _original_sslcontext
+    try:
+        yield
+    finally:
+        _original_wrap_socket.__globals__['SSLContext'] = tmp_sslcontext
+        _original_sslsocket._create.__globals__['SSLSocket'] = tmp_sslsocket
 
 
 class GreenSSLSocket(_original_sslsocket):
@@ -40,16 +54,43 @@ class GreenSSLSocket(_original_sslsocket):
     settimeout(), and to close/reopen the connection when a timeout
     occurs at an unexpected juncture in the code.
     """
+    def __new__(cls, sock=None, keyfile=None, certfile=None,
+                server_side=False, cert_reqs=CERT_NONE,
+                ssl_version=PROTOCOL_SSLv23, ca_certs=None,
+                do_handshake_on_connect=True, *args, **kw):
+        if _is_under_py_3_7:
+            return super(GreenSSLSocket, cls).__new__(cls)
+        else:
+            if not isinstance(sock, GreenSocket):
+                sock = GreenSocket(sock)
+            with _original_ssl_context():
+                ret = _original_wrap_socket(
+                    sock=sock.fd,
+                    keyfile=keyfile,
+                    certfile=certfile,
+                    server_side=server_side,
+                    cert_reqs=cert_reqs,
+                    ssl_version=ssl_version,
+                    ca_certs=ca_certs,
+                    do_handshake_on_connect=False,
+                    *args, **kw
+                )
+            ret.keyfile = keyfile
+            ret.certfile = certfile
+            ret.cert_reqs = cert_reqs
+            ret.ssl_version = ssl_version
+            ret.ca_certs = ca_certs
+            ret.__class__ = GreenSSLSocket
+            return ret
+
     # we are inheriting from SSLSocket because its constructor calls
     # do_handshake whose behavior we wish to override
-
     def __init__(self, sock, keyfile=None, certfile=None,
                  server_side=False, cert_reqs=CERT_NONE,
                  ssl_version=PROTOCOL_SSLv23, ca_certs=None,
                  do_handshake_on_connect=True, *args, **kw):
         if not isinstance(sock, GreenSocket):
             sock = GreenSocket(sock)
-
         self.act_non_blocking = sock.act_non_blocking
 
         if six.PY2:
@@ -57,42 +98,12 @@ class GreenSSLSocket(_original_sslsocket):
             # this assignment
             self._timeout = sock.gettimeout()
 
-        if sys.version_info >= (3, 7):
-            # Monkey-patch the sslsocket so our modified self gets
-            # injected into its _create method.
-            def fake_new(self, cls, *args, **kwargs):
-                return self
-
-            orig_new = _original_sslsocket.__new__
-            try:
-                _original_sslsocket.__new__ = fake_new.__get__(self, GreenSSLSocket)
-
-                self = _original_wrap_socket(
-                    sock=sock.fd,
-                    keyfile=keyfile,
-                    certfile=certfile,
-                    server_side=server_side,
-                    cert_reqs=cert_reqs,
-                    ssl_version=ssl_version,
-                    ca_certs=ca_certs,
-                    do_handshake_on_connect=False,
-                    *args, **kw
-                )
-                self.keyfile = keyfile
-                self.certfile = certfile
-                self.cert_reqs = cert_reqs
-                self.ssl_version = ssl_version
-                self.ca_certs = ca_certs
-            finally:
-                # Unpatch
-                _original_sslsocket.__new__ = orig_new
-        else:
+        if _is_under_py_3_7:
             # nonblocking socket handshaking on connect got disabled so let's pretend it's disabled
             # even when it's on
             super(GreenSSLSocket, self).__init__(
                 sock.fd, keyfile, certfile, server_side, cert_reqs, ssl_version,
                 ca_certs, do_handshake_on_connect and six.PY2, *args, **kw)
-
         # the superclass initializer trashes the methods so we remove
         # the local-object versions of them and let the actual class
         # methods shine through
@@ -354,7 +365,7 @@ class GreenSSLSocket(_original_sslsocket):
         except NameError:
             self._sslobj = sslobj
         else:
-            if sys.version_info < (3, 7):
+            if _is_under_py_3_7:
                 self._sslobj = SSLObject(sslobj, owner=self)
             else:
                 self._sslobj = sslobj
@@ -396,6 +407,7 @@ class GreenSSLSocket(_original_sslsocket):
     def dup(self):
         raise NotImplementedError("Can't dup an ssl object")
 
+
 SSLSocket = GreenSSLSocket
 
 
-- 
2.21.0

openSUSE Build Service is sponsored by