File: 0015-more-python3.7-fixes.patch

package info (click to toggle)
python-eventlet 0.20.0-6
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 3,376 kB
  • sloc: python: 31,120; sh: 208; makefile: 90
file content (163 lines) | stat: -rw-r--r-- 6,299 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
Description: More Python 3.7 fixes
 This patch is a mix of these:
 https://github.com/eventlet/eventlet/pull/531/commits
Author: Jerry Luan <jerry.luan@airbnb.com>
Origin: upstream, https://github.com/eventlet/eventlet/issues/526
Last-Update: 2019-01-22

--- python-eventlet-0.20.0.orig/eventlet/green/ssl.py
+++ python-eventlet-0.20.0/eventlet/green/ssl.py
@@ -3,17 +3,19 @@ __ssl = __import__('ssl')
 from eventlet.patcher import slurp_properties
 slurp_properties(__ssl, globals(), srckeys=dir(__ssl))
 
-import errno
-import functools
 import sys
 import time
 
+import imp
 from eventlet import greenio
 from eventlet.greenio import (
     set_nonblocking, GreenSocket, CONNECT_ERR, CONNECT_SUCCESS,
 )
 from eventlet.hubs import trampoline, IOClosed
 from eventlet.support import get_errno, PY33, six
+import six
+from contextlib import contextmanager
+
 orig_socket = __import__('socket')
 socket = orig_socket.socket
 if sys.version_info >= (2, 7):
@@ -29,6 +31,20 @@ __patched__ = [
 
 _original_sslsocket = __ssl.SSLSocket
 _original_wrap_socket = __ssl.wrap_socket
+_original_sslcontext = getattr(__ssl, 'SSLContext', None)
+
+
+@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):
@@ -45,16 +61,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 sys.version_info < (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:
@@ -62,42 +105,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 sys.version_info < (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
@@ -406,6 +419,7 @@ class GreenSSLSocket(_original_sslsocket
     def dup(self):
         raise NotImplementedError("Can't dup an ssl object")
 
+
 SSLSocket = GreenSSLSocket
 
 
--- python-eventlet-0.20.0.orig/eventlet/greenio/base.py
+++ python-eventlet-0.20.0/eventlet/greenio/base.py
@@ -140,7 +140,9 @@ class GreenSocket(object):
         except AttributeError:
             self._timeout = socket.getdefaulttimeout()
 
-        if should_set_nonblocking:
+        # Filter fd.fileno() != -1 so that won't call set non-blocking on
+        # closed socket
+        if should_set_nonblocking and fd.fileno() != -1:
             set_nonblocking(fd)
         self.fd = fd
         # when client calls setblocking(0) or settimeout(0) the socket must