Skip to content

Commit 03583e7

Browse files
authored
Merge branch '3.12' into backport-8a00c9a-3.12
2 parents c719cc5 + 85b6b0e commit 03583e7

File tree

16 files changed

+122
-83
lines changed

16 files changed

+122
-83
lines changed

Doc/library/os.rst

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3547,16 +3547,16 @@ features:
35473547

35483548
This example displays the number of bytes taken by non-directory files in each
35493549
directory under the starting directory, except that it doesn't look under any
3550-
CVS subdirectory::
3550+
``__pycache__`` subdirectory::
35513551

35523552
import os
35533553
from os.path import join, getsize
3554-
for root, dirs, files in os.walk('python/Lib/email'):
3554+
for root, dirs, files in os.walk('python/Lib/xml'):
35553555
print(root, "consumes", end=" ")
35563556
print(sum(getsize(join(root, name)) for name in files), end=" ")
35573557
print("bytes in", len(files), "non-directory files")
3558-
if 'CVS' in dirs:
3559-
dirs.remove('CVS') # don't visit CVS directories
3558+
if '__pycache__' in dirs:
3559+
dirs.remove('__pycache__') # don't visit __pycache__ directories
35603560

35613561
In the next example (simple implementation of :func:`shutil.rmtree`),
35623562
walking the tree bottom-up is essential, :func:`rmdir` doesn't allow
@@ -3609,16 +3609,16 @@ features:
36093609

36103610
This example displays the number of bytes taken by non-directory files in each
36113611
directory under the starting directory, except that it doesn't look under any
3612-
CVS subdirectory::
3612+
``__pycache__`` subdirectory::
36133613

36143614
import os
3615-
for root, dirs, files, rootfd in os.fwalk('python/Lib/email'):
3615+
for root, dirs, files, rootfd in os.fwalk('python/Lib/xml'):
36163616
print(root, "consumes", end="")
36173617
print(sum([os.stat(name, dir_fd=rootfd).st_size for name in files]),
36183618
end="")
36193619
print("bytes in", len(files), "non-directory files")
3620-
if 'CVS' in dirs:
3621-
dirs.remove('CVS') # don't visit CVS directories
3620+
if '__pycache__' in dirs:
3621+
dirs.remove('__pycache__') # don't visit __pycache__ directories
36223622

36233623
In the next example, walking the tree bottom-up is essential:
36243624
:func:`rmdir` doesn't allow deleting a directory before the directory is

Lib/os.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -335,12 +335,12 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
335335
336336
import os
337337
from os.path import join, getsize
338-
for root, dirs, files in os.walk('python/Lib/email'):
338+
for root, dirs, files in os.walk('python/Lib/xml'):
339339
print(root, "consumes ")
340340
print(sum(getsize(join(root, name)) for name in files), end=" ")
341341
print("bytes in", len(files), "non-directory files")
342-
if 'CVS' in dirs:
343-
dirs.remove('CVS') # don't visit CVS directories
342+
if '__pycache__' in dirs:
343+
dirs.remove('__pycache__') # don't visit __pycache__ directories
344344
345345
"""
346346
sys.audit("os.walk", top, topdown, onerror, followlinks)
@@ -466,13 +466,13 @@ def fwalk(top=".", topdown=True, onerror=None, *, follow_symlinks=False, dir_fd=
466466
Example:
467467
468468
import os
469-
for root, dirs, files, rootfd in os.fwalk('python/Lib/email'):
469+
for root, dirs, files, rootfd in os.fwalk('python/Lib/xml'):
470470
print(root, "consumes", end="")
471471
print(sum(os.stat(name, dir_fd=rootfd).st_size for name in files),
472472
end="")
473473
print("bytes in", len(files), "non-directory files")
474-
if 'CVS' in dirs:
475-
dirs.remove('CVS') # don't visit CVS directories
474+
if '__pycache__' in dirs:
475+
dirs.remove('__pycache__') # don't visit __pycache__ directories
476476
"""
477477
sys.audit("os.fwalk", top, topdown, onerror, follow_symlinks, dir_fd)
478478
top = fspath(top)

