Skip to content

Commit 0864441

Browse files
authored
Merge branch 'main' into windows-add-sys-abiflags
2 parents 45be11d + bc5a028 commit 0864441

File tree

16 files changed

+200
-62
lines changed

16 files changed

+200
-62
lines changed

Doc/library/os.rst

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

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

36983698
import os
36993699
from os.path import join, getsize
3700-
for root, dirs, files in os.walk('python/Lib/email'):
3700+
for root, dirs, files in os.walk('python/Lib/xml'):
37013701
print(root, "consumes", end=" ")
37023702
print(sum(getsize(join(root, name)) for name in files), end=" ")
37033703
print("bytes in", len(files), "non-directory files")
3704-
if 'CVS' in dirs:
3705-
dirs.remove('CVS') # don't visit CVS directories
3704+
if '__pycache__' in dirs:
3705+
dirs.remove('__pycache__') # don't visit __pycache__ directories
37063706

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

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

37603760
import os
3761-
for root, dirs, files, rootfd in os.fwalk('python/Lib/email'):
3761+
for root, dirs, files, rootfd in os.fwalk('python/Lib/xml'):
37623762
print(root, "consumes", end="")
37633763
print(sum([os.stat(name, dir_fd=rootfd).st_size for name in files]),
37643764
end="")
37653765
print("bytes in", len(files), "non-directory files")
3766-
if 'CVS' in dirs:
3767-
dirs.remove('CVS') # don't visit CVS directories
3766+
if '__pycache__' in dirs:
3767+
dirs.remove('__pycache__') # don't visit __pycache__ directories
37683768

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

Doc/library/socket.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -882,10 +882,10 @@ The following functions all create :ref:`socket objects <socket-objects>`.
882882
, a default reasonable value is chosen.
883883
*reuse_port* dictates whether to set the :data:`SO_REUSEPORT` socket option.
884884

885-
If *dualstack_ipv6* is true and the platform supports it the socket will
886-
be able to accept both IPv4 and IPv6 connections, else it will raise
887-
:exc:`ValueError`. Most POSIX platforms and Windows are supposed to support
888-
this functionality.
885+
If *dualstack_ipv6* is true, *family* is :data:`AF_INET6` and the platform
886+
supports it the socket will be able to accept both IPv4 and IPv6 connections,
887+
else it will raise :exc:`ValueError`. Most POSIX platforms and Windows are
888+
supposed to support this functionality.
889889
When this functionality is enabled the address returned by
890890
:meth:`socket.getpeername` when an IPv4 connection occurs will be an IPv6
891891
address represented as an IPv4-mapped IPv6 address.

Doc/library/stdtypes.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4780,7 +4780,7 @@ can be used interchangeably to index the same dictionary entry.
47804780
such as an empty list. To get distinct values, use a :ref:`dict
47814781
comprehension <dict>` instead.
47824782

4783-
.. method:: get(key, default=None)
4783+
.. method:: get(key, default=None, /)
47844784

47854785
Return the value for *key* if *key* is in the dictionary, else *default*.
47864786
If *default* is not given, it defaults to ``None``, so that this method
@@ -4822,7 +4822,7 @@ can be used interchangeably to index the same dictionary entry.
48224822

48234823
.. versionadded:: 3.8
48244824

4825-
.. method:: setdefault(key, default=None)
4825+
.. method:: setdefault(key, default=None, /)
48264826

48274827
If *key* is in the dictionary, return its value. If not, insert *key*
48284828
with a value of *default* and return *default*. *default* defaults to

Include/internal/pycore_symtable.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ typedef struct _symtable_entry {
126126
unsigned ste_method : 1; /* true if block is a function block defined in class scope */
127127
unsigned ste_has_conditional_annotations : 1; /* true if block has conditionally executed annotations */
128128
unsigned ste_in_conditional_block : 1; /* set while we are inside a conditionally executed block */
129+
unsigned ste_in_unevaluated_annotation : 1; /* set while we are processing an annotation that will not be evaluated */
129130
int ste_comp_iter_expr; /* non-zero if visiting a comprehension range expression */
130131
_Py_SourceLocation ste_loc; /* source location of block */
131132
struct _symtable_entry *ste_annotation_block; /* symbol table entry for this entry's annotations */

Lib/os.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -345,12 +345,12 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
345345
346346
import os
347347
from os.path import join, getsize
348-
for root, dirs, files in os.walk('python/Lib/email'):
348+
for root, dirs, files in os.walk('python/Lib/xml'):
349349
print(root, "consumes ")
350350
print(sum(getsize(join(root, name)) for name in files), end=" ")
351351
print("bytes in", len(files), "non-directory files")
352-
if 'CVS' in dirs:
353-
dirs.remove('CVS') # don't visit CVS directories
352+
if '__pycache__' in dirs:
353+
dirs.remove('__pycache__') # don't visit __pycache__ directories
354354
355355
"""
356356
sys.audit("os.walk", top, topdown, onerror, followlinks)
@@ -460,13 +460,13 @@ def fwalk(top=".", topdown=True, onerror=None, *, follow_symlinks=False, dir_fd=
460460
Example:
461461
462462
import os
463-
for root, dirs, files, rootfd in os.fwalk('python/Lib/email'):
463+
for root, dirs, files, rootfd in os.fwalk('python/Lib/xml'):
464464
print(root, "consumes", end="")
465465
print(sum(os.stat(name, dir_fd=rootfd).st_size for name in files),
466466
end="")
467467
print("bytes in", len(files), "non-directory files")
468-
if 'CVS' in dirs:
469-
dirs.remove('CVS') # don't visit CVS directories
468+
if '__pycache__' in dirs:
469+
dirs.remove('__pycache__') # don't visit __pycache__ directories
470470
"""
471471
sys.audit("os.fwalk", top, topdown, onerror, follow_symlinks, dir_fd)
472472
top = fspath(top)

Lib/test/test_ssl.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2782,6 +2782,14 @@ def try_protocol_combo(server_protocol, client_protocol, expect_success,
27822782
% (expect_success, stats['version']))
27832783

27842784

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+
27852793
class ThreadedTests(unittest.TestCase):
27862794

27872795
@support.requires_resource('walltime')
@@ -4042,8 +4050,13 @@ def test_no_legacy_server_connect(self):
40424050
sni_name=hostname)
40434051

