Skip to content

Commit 5bc463a

Browse files
authored
Merge branch 'main' into fix-136859
2 parents e898f39 + 4a151ca commit 5bc463a

File tree

16 files changed

+936
-417
lines changed

16 files changed

+936
-417
lines changed

Doc/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ venv:
170170
echo "venv already exists."; \
171171
echo "To recreate it, remove it first with \`make clean-venv'."; \
172172
else \
173+
set -e; \
173174
echo "Creating venv in $(VENVDIR)"; \
174175
if $(UV) --version >/dev/null 2>&1; then \
175176
$(UV) venv --python=$(PYTHON) $(VENVDIR); \

Doc/library/gc.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ The :mod:`gc` module provides the following functions:
6060
The effect of calling ``gc.collect()`` while the interpreter is already
6161
performing a collection is undefined.
6262

63-
.. versionchanged:: 3.13
63+
.. versionchanged:: 3.14
6464
``generation=1`` performs an increment of collection.
6565

6666

@@ -83,13 +83,13 @@ The :mod:`gc` module provides the following functions:
8383
returned. If *generation* is not ``None``, return only the objects as follows:
8484

8585
* 0: All objects in the young generation
86-
* 1: No objects, as there is no generation 1 (as of Python 3.13)
86+
* 1: No objects, as there is no generation 1 (as of Python 3.14)
8787
* 2: All objects in the old generation
8888

8989
.. versionchanged:: 3.8
9090
New *generation* parameter.
9191

92-
.. versionchanged:: 3.13
92+
.. versionchanged:: 3.14
9393
Generation 1 is removed
9494

9595
.. audit-event:: gc.get_objects generation gc.get_objects
@@ -142,7 +142,7 @@ The :mod:`gc` module provides the following functions:
142142

143143
See `Garbage collector design <https://devguide.python.org/garbage_collector>`_ for more information.
144144

145-
.. versionchanged:: 3.13
145+
.. versionchanged:: 3.14
146146
*threshold2* is ignored
147147

148148

Doc/library/tarfile.rst

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,6 +1353,9 @@ Command-line options
13531353
Examples
13541354
--------
13551355

1356+
Reading examples
1357+
~~~~~~~~~~~~~~~~~~~
1358+
13561359
How to extract an entire tar archive to the current working directory::
13571360

13581361
import tarfile
@@ -1375,6 +1378,23 @@ a generator function instead of a list::
13751378
tar.extractall(members=py_files(tar))
13761379
tar.close()
13771380

1381+
How to read a gzip compressed tar archive and display some member information::
1382+
1383+
import tarfile
1384+
tar = tarfile.open("sample.tar.gz", "r:gz")
1385+
for tarinfo in tar:
1386+
print(tarinfo.name, "is", tarinfo.size, "bytes in size and is ", end="")
1387+
if tarinfo.isreg():
1388+
print("a regular file.")
1389+
elif tarinfo.isdir():
1390+
print("a directory.")
1391+
else:
1392+
print("something else.")
1393+
tar.close()
1394+
1395+
Writing examples
1396+
~~~~~~~~~~~~~~~~
1397+
13781398
How to create an uncompressed tar archive from a list of filenames::
13791399

13801400
import tarfile
@@ -1390,19 +1410,15 @@ The same example using the :keyword:`with` statement::
13901410
for name in ["foo", "bar", "quux"]:
13911411
tar.add(name)
13921412

1393-
How to read a gzip compressed tar archive and display some member information::
1413+
How to create and write an archive to stdout using
1414+
:data:`sys.stdout.buffer <sys.stdout>` in the *fileobj* parameter
1415+
in :meth:`TarFile.add`::
13941416

1395-
import tarfile
1396-
tar = tarfile.open("sample.tar.gz", "r:gz")
1397-
for tarinfo in tar:
1398-
print(tarinfo.name, "is", tarinfo.size, "bytes in size and is ", end="")
1399-
if tarinfo.isreg():
1400-
print("a regular file.")
1401-
elif tarinfo.isdir():
1402-
print("a directory.")
1403-
else:
1404-
print("something else.")
1405-
tar.close()
1417+
import sys
1418+
import tarfile
1419+
with tarfile.open("sample.tar.gz", "w|gz", fileobj=sys.stdout.buffer) as tar:
1420+
for name in ["foo", "bar", "quux"]:
1421+
tar.add(name)
14061422