Lib/test/audit-tests.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,15 @@ def test_open(testfn):
208208
if not fn:
209209
continue
210210
with assertRaises(RuntimeError):
211-
fn(*args)
211+
try:
212+
fn(*args)
213+
except NotImplementedError:
214+
if fn == load_dh_params:
215+
# Not callable in some builds
216+
load_dh_params = None
217+
raise RuntimeError
218+
else:
219+
raise
212220

213221
actual_mode = [(a[0], a[1]) for e, a in hook.seen if e == "open" and a[1]]
214222
actual_flag = [(a[0], a[2]) for e, a in hook.seen if e == "open" and not a[1]]

Lib/test/test_audit.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def do_test(self, *args):
2323
with subprocess.Popen(
2424
[sys.executable, "-X utf8", AUDIT_TESTS_PY, *args],
2525
encoding="utf-8",
26+
errors="backslashreplace",
2627
stdout=subprocess.PIPE,
2728
stderr=subprocess.PIPE,
2829
) as p:

Lib/test/test_ssl.py

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,10 +1326,14 @@ def test_load_verify_cadata(self):
13261326
with self.assertRaises(ssl.SSLError):
13271327
ctx.load_verify_locations(cadata=cacert_der + b"A")
13281328

1329-
@unittest.skipIf(Py_DEBUG_WIN32, "Avoid mixing debug/release CRT on Windows")
13301329
def test_load_dh_params(self):
13311330
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
1332-
ctx.load_dh_params(DHFILE)
1331+
try:
1332+
ctx.load_dh_params(DHFILE)
1333+
except RuntimeError:
1334+
if Py_DEBUG_WIN32:
1335+
self.skipTest("not supported on Win32 debug build")
1336+
raise
13331337
if os.name != 'nt':
13341338
ctx.load_dh_params(BYTES_DHFILE)
13351339
self.assertRaises(TypeError, ctx.load_dh_params)
@@ -1650,12 +1654,17 @@ def test_str(self):
16501654
self.assertEqual(str(e), "foo")
16511655
self.assertEqual(e.errno, 1)
16521656

1653-
@unittest.skipIf(Py_DEBUG_WIN32, "Avoid mixing debug/release CRT on Windows")
16541657
def test_lib_reason(self):
16551658
# Test the library and reason attributes
16561659
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
1657-
with self.assertRaises(ssl.SSLError) as cm:
1658-
ctx.load_dh_params(CERTFILE)
1660+
try:
1661+
with self.assertRaises(ssl.SSLError) as cm:
1662+
ctx.load_dh_params(CERTFILE)
1663+
except RuntimeError:
1664+
if Py_DEBUG_WIN32:
1665+
self.skipTest("not supported on Win32 debug build")
1666+
raise
1667+
16591668
self.assertEqual(cm.exception.library, 'PEM')
16601669
regex = "(NO_START_LINE|UNSUPPORTED_PUBLIC_KEY_TYPE)"
16611670
self.assertRegex(cm.exception.reason, regex)
@@ -2773,6 +2782,14 @@ def try_protocol_combo(server_protocol, client_protocol, expect_success,
27732782
% (expect_success, stats['version']))
27742783

27752784

2785+
def supports_kx_alias(ctx, aliases):
2786+
for cipher in ctx.get_ciphers():
2787+
for alias in aliases:
2788+
if f"Kx={alias}" in cipher['description']:
2789+
return True
2790+
return False
2791+
2792+
27762793
class ThreadedTests(unittest.TestCase):
27772794

27782795
@support.requires_resource('walltime')
@@ -3960,21 +3977,30 @@ def test_no_legacy_server_connect(self):
39603977
chatty=True, connectionchatty=True,
39613978
sni_name=hostname)
39623979