40444052
def test_dh_params(self):
4045-
# Check we can get a connection with ephemeral Diffie-Hellman
4053+
# Check we can get a connection with ephemeral finite-field
4054+
# Diffie-Hellman (if supported).
40464055
client_context, server_context, hostname = testing_context()
4056+
dhe_aliases = {"ADH", "EDH", "DHE"}
4057+
if not (supports_kx_alias(client_context, dhe_aliases)
4058+
and supports_kx_alias(server_context, dhe_aliases)):
4059+
self.skipTest("libssl doesn't support ephemeral DH")
40474060
# test scenario needs TLS <= 1.2
40484061
client_context.maximum_version = ssl.TLSVersion.TLSv1_2
40494062
try:
@@ -4059,7 +4072,7 @@ def test_dh_params(self):
40594072
sni_name=hostname)
40604073
cipher = stats["cipher"][0]
40614074
parts = cipher.split("-")
4062-
if "ADH" not in parts and "EDH" not in parts and "DHE" not in parts:
4075+
if not dhe_aliases.intersection(parts):
40634076
self.fail("Non-DH key exchange: " + cipher[0])
40644077

40654078
def test_ecdh_curve(self):

Lib/test/test_tools/test_msgfmt.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Tests for the Tools/i18n/msgfmt.py tool."""
22

33
import json
4+
import struct
45
import sys
56
import unittest
67
from gettext import GNUTranslations
@@ -40,6 +41,31 @@ def test_compilation(self):
4041

4142
self.assertDictEqual(actual._catalog, expected._catalog)
4243

44+
def test_binary_header(self):
45+
with temp_cwd():
46+
tmp_mo_file = 'messages.mo'
47+
compile_messages(data_dir / "general.po", tmp_mo_file)
48+
with open(tmp_mo_file, 'rb') as f:
49+
mo_data = f.read()
50+
51+
(
52+
magic,
53+
version,
54+
num_strings,
55+
orig_table_offset,
56+
trans_table_offset,
57+
hash_table_size,
58+
hash_table_offset,
59+
) = struct.unpack("=7I", mo_data[:28])
60+
61+
self.assertEqual(magic, 0x950412de)
62+
self.assertEqual(version, 0)
63+
self.assertEqual(num_strings, 9)
64+
self.assertEqual(orig_table_offset, 28)
65+
self.assertEqual(trans_table_offset, 100)
66+
self.assertEqual(hash_table_size, 0)
67+
self.assertEqual(hash_table_offset, 0)
68+
4369
def test_translations(self):
4470
with open(data_dir / 'general.mo', 'rb') as f:
4571
t = GNUTranslations(f)

Lib/test/test_type_annotations.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import textwrap
44
import types
55
import unittest
6-
from test.support import run_code, check_syntax_error
6+
from test.support import run_code, check_syntax_error, cpython_only
77

88

99
class TypeAnnotationTests(unittest.TestCase):
@@ -109,6 +109,16 @@ class D(metaclass=C):
109109
del D.__annotations__
110110
self.assertEqual(D.__annotations__, {})
111111

112+
@cpython_only
113+
def test_no_cell(self):
114+
# gh-130924: Test that uses of annotations in local scopes do not
115+
# create cell variables.
116+
def f(x):
117+
a: x
118+
return x
119+
120+
self.assertEqual(f.__code__.co_cellvars, ())
121+
112122

113123
def build_module(code: str, name: str = "top") -> types.ModuleType:
114124
ns = run_code(code)
@@ -352,6 +362,7 @@ def test_no_exotic_expressions_in_unevaluated_annotations(self):
352362
check_syntax_error(self, prelude + "(x): (yield)", "yield expression cannot be used within an annotation")
353363
check_syntax_error(self, prelude + "(x): (yield from x)", "yield expression cannot be used within an annotation")
354364
check_syntax_error(self, prelude + "(x): (y := 3)", "named expression cannot be used within an annotation")
365+
check_syntax_error(self, prelude + "(x): (__debug__ := 3)", "named expression cannot be used within an annotation")
355366
check_syntax_error(self, prelude + "(x): (await 42)", "await expression cannot be used within an annotation")
356367

357368
def test_ignore_non_simple_annotations(self):
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Add fast path for small and medium-size integers in
2+
:c:func:`PyLong_FromInt32`, :c:func:`PyLong_FromUInt32`,
3+
:c:func:`PyLong_FromInt64` and
4+
:c:func:`PyLong_FromUInt64`. Patch by Chris Eibl.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Usage of a name in a function-scope annotation no longer triggers creation
2+
of a cell for that variable. This fixes a regression in earlier alphas of
3+
Python 3.14.

0 commit comments

Comments
 (0)