14071423
How to create an archive and reset the user information using the *filter*
14081424
parameter in :meth:`TarFile.add`::

Doc/whatsnew/3.14.rst

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,30 @@ free-threaded build and false for the GIL-enabled build.
10581058

10591059
(Contributed by Neil Schemenauer and Kumar Aditya in :gh:`130010`.)
10601060

1061+
.. _whatsnew314-incremental-gc:
1062+
1063+
Incremental garbage collection
1064+
------------------------------
1065+
1066+
The cycle garbage collector is now incremental.
1067+
This means that maximum pause times are reduced
1068+
by an order of magnitude or more for larger heaps.
1069+
1070+
There are now only two generations: young and old.
1071+
When :func:`gc.collect` is not called directly, the
1072+
GC is invoked a little less frequently. When invoked, it
1073+
collects the young generation and an increment of the
1074+
old generation, instead of collecting one or more generations.
1075+
1076+
The behavior of :func:`!gc.collect` changes slightly:
1077+
1078+
* ``gc.collect(1)``: Performs an increment of garbage collection,
1079+
rather than collecting generation 1.
1080+
* Other calls to :func:`!gc.collect` are unchanged.
1081+
1082+
(Contributed by Mark Shannon in :gh:`108362`.)
1083+
1084+
10611085
Other language changes
10621086
======================
10631087

@@ -1486,6 +1510,36 @@ functools
14861510
(Contributed by Sayandip Dutta in :gh:`125916`.)
14871511

14881512

1513+
gc
1514+
--
1515+
1516+
The cyclic garbage collector is now incremental,
1517+
which changes the meaning of the results of
1518+
:meth:`~gc.get_threshold` and :meth:`~gc.set_threshold`
1519+
as well as :meth:`~gc.get_count` and :meth:`~gc.get_stats`.
1520+
1521+
* For backwards compatibility, :meth:`~gc.get_threshold` continues to return
1522+
a three-item tuple.
1523+
The first value is the threshold for young collections, as before;
1524+
the second value determines the rate at which the old collection is scanned
1525+
(the default is 10, and higher values mean that the old collection
1526+
is scanned more slowly).
1527+
The third value is meaningless and is always zero.
1528+
1529+
* :meth:`~gc.set_threshold` ignores any items after the second.
1530+
1531+
* :meth:`~gc.get_count` and :meth:`~gc.get_stats` continue to return
1532+
the same format of results.
1533+
The only difference is that instead of the results referring to
1534+
the young, aging and old generations,
1535+
the results refer to the young generation
1536+
and the aging and collecting spaces of the old generation.
1537+
1538+
In summary, code that attempted to manipulate the behavior of the cycle GC
1539+
may not work exactly as intended, but it is very unlikely to be harmful.
1540+
All other code will work just fine.
1541+
1542+
14891543
getopt
14901544
------
14911545

@@ -2233,6 +2287,7 @@ asyncio
22332287
(Contributed by Yury Selivanov, Pablo Galindo Salgado, and Łukasz Langa
22342288
in :gh:`91048`.)
22352289

2290+
22362291
base64
22372292
------
22382293

@@ -2241,6 +2296,15 @@ base64
22412296
(Contributed by Bénédikt Tran, Chris Markiewicz, and Adam Turner in :gh:`118761`.)
22422297

22432298

2299+
gc
2300+
--
2301+
2302+
* The new :ref:`incremental garbage collector <whatsnew314-incremental-gc>`
2303+
means that maximum pause times are reduced
2304+
by an order of magnitude or more for larger heaps.
2305+
(Contributed by Mark Shannon in :gh:`108362`.)
2306+
2307+
22442308
io
22452309
---
22462310
* :mod:`io` which provides the built-in :func:`open` makes less system calls
@@ -2707,6 +2771,13 @@ Changes in the Python API
27072771
Wrap it in :func:`staticmethod` if you want to preserve the old behavior.
27082772
(Contributed by Serhiy Storchaka and Dominykas Grigonis in :gh:`121027`.)
27092773

2774+
* The :ref:`garbage collector is now incremental <whatsnew314-incremental-gc>`,
2775+
which means that the behavior of :func:`gc.collect` changes slightly:
2776+
2777+
* ``gc.collect(1)``: Performs an increment of garbage collection,
2778+
rather than collecting generation 1.
2779+
* Other calls to :func:`!gc.collect` are unchanged.
2780+
27102781
* The :func:`locale.nl_langinfo` function now sets temporarily the ``LC_CTYPE``
27112782
locale in some cases.
27122783
This temporary change affects other threads.

