Merge lp:~jderose/degu/py3.10 into lp:degu

Proposed by Jason Gerard DeRose
Status: Merged
Merged at revision: 493
Proposed branch: lp:~jderose/degu/py3.10
Merge into: lp:degu
Diff against target: 439 lines (+61/-52)
9 files modified
debian/control (+1/-0)
degu/client.py (+3/-3)
degu/server.py (+3/-3)
degu/tests/test_base.py (+22/-16)
degu/tests/test_client.py (+10/-10)
degu/tests/test_server.py (+12/-12)
degu/tests/test_sslhelpers.py (+8/-5)
doc/degu.client.rst (+1/-1)
setup.py (+1/-2)
To merge this branch: bzr merge lp:~jderose/degu/py3.10
Reviewer Review Type Date Requested Status
Jeremy Soller (community) Approve
Review via email: mp+424913@code.launchpad.net

Commit message

Support Python 3.10

To post a comment you must log in.
Revision history for this message
Jeremy Soller (jackpot51) wrote :

Changes all look good to me

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2021-01-13 13:00:43 +0000
3+++ debian/control 2022-06-16 23:17:03 +0000
4@@ -6,6 +6,7 @@
5 dh-python,
6 python3-all-dev (>= 3.8),
7 python3-all-dbg (>= 3.8),
8+ python3-setuptools,
9 python3-sphinx,
10 pyflakes3,
11 clang-tools,
12
13=== modified file 'degu/client.py'
14--- degu/client.py 2016-05-18 04:00:39 +0000
15+++ degu/client.py 2022-06-16 23:17:03 +0000
16@@ -82,7 +82,7 @@
17 )
18 )
19
20- sslctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
21+ sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
22 sslctx.verify_mode = ssl.CERT_REQUIRED
23 sslctx.set_ciphers(
24 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384'
25@@ -116,8 +116,8 @@
26
27 if not isinstance(sslctx, ssl.SSLContext):
28 raise TypeError('sslctx must be an ssl.SSLContext')
29- if sslctx.protocol != ssl.PROTOCOL_TLSv1_2:
30- raise ValueError('sslctx.protocol must be ssl.PROTOCOL_TLSv1_2')
31+ if sslctx.protocol != ssl.PROTOCOL_TLS_CLIENT:
32+ raise ValueError('sslctx.protocol must be ssl.PROTOCOL_TLS_CLIENT')
33 if not (sslctx.options & ssl.OP_NO_COMPRESSION):
34 raise ValueError('sslctx.options must include ssl.OP_NO_COMPRESSION')
35 if sslctx.verify_mode != ssl.CERT_REQUIRED:
36
37=== modified file 'degu/server.py'
38--- degu/server.py 2019-11-26 01:04:54 +0000
39+++ degu/server.py 2022-06-16 23:17:03 +0000
40@@ -69,7 +69,7 @@
41 )
42 )
43
44- sslctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
45+ sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
46 sslctx.set_ciphers(
47 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384'
48 )
49@@ -109,8 +109,8 @@
50
51 if not isinstance(sslctx, ssl.SSLContext):
52 raise TypeError('sslctx must be an ssl.SSLContext')
53- if sslctx.protocol != ssl.PROTOCOL_TLSv1_2:
54- raise ValueError('sslctx.protocol must be ssl.PROTOCOL_TLSv1_2')
55+ if sslctx.protocol != ssl.PROTOCOL_TLS_SERVER:
56+ raise ValueError('sslctx.protocol must be ssl.PROTOCOL_TLS_SERVER')
57
58 # We consider ssl.CERT_OPTIONAL to be a bad grey area:
59 if sslctx.verify_mode == ssl.CERT_OPTIONAL:
60
61=== modified file 'degu/tests/test_base.py'
62--- degu/tests/test_base.py 2021-01-11 18:50:42 +0000
63+++ degu/tests/test_base.py 2022-06-16 23:17:03 +0000
64@@ -425,9 +425,9 @@
65 if self.backend is _base:
66 msg = ARG_MSG_C.format(fullname, number, len(args))
67 elif len(args) < number:
68- msg = ARG_MSG_Py_1.format(name, missing)
69+ msg = ARG_MSG_Py_1.format(fullname, missing)
70 else:
71- msg = ARG_MSG_Py_2.format(name, number + 1, number + 2)
72+ msg = ARG_MSG_Py_2.format(fullname, number + 1, number + 2)
73 self.assertEqual(str(cm.exception), msg)
74
75 def check_method_args(self, inst, name, number, missing):
76@@ -803,10 +803,6 @@
77 self.assertEqual(str(r), 'bytes=0-9999999999999998')
78
79 # Check reference counting:
80- if self.backend is _base:
81- delmsg = 'readonly attribute'
82- else:
83- delmsg = "can't delete attribute"
84 for i in range(1000):
85 stop = random.randrange(1, MAX_LENGTH + 1)
86 start = random.randrange(0, stop)
87@@ -827,6 +823,10 @@
88 # start, stop should be read-only:
89 r = self.Range(start, stop)
90 for name in ('start', 'stop'):
91+ if self.backend is _base:
92+ delmsg = 'readonly attribute'
93+ else:
94+ delmsg = "can't delete attribute '" + name + "'"
95 with self.assertRaises(AttributeError) as cm:
96 delattr(r, name)
97 self.assertEqual(str(cm.exception), delmsg)
98@@ -1139,10 +1139,6 @@
99 )
100
101 # Check reference counting:
102- if self.backend is _base:
103- delmsg = 'readonly attribute'
104- else:
105- delmsg = "can't delete attribute"
106 for i in range(1000):
107 stop = random.randrange(1, MAX_LENGTH + 1)
108 start = random.randrange(0, stop)
109@@ -1172,6 +1168,10 @@
110 # start, stop, total should be read-only:
111 r = self.ContentRange(start, stop, total)
112 for name in ('start', 'stop', 'total'):
113+ if self.backend is _base:
114+ delmsg = 'readonly attribute'
115+ else:
116+ delmsg = "can't delete attribute '" + name + "'"
117 with self.assertRaises(AttributeError) as cm:
118 delattr(r, name)
119 self.assertEqual(str(cm.exception), delmsg)
120@@ -2170,6 +2170,7 @@
121 self.assertEqual(str(cm.exception),
122 "'MissingReadline' object has no attribute 'readline'"
123 )
124+ del cm # Must del context manager before testing refcount (py 3.10+):
125 self.assertEqual(sys.getrefcount(rfile), 2)
126
127 # rfile.readline() not callable:
128@@ -2195,6 +2196,7 @@
129 self.assertEqual(str(cm.exception),
130 "'MissingRead' object has no attribute 'readinto'"
131 )
132+ del cm # Must del context manager before testing refcount (py 3.10+):
133 self.assertEqual(sys.getrefcount(rfile), 2)
134
135 # rfile.readinto() not callable:
136@@ -3505,13 +3507,13 @@
137 Check body instance attributes that should be read-only.
138 """
139 assert len(members) >= 2
140- if self.backend is _basepy:
141- setmsg = "can't set attribute"
142- delmsg = "can't delete attribute"
143- else:
144- setmsg = 'readonly attribute'
145- delmsg = 'readonly attribute'
146 for name in members:
147+ if self.backend is _basepy:
148+ setmsg = "can't set attribute '" + name + "'"
149+ delmsg = "can't delete attribute '" + name + "'"
150+ else:
151+ setmsg = 'readonly attribute'
152+ delmsg = 'readonly attribute'
153 value = getattr(body, name)
154 with self.assertRaises(AttributeError) as cm:
155 setattr(body, name, value)
156@@ -3993,6 +3995,7 @@
157 self.assertEqual(str(cm.exception),
158 "'MissingReadline' object has no attribute 'readline'"
159 )
160+ del cm # Must del context manager before testing refcount (py 3.10+):
161 self.assertEqual(sys.getrefcount(rfile), 2)
162
163 # Not a backend.SocketWrapper, rfile.readline() not callable:
164@@ -4018,6 +4021,7 @@
165 self.assertEqual(str(cm.exception),
166 "'MissingRead' object has no attribute 'readinto'"
167 )
168+ del cm # Must del context manager before testing refcount (py 3.10+):
169 self.assertEqual(sys.getrefcount(rfile), 2)
170
171 # Not a backend.SocketWrapper, rfile.readinto() not callable:
172@@ -6245,6 +6249,7 @@
173 self.assertEqual(str(cm.exception),
174 "'BadSocket1' object has no attribute 'recv_into'"
175 )
176+ del cm # Must del context manager before testing refcount (py 3.10+):
177 self.assertEqual(sys.getrefcount(sock), 2)
178 self.assertEqual(sock._calls, ['close'])
179
180@@ -6259,6 +6264,7 @@
181 self.assertEqual(str(cm.exception),
182 "'BadSocket2' object has no attribute 'send'"
183 )
184+ del cm # Must del context manager before testing refcount (py 3.10+):
185 self.assertEqual(sys.getrefcount(sock), 2)
186 self.assertEqual(sock._calls, ['close'])
187
188
189=== modified file 'degu/tests/test_client.py'
190--- degu/tests/test_client.py 2017-09-04 23:38:30 +0000
191+++ degu/tests/test_client.py 2022-06-16 23:17:03 +0000
192@@ -142,7 +142,7 @@
193 for func in client_sslctx_funcs:
194 sslctx = func({})
195 self.assertIsInstance(sslctx, ssl.SSLContext)
196- self.assertEqual(sslctx.protocol, ssl.PROTOCOL_TLSv1_2)
197+ self.assertEqual(sslctx.protocol, ssl.PROTOCOL_TLS_CLIENT)
198 self.assertEqual(sslctx.verify_mode, ssl.CERT_REQUIRED)
199 self.assertIs(sslctx.check_hostname, True)
200
201@@ -159,7 +159,7 @@
202 for func in client_sslctx_funcs:
203 sslctx = func({'check_hostname': True})
204 self.assertIsInstance(sslctx, ssl.SSLContext)
205- self.assertEqual(sslctx.protocol, ssl.PROTOCOL_TLSv1_2)
206+ self.assertEqual(sslctx.protocol, ssl.PROTOCOL_TLS_CLIENT)
207 self.assertEqual(sslctx.verify_mode, ssl.CERT_REQUIRED)
208 self.assertIs(sslctx.check_hostname, True)
209
210@@ -173,7 +173,7 @@
211 for func in client_sslctx_funcs:
212 sslctx = func(sslconfig)
213 self.assertIsInstance(sslctx, ssl.SSLContext)
214- self.assertEqual(sslctx.protocol, ssl.PROTOCOL_TLSv1_2)
215+ self.assertEqual(sslctx.protocol, ssl.PROTOCOL_TLS_CLIENT)
216 self.assertEqual(sslctx.verify_mode, ssl.CERT_REQUIRED)
217 self.assertIs(sslctx.check_hostname, False)
218
219@@ -182,7 +182,7 @@
220 for func in client_sslctx_funcs:
221 sslctx = func(sslconfig)
222 self.assertIsInstance(sslctx, ssl.SSLContext)
223- self.assertEqual(sslctx.protocol, ssl.PROTOCOL_TLSv1_2)
224+ self.assertEqual(sslctx.protocol, ssl.PROTOCOL_TLS_CLIENT)
225 self.assertEqual(sslctx.verify_mode, ssl.CERT_REQUIRED)
226 self.assertIs(sslctx.check_hostname, True)
227
228@@ -193,7 +193,7 @@
229 for func in client_sslctx_funcs:
230 sslctx = func(sslconfig)
231 self.assertIsInstance(sslctx, ssl.SSLContext)
232- self.assertEqual(sslctx.protocol, ssl.PROTOCOL_TLSv1_2)
233+ self.assertEqual(sslctx.protocol, ssl.PROTOCOL_TLS_CLIENT)
234 self.assertEqual(sslctx.verify_mode, ssl.CERT_REQUIRED)
235 self.assertIs(sslctx.check_hostname, False)
236
237@@ -202,7 +202,7 @@
238 for func in client_sslctx_funcs:
239 sslctx = func(sslconfig)
240 self.assertIsInstance(sslctx, ssl.SSLContext)
241- self.assertEqual(sslctx.protocol, ssl.PROTOCOL_TLSv1_2)
242+ self.assertEqual(sslctx.protocol, ssl.PROTOCOL_TLS_CLIENT)
243 self.assertEqual(sslctx.verify_mode, ssl.CERT_REQUIRED)
244 self.assertIs(sslctx.check_hostname, True)
245
246@@ -470,11 +470,11 @@
247 self.assertEqual(str(cm.exception), 'sslctx must be an ssl.SSLContext')
248
249 # Bad SSL protocol version:
250- sslctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
251+ sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
252 with self.assertRaises(ValueError) as cm:
253 client.SSLClient(sslctx, None)
254 self.assertEqual(str(cm.exception),
255- 'sslctx.protocol must be ssl.PROTOCOL_TLSv1_2'
256+ 'sslctx.protocol must be ssl.PROTOCOL_TLS_CLIENT'
257 )
258
259 # Note: Python 3.3.4 (and presumably 3.4.0) now disables SSLv2 by
260@@ -482,7 +482,7 @@
261 # we cannot unset the ssl.OP_NO_SSLv2 bit, we can't unit test to check
262 # that Degu enforces this, so for now, we set the bit here so it works
263 # with Python 3.3.3 still; see: http://bugs.python.org/issue20207
264- sslctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
265+ sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
266 sslctx.options |= ssl.OP_NO_SSLv2
267
268 # not (options & ssl.OP_NO_COMPRESSION)
269@@ -494,7 +494,7 @@
270 )
271
272 # verify_mode is not ssl.CERT_REQUIRED:
273- sslctx.options |= ssl.OP_NO_COMPRESSION
274+ sslctx.verify_mode = ssl.CERT_OPTIONAL
275 with self.assertRaises(ValueError) as cm:
276 client.SSLClient(sslctx, None)
277 self.assertEqual(str(cm.exception),
278
279=== modified file 'degu/tests/test_server.py'
280--- degu/tests/test_server.py 2019-11-26 01:04:54 +0000
281+++ degu/tests/test_server.py 2022-06-16 23:17:03 +0000
282@@ -120,7 +120,7 @@
283 )
284 for func in server_sslctx_funcs:
285 sslctx = func(pki.server_sslconfig)
286- self.assertEqual(sslctx.protocol, ssl.PROTOCOL_TLSv1_2)
287+ self.assertEqual(sslctx.protocol, ssl.PROTOCOL_TLS_SERVER)
288 self.assertEqual(sslctx.verify_mode, ssl.CERT_REQUIRED)
289
290 # New in Degu 0.3: should not be able to accept connections from
291@@ -138,7 +138,7 @@
292 sslconfig['allow_unauthenticated_clients'] = True
293 for func in server_sslctx_funcs:
294 sslctx = func(sslconfig)
295- self.assertEqual(sslctx.protocol, ssl.PROTOCOL_TLSv1_2)
296+ self.assertEqual(sslctx.protocol, ssl.PROTOCOL_TLS_SERVER)
297 self.assertEqual(sslctx.verify_mode, ssl.CERT_NONE)
298
299 # Cannot mix ca_file/ca_path with allow_unauthenticated_clients:
300@@ -176,13 +176,13 @@
301
302 # Wrong protocol:
303 with self.assertRaises(ValueError) as cm:
304- server._validate_server_sslctx(ssl.SSLContext(ssl.PROTOCOL_TLSv1))
305+ server._validate_server_sslctx(ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT))
306 self.assertEqual(str(cm.exception),
307- 'sslctx.protocol must be ssl.PROTOCOL_TLSv1_2'
308+ 'sslctx.protocol must be ssl.PROTOCOL_TLS_SERVER'
309 )
310
311 # Don't allow ssl.CERT_OPTIONAL:
312- sslctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
313+ sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
314 sslctx.verify_mode = ssl.CERT_OPTIONAL
315 with self.assertRaises(ValueError) as cm:
316 server._validate_server_sslctx(sslctx)
317@@ -191,13 +191,13 @@
318 )
319
320 # All good:
321- sslctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
322+ sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
323 self.assertIs(sslctx.verify_mode, ssl.CERT_NONE)
324 self.assertIs(server._validate_server_sslctx(sslctx), sslctx)
325
326 # Now again, this time with CERT_REQUIRED:
327 # options missing OP_NO_COMPRESSION:
328- sslctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
329+ sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
330 sslctx.verify_mode = ssl.CERT_REQUIRED
331 self.assertIs(sslctx.verify_mode, ssl.CERT_REQUIRED)
332 self.assertIs(server._validate_server_sslctx(sslctx), sslctx)
333@@ -426,15 +426,15 @@
334 self.assertEqual(str(cm.exception), 'sslctx must be an ssl.SSLContext')
335
336 # Bad SSL protocol version:
337- sslctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
338+ sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
339 with self.assertRaises(ValueError) as cm:
340 server.SSLServer(sslctx, degu.IPv6_LOOPBACK, good_app)
341 self.assertEqual(str(cm.exception),
342- 'sslctx.protocol must be ssl.PROTOCOL_TLSv1_2'
343+ 'sslctx.protocol must be ssl.PROTOCOL_TLS_SERVER'
344 )
345
346 # Good sslctx from here on:
347- sslctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
348+ sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
349
350 # Bad address type:
351 with self.assertRaises(TypeError) as cm:
352@@ -1003,7 +1003,7 @@
353 with self.assertRaises(ssl.SSLError) as cm:
354 client.connect()
355 self.assertTrue(
356- str(cm.exception).startswith('[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE]')
357+ str(cm.exception).startswith('[SSL: CERTIFICATE_VERIFY_FAILED]')
358 )
359 self.assertIs(conn.closed, True)
360
361@@ -1017,7 +1017,7 @@
362 with self.assertRaises(ssl.SSLError) as cm:
363 client.connect()
364 self.assertTrue(
365- str(cm.exception).startswith('[SSL: TLSV1_ALERT_UNKNOWN_CA]')
366+ str(cm.exception).startswith('[SSL: CERTIFICATE_VERIFY_FAILED]')
367 )
368 self.assertIs(conn.closed, True)
369
370
371=== modified file 'degu/tests/test_sslhelpers.py'
372--- degu/tests/test_sslhelpers.py 2016-03-13 18:28:18 +0000
373+++ degu/tests/test_sslhelpers.py 2022-06-16 23:17:03 +0000
374@@ -36,22 +36,26 @@
375 def test_create_key(self):
376 # 1024 bit:
377 key_data = sslhelpers.create_key(1024)
378- self.assertIn(len(key_data), [883, 887, 891])
379+ self.assertGreater(len(key_data), 512)
380+ self.assertLess(len(key_data), 1024)
381 sslhelpers.get_pubkey(key_data)
382
383 # 2048 bit:
384 key_data = sslhelpers.create_key(2048)
385- self.assertIn(len(key_data), [1671, 1675, 1679])
386+ self.assertGreater(len(key_data), 1024)
387+ self.assertLess(len(key_data), 2048)
388 sslhelpers.get_pubkey(key_data)
389
390 # 3072 bit:
391 key_data = sslhelpers.create_key(3072)
392- self.assertIn(len(key_data), [2455, 2459])
393+ self.assertGreater(len(key_data), 2048)
394+ self.assertLess(len(key_data), 3072)
395 sslhelpers.get_pubkey(key_data)
396
397 # 4096 bit:
398 key_data = sslhelpers.create_key(4096)
399- self.assertIn(len(key_data), [3239, 3243, 3247])
400+ self.assertGreater(len(key_data), 3072)
401+ self.assertLess(len(key_data), 4096)
402 sslhelpers.get_pubkey(key_data)
403
404 def test_create_ca(self):
405@@ -179,7 +183,6 @@
406 set([
407 ca_id + '.key',
408 ca_id + '.ca',
409- ca_id + '.srl',
410 cert_id + '.csr',
411 cert_id + '.cert',
412 ])
413
414=== modified file 'doc/degu.client.rst'
415--- doc/degu.client.rst 2017-07-18 18:07:33 +0000
416+++ doc/degu.client.rst 2022-06-16 23:17:03 +0000
417@@ -42,7 +42,7 @@
418 server certificate (more or less how a browser would configure SSL):
419
420 >>> import ssl
421->>> sslclient.sslctx.protocol == ssl.PROTOCOL_TLSv1_2
422+>>> sslclient.sslctx.protocol == ssl.PROTOCOL_TLS_CLIENT
423 True
424 >>> sslclient.sslctx.verify_mode == ssl.CERT_REQUIRED
425 True
426
427=== modified file 'setup.py'
428--- setup.py 2021-01-13 13:00:43 +0000
429+++ setup.py 2022-06-16 23:17:03 +0000
430@@ -33,8 +33,7 @@
431 import os
432 from os import path
433 import subprocess
434-from distutils.core import setup, Extension
435-from distutils.cmd import Command
436+from setuptools import setup, Command, Extension
437
438 import degu
439 from degu.tests.run import run_tests

Subscribers

People subscribed via source and target branches