3963-
@unittest.skipIf(Py_DEBUG_WIN32, "Avoid mixing debug/release CRT on Windows")
39643980
def test_dh_params(self):
3965-
# Check we can get a connection with ephemeral Diffie-Hellman
3981+
# Check we can get a connection with ephemeral finite-field
3982+
# Diffie-Hellman (if supported).
39663983
client_context, server_context, hostname = testing_context()
3984+
dhe_aliases = {"ADH", "EDH", "DHE"}
3985+
if not (supports_kx_alias(client_context, dhe_aliases)
3986+
and supports_kx_alias(server_context, dhe_aliases)):
3987+
self.skipTest("libssl doesn't support ephemeral DH")
39673988
# test scenario needs TLS <= 1.2
39683989
client_context.maximum_version = ssl.TLSVersion.TLSv1_2
3969-
server_context.load_dh_params(DHFILE)
3990+
try:
3991+
server_context.load_dh_params(DHFILE)
3992+
except RuntimeError:
3993+
if Py_DEBUG_WIN32:
3994+
self.skipTest("not supported on Win32 debug build")
3995+
raise
39703996
server_context.set_ciphers("kEDH")
39713997
server_context.maximum_version = ssl.TLSVersion.TLSv1_2
39723998
stats = server_params_test(client_context, server_context,
39733999
chatty=True, connectionchatty=True,
39744000
sni_name=hostname)
39754001
cipher = stats["cipher"][0]
39764002
parts = cipher.split("-")
3977-
if "ADH" not in parts and "EDH" not in parts and "DHE" not in parts:
4003+
if not dhe_aliases.intersection(parts):
39784004
self.fail("Non-DH key exchange: " + cipher[0])
39794005

39804006
def test_ecdh_curve(self):
@@ -4607,14 +4633,18 @@ def keylog_lines(self, fname=os_helper.TESTFN):
46074633
return len(list(f))
46084634

46094635
@requires_keylog
4610-
@unittest.skipIf(Py_DEBUG_WIN32, "Avoid mixing debug/release CRT on Windows")
46114636
def test_keylog_defaults(self):
46124637
self.addCleanup(os_helper.unlink, os_helper.TESTFN)
46134638
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
46144639
self.assertEqual(ctx.keylog_filename, None)
46154640

46164641
self.assertFalse(os.path.isfile(os_helper.TESTFN))
4617-
ctx.keylog_filename = os_helper.TESTFN
4642+
try:
4643+
ctx.keylog_filename = os_helper.TESTFN
4644+
except RuntimeError:
4645+
if Py_DEBUG_WIN32:
4646+
self.skipTest("not supported on Win32 debug build")
4647+
raise
46184648
self.assertEqual(ctx.keylog_filename, os_helper.TESTFN)
46194649
self.assertTrue(os.path.isfile(os_helper.TESTFN))
46204650
self.assertEqual(self.keylog_lines(), 1)
@@ -4631,12 +4661,17 @@ def test_keylog_defaults(self):
46314661
ctx.keylog_filename = 1
46324662

46334663
@requires_keylog
4634-
@unittest.skipIf(Py_DEBUG_WIN32, "Avoid mixing debug/release CRT on Windows")
46354664
def test_keylog_filename(self):
46364665
self.addCleanup(os_helper.unlink, os_helper.TESTFN)
46374666
client_context, server_context, hostname = testing_context()
46384667

4639-
client_context.keylog_filename = os_helper.TESTFN
4668+
try:
4669+
client_context.keylog_filename = os_helper.TESTFN
4670+
except RuntimeError:
4671+
if Py_DEBUG_WIN32:
4672+
self.skipTest("not supported on Win32 debug build")
4673+
raise
4674+
46404675
server = ThreadedEchoServer(context=server_context, chatty=False)
46414676
with server:
46424677
with client_context.wrap_socket(socket.socket(),
@@ -4669,7 +4704,6 @@ def test_keylog_filename(self):
46694704
@requires_keylog
46704705
@unittest.skipIf(sys.flags.ignore_environment,
46714706
"test is not compatible with ignore_environment")
4672-
@unittest.skipIf(Py_DEBUG_WIN32, "Avoid mixing debug/release CRT on Windows")
46734707
def test_keylog_env(self):
46744708
self.addCleanup(os_helper.unlink, os_helper.TESTFN)
46754709
with unittest.mock.patch.dict(os.environ):
@@ -4679,7 +4713,12 @@ def test_keylog_env(self):
46794713
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
46804714
self.assertEqual(ctx.keylog_filename, None)
46814715

4682-
ctx = ssl.create_default_context()
4716+
try:
4717+
ctx = ssl.create_default_context()
4718+
except RuntimeError:
4719+
if Py_DEBUG_WIN32:
4720+
self.skipTest("not supported on Win32 debug build")
4721+
raise
46834722
self.assertEqual(ctx.keylog_filename, os_helper.TESTFN)
46844723

46854724
ctx = ssl._create_stdlib_context()

Lib/test/test_ucn.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import ast
1111
import unittest
1212
import unicodedata
13+
import urllib.error
1314

1415
from test import support
1516
from http.client import HTTPException
@@ -181,20 +182,23 @@ def check_version(testfile):
181182
try:
182183
testdata = support.open_urlresource(url, encoding="utf-8",
183184
check=check_version)
184-
except (OSError, HTTPException):
185-
self.skipTest("Could not retrieve " + url)
186-
self.addCleanup(testdata.close)
187-
for line in testdata:
188-
line = line.strip()
189-
if not line or line.startswith('#'):
190-
continue
191-
seqname, codepoints = line.split(';')
192-
codepoints = ''.join(chr(int(cp, 16)) for cp in codepoints.split())
193-
self.assertEqual(unicodedata.lookup(seqname), codepoints)
194-
with self.assertRaises(SyntaxError):
195-
self.checkletter(seqname, None)
196-
with self.assertRaises(KeyError):
197-
unicodedata.ucd_3_2_0.lookup(seqname)
185+
except urllib.error.HTTPError as exc:
186+
exc.close()
187+
self.skipTest(f"Could not retrieve {url}: {exc!r}")
188+
except (OSError, HTTPException) as exc:
189+
self.skipTest(f"Could not retrieve {url}: {exc!r}")
190+
with testdata:
191+
for line in testdata:
192+
line = line.strip()
193+
if not line or line.startswith('#'):
194+
continue
195+
seqname, codepoints = line.split(';')
196+
codepoints = ''.join(chr(int(cp, 16)) for cp in codepoints.split())
197+
self.assertEqual(unicodedata.lookup(seqname), codepoints)
198+
with self.assertRaises(SyntaxError):
199+
self.checkletter(seqname, None)
200+
with self.assertRaises(KeyError):
201+
unicodedata.ucd_3_2_0.lookup(seqname)
198202

199203
def test_errors(self):
200204
self.assertRaises(TypeError, unicodedata.name)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
``test_ssl.test_dh_params`` is skipped if the underlying TLS library does not support finite-field ephemeral Diffie-Hellman.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Update bundled version of OpenSSL to 3.0.16. The new build also disables
2+
uplink support, which may be relevant to embedders but has no impact on
3+
normal use.

Misc/externals.spdx.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,21 +48,21 @@
4848
"checksums": [
4949
{
5050
"algorithm": "SHA256",
51-
"checksumValue": "1550c87996a0858474a9dd179deab2c55eb73726b9a140b32865b02fd3d8a86b"
51+
"checksumValue": "6bb739ecddbd2cfb6d255eb5898437a9b5739277dee931338d3275bac5d96ba2"
5252
}
5353
],
54-
"downloadLocation": "https://github.com/python/cpython-source-deps/archive/refs/tags/openssl-3.0.15.tar.gz",
54+
"downloadLocation": "https://github.com/python/cpython-source-deps/archive/refs/tags/openssl-3.0.16.tar.gz",
5555
"externalRefs": [
5656
{
5757
"referenceCategory": "SECURITY",
58-
"referenceLocator": "cpe:2.3:a:openssl:openssl:3.0.15:*:*:*:*:*:*:*",
58+
"referenceLocator": "cpe:2.3:a:openssl:openssl:3.0.16:*:*:*:*:*:*:*",
5959
"referenceType": "cpe23Type"
6060
}
6161
],
6262
"licenseConcluded": "NOASSERTION",
6363
"name": "openssl",
6464
"primaryPackagePurpose": "SOURCE",
65-
"versionInfo": "3.0.15"
65+
"versionInfo": "3.0.16"
6666
},
6767
{
6868
"SPDXID": "SPDXRef-PACKAGE-sqlite",

Modules/_ssl.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4136,6 +4136,12 @@ _ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath)
41364136
FILE *f;
41374137
DH *dh;
41384138

4139+
#if defined(MS_WINDOWS) && defined(_DEBUG)
4140+
PyErr_SetString(PyExc_NotImplementedError,
4141+
"load_dh_params: unavailable on Windows debug build");
4142+
return NULL;
4143+
#endif
4144+
41394145
f = _Py_fopen_obj(filepath, "rb");
41404146
if (f == NULL)
41414147
return NULL;

0 commit comments

Comments
 (0)