Lib/hashlib.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@
8080
}
8181

8282
def __get_builtin_constructor(name):
83+
if not isinstance(name, str):
84+
# Since this function is only used by new(), we use the same
85+
# exception as _hashlib.new() when 'name' is of incorrect type.
86+
err = f"new() argument 'name' must be str, not {type(name).__name__}"
87+
raise TypeError(err)
8388
cache = __builtin_constructor_cache
8489
constructor = cache.get(name)
8590
if constructor is not None:
@@ -120,20 +125,33 @@ def __get_builtin_constructor(name):
120125
if constructor is not None:
121126
return constructor
122127

123-
raise ValueError('unsupported hash type ' + name)
128+
# Keep the message in sync with hashlib.h::HASHLIB_UNSUPPORTED_ALGORITHM.
129+
raise ValueError(f'unsupported hash algorithm {name}')
124130

125131

126132
def __get_openssl_constructor(name):
133+
# This function is only used until the module has been initialized.
134+
assert isinstance(name, str), "invalid call to __get_openssl_constructor()"
127135
if name in __block_openssl_constructor:
128136
# Prefer our builtin blake2 implementation.
129137
return __get_builtin_constructor(name)
130138
try:
131-
# MD5, SHA1, and SHA2 are in all supported OpenSSL versions
132-
# SHA3/shake are available in OpenSSL 1.1.1+
139+
# Fetch the OpenSSL hash function if it exists,
140+
# independently of the context security policy.
133141
f = getattr(_hashlib, 'openssl_' + name)
134-
# Allow the C module to raise ValueError. The function will be
135-
# defined but the hash not actually available. Don't fall back to
136-
# builtin if the current security policy blocks a digest, bpo#40695.
142+
# Check if the context security policy blocks the digest or not
143+
# by allowing the C module to raise a ValueError. The function
144+
# will be defined but the hash will not be available at runtime.
145+
#
146+
# We use "usedforsecurity=False" to prevent falling back to the
147+
# built-in function in case the security policy does not allow it.
148+
#
149+
# Note that this only affects the explicit named constructors,
150+
# and not the algorithms exposed through hashlib.new() which
151+
# can still be resolved to a built-in function even if the
152+
# current security policy does not allow it.
153+
#
154+
# See https://github.com/python/cpython/issues/84872.
137155
f(usedforsecurity=False)
138156
# Use the C function directly (very fast)
139157
return f
@@ -154,6 +172,8 @@ def __hash_new(name, *args, **kwargs):
154172
optionally initialized with data (which must be a bytes-like object).
155173
"""
156174
if name in __block_openssl_constructor:
175+
# __block_openssl_constructor is expected to contain strings only
176+
assert isinstance(name, str), f"unexpected name: {name}"
157177
# Prefer our builtin blake2 implementation.
158178
return __get_builtin_constructor(name)(*args, **kwargs)
159179
try:

Lib/hmac.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@
2626
digest_size = None
2727

2828

29+
def _is_shake_constructor(digest_like):
30+
if isinstance(digest_like, str):
31+
name = digest_like
32+
else:
33+
h = digest_like() if callable(digest_like) else digest_like.new()
34+
if not isinstance(name := getattr(h, "name", None), str):
35+
return False
36+
return name.startswith(("shake", "SHAKE"))
37+
38+
2939
def _get_digest_constructor(digest_like):
3040
if callable(digest_like):
3141
return digest_like
@@ -109,6 +119,8 @@ def _init_old(self, key, msg, digestmod):
109119
import warnings
110120

111121
digest_cons = _get_digest_constructor(digestmod)
122+
if _is_shake_constructor(digest_cons):
123+
raise ValueError(f"unsupported hash algorithm {digestmod}")
112124

113125
self._hmac = None
114126
self._outer = digest_cons()
@@ -243,6 +255,8 @@ def digest(key, msg, digest):
243255

244256
def _compute_digest_fallback(key, msg, digest):
245257
digest_cons = _get_digest_constructor(digest)
258+
if _is_shake_constructor(digest_cons):
259+
raise ValueError(f"unsupported hash algorithm {digest}")
246260
inner = digest_cons()
247261
outer = digest_cons()
248262
blocksize = getattr(inner, 'block_size', 64)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy