Skip to content

Commit ca04150

Browse files
committed
Merge remote-tracking branch 'upstream/main' into fix-issue-138978
2 parents 09ad373 + b38e073 commit ca04150

37 files changed

Lines changed: 543 additions & 207 deletions

Doc/library/ast.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2254,7 +2254,7 @@ and classes for traversing abstract syntax trees:
22542254

22552255
In addition, if ``mode`` is ``'func_type'``, the input syntax is
22562256
modified to correspond to :pep:`484` "signature type comments",
2257-
e.g. ``(str, int) -> List[str]``.
2257+
for example ``(str, int) -> List[str]``.
22582258

22592259
Setting ``feature_version`` to a tuple ``(major, minor)`` will result in
22602260
a "best-effort" attempt to parse using that Python version's grammar.

Doc/whatsnew/3.16.rst

Lines changed: 60 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,16 @@ codecs
120120
even when a built-in codec of the same name exists.
121121
(Contributed by Serhiy Storchaka in :gh:`152997`.)
122122

123+
124+
concurrent.futures
125+
------------------
126+
127+
* The iterator returned by :meth:`concurrent.futures.Executor.map` is no longer
128+
automatically closed if a function call raises an exception.
129+
Use method :meth:`!close` to explicitly close the iterator.
130+
(Contributed by xzmeng and Serhiy Storchaka in :gh:`108518`.)
131+
132+
123133
csv
124134
---
125135

@@ -140,6 +150,19 @@ csv
140150
instead of always returning ``'\r\n'``.
141151
(Contributed by Serhiy Storchaka in :gh:`75008`.)
142152

153+
154+
ctypes
155+
------
156+
157+
* Add :func:`ctypes.util.struct` for generating :class:`~ctypes.Structure` types
158+
from an annotation-based syntax, similar to how the :mod:`dataclasses` module
159+
is used.
160+
(Contributed by Peter Bierma in :gh:`104533`.)
161+
* Add :func:`ctypes.util.wrap_dll_function` for generating function pointers
162+
through a function signature.
163+
(Contributed by Peter Bierma in :gh:`153903`.)
164+
165+
143166
curses
144167
------
145168

@@ -274,27 +297,6 @@ curses
274297
(Contributed by Serhiy Storchaka in :gh:`133031`.)
275298

276299

277-
ctypes
278-
------
279-
280-
* Add :func:`ctypes.util.struct` for generating :class:`~ctypes.Structure` types
281-
from an annotation-based syntax, similar to how the :mod:`dataclasses` module
282-
is used.
283-
(Contributed by Peter Bierma in :gh:`104533`.)
284-
* Add :func:`ctypes.util.wrap_dll_function` for generating function pointers
285-
through a function signature.
286-
(Contributed by Peter Bierma in :gh:`153903`.)
287-
288-
289-
concurrent.futures
290-
------------------
291-
292-
* The iterator returned by :meth:`concurrent.futures.Executor.map` is no longer
293-
automatically closed if a function call raises an exception.
294-
Use method :meth:`!close` to explicitly close the iterator.
295-
(Contributed by xzmeng and Serhiy Storchaka in :gh:`108518`.)
296-
297-
298300
encodings
299301
---------
300302

@@ -310,12 +312,6 @@ gzip
310312
which is passed on to the constructor of the :class:`~gzip.GzipFile` class.
311313
(Contributed by Marin Misur in :gh:`91372`.)
312314

313-
io
314-
--
315-
316-
* Add :meth:`io.BytesIO.peek` method to read without advancing position.
317-
(Contributed by Marcel Martin in :gh:`90533`.)
318-
319315

320316
imaplib
321317
-------
@@ -368,12 +364,20 @@ imaplib
368364
(Contributed by Serhiy Storchaka in :gh:`153521`.)
369365

370366

367+
io
368+
--
369+
370+
* Add :meth:`io.BytesIO.peek` method to read without advancing position.
371+
(Contributed by Marcel Martin in :gh:`90533`.)
372+
373+
371374
ipaddress
372375
---------
373376

374-
Add :meth:`~ipaddress.IPv4Network.next_network` and
375-
:meth:`~ipaddress.IPv6Network.next_network` methods to find the next nearest
376-
network with a specific prefix size.
377+
* Add :meth:`~ipaddress.IPv4Network.next_network` and
378+
:meth:`~ipaddress.IPv6Network.next_network` methods to find the next nearest
379+
network with a specific prefix size.
380+
(Contributed by Faisal Mahmood in :gh:`87027`.)
377381

378382

379383
logging
@@ -413,16 +417,15 @@ math
413417
multiprocessing
414418
---------------
415419

416-
* Add the optional ``buffersize`` parameter to
420+
* Add the optional *buffersize* parameter to
417421
:meth:`multiprocessing.pool.Pool.imap` and
418422
:meth:`multiprocessing.pool.Pool.imap_unordered` to limit the number of
419423
submitted tasks whose results have not yet been yielded. If the buffer is
420-
full, iteration over the *iterables* pauses until a result is yielded from
424+
full, iteration over the *iterable* pauses until a result is yielded from
421425
the buffer. To fully utilize pool's capacity when using this feature, set
422426
*buffersize* at least to the number of processes in pool (to consume
423427
*iterable* as you go), or even higher (to prefetch the next
424428
``N=buffersize-processes`` arguments).
425-
426429
(Contributed by Oleksandr Baltian in :gh:`136871`.)
427430

428431

@@ -471,6 +474,7 @@ shlex
471474
a string, even if it is already safe for a shell without being quoted.
472475
(Contributed by Jay Berry in :gh:`148846`.)
473476

477+
474478
sqlite3
475479
-------
476480

@@ -479,6 +483,7 @@ sqlite3
479483
:exc:`SystemError` or :exc:`ValueError`.
480484
(Contributed by Jiseok CHOI in :gh:`150449`.)
481485

486+
482487
symtable
483488
--------
484489

@@ -673,12 +678,6 @@ re
673678
(Contributed by Serhiy Storchaka in :gh:`152033` and Pieter Eendebak in
674679
:gh:`152056`.)
675680

676-
module_name
677-
-----------
678-
679-
* TODO
680-
681-
682681

683682
Removed
684683
========
@@ -719,22 +718,27 @@ asyncio
719718
functools
720719
---------
721720

722-
* Calling the Python implementation of :func:`functools.reduce` with *function*
723-
or *sequence* as keyword arguments has been deprecated since Python 3.14.
721+
* Remove support for calling the Python implementation of
722+
:func:`functools.reduce` with *function* or *sequence* as keyword arguments,
723+
deprecated since Python 3.14. These parameters are now positional-only.
724+
(Contributed by Nikita Sobolev in :gh:`149537`.)
724725

725726
logging
726727
-------
727728

728-
* Support for custom logging handlers with the *strm* argument is deprecated
729-
and scheduled for removal in Python 3.16. Define handlers with the *stream*
730-
argument instead.
729+
* Remove support for custom logging handlers with the *strm* argument,
730+
deprecated since Python 3.14.
731+
Define handlers with the *stream* argument instead.
732+
(Contributed by Nikita Sobolev in :gh:`149598`.)
731733

732734
mimetypes
733735
---------
734736

735-
* Valid extensions start with a '.' or are empty for
736-
:meth:`mimetypes.MimeTypes.add_type`.
737-
Undotted extensions now raise a :exc:`ValueError`.
737+
* Remove support for undotted extensions in
738+
:meth:`mimetypes.MimeTypes.add_type`, deprecated since Python 3.14.
739+
Valid extensions must now start with a ``'.'`` or be empty;
740+
undotted extensions raise a :exc:`ValueError`.
741+
(Contributed by Nikita Sobolev in :gh:`149720`.)
738742

739743
shutil
740744
------
@@ -791,14 +795,14 @@ Deprecated
791795
New deprecations
792796
----------------
793797

794-
* :mod:`abc`
798+
* :mod:`abc`:
795799

796-
* Soft-deprecated since Python 3.3 :class:`abc.abstractclassmethod`,
797-
:class:`abc.abstractstaticmethod`, and :class:`abc.abstractproperty`
800+
* :class:`abc.abstractclassmethod`, :class:`abc.abstractstaticmethod`,
801+
and :class:`abc.abstractproperty`, soft-deprecated since Python 3.3,
798802
now raise a :exc:`DeprecationWarning`.
799-
These classes will be removed in Python 3.21, instead
803+
These classes will be removed in Python 3.21;
800804
use :func:`abc.abstractmethod` with :func:`classmethod`,
801-
:func:`staticmethod`, and :class:`property` respectively.
805+
:func:`staticmethod`, and :class:`property` respectively instead.
802806

803807
* :mod:`ast`:
804808

@@ -813,12 +817,12 @@ New deprecations
813817

814818
* :mod:`struct`:
815819

816-
* Soft-deprecated since Python 3.15, using ``'F'`` and ``'D'`` type codes are now
817-
deprecated. These codes will be removed in Python 3.21. Use instead
818-
two-letter forms ``'Zf'`` and ``'Zd'``.
820+
* The ``'F'`` and ``'D'`` type codes, soft-deprecated since Python 3.15,
821+
are now deprecated. These codes will be removed in Python 3.21.
822+
Use the two-letter forms ``'Zf'`` and ``'Zd'`` instead.
819823
(Contributed by Sergey B Kirpichev in :gh:`121249`.)
820824

821-
* :mod:`tempfile`
825+
* :mod:`tempfile`:
822826

823827
* The private ``tempfile._TemporaryFileWrapper`` name is deprecated
824828
and is slated for removal in Python 3.21.

Lib/asyncio/taskgroups.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ def create_task(self, coro, **kwargs):
239239
# the current task too early. gh-128550, gh-128588
240240
self._tasks.add(task)
241241
task.add_done_callback(self._on_task_done)
242+
# gh-155418: an eager task can cancel the group before joining _tasks
243+
if self._aborting and not task.done():
244+
task.cancel()
242245
try:
243246
return task
244247
finally:

Lib/enum.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -624,9 +624,13 @@ def __new__(metacls, cls, bases, classdict, *, boundary=None, _simple=False, **k
624624
'__invert__'
625625
):
626626
if name not in classdict:
627+
# check for mixin overrides before replacing
627628
enum_method = getattr(Flag, name)
628-
setattr(enum_class, name, enum_method)
629-
classdict[name] = enum_method
629+
found_method = getattr(enum_class, name)
630+
data_type_method = getattr(member_type, name, None)
631+
if found_method in (enum_method, data_type_method):
632+
setattr(enum_class, name, enum_method)
633+
classdict[name] = enum_method
630634
#
631635
# replace any other __new__ with our own (as long as Enum is not None,
632636
# anyway) -- again, this is to support pickle

Lib/http/cookiejar.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ def request_host(request):
627627
628628
"""
629629
url = request.get_full_url()
630-
host = urllib.parse.urlparse(url)[1]
630+
host = urllib.parse.urlparse(url).netloc
631631
if host == "":
632632
host = request.get_header("Host", "")
633633

Lib/test/libregrtest/refleak.py

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import sys
33
import warnings
4+
from array import array
45
from inspect import isabstract
56
from typing import Any
67
import linecache
@@ -100,24 +101,20 @@ def runtest_refleak(test_name, test_func,
100101
for obj in ByteString.__subclasses__() + [ByteString]: # type: ignore[attr-defined]
101102
abcs[obj] = _get_dump(obj)[0]
102103

103-
# bpo-31217: Integer pool to get a single integer object for the same
104-
# value. The pool is used to prevent false alarm when checking for memory
105-
# block leaks. Fill the pool with values in -1000..1000 which are the most
106-
# common (reference, memory block, file descriptor) differences.
107-
int_pool = {value: value for value in range(-1000, 1000)}
108-
def get_pooled_int(value):
109-
return int_pool.setdefault(value, value)
110-
111104
warmups = hunt_refleak.warmups
112105
runs = hunt_refleak.runs
113106
filename = hunt_refleak.filename
114107
repcount = warmups + runs
115108

116-
# Pre-allocate to ensure that the loop doesn't allocate anything new
109+
# Pre-allocate to ensure that the loop doesn't allocate anything new.
110+
# Store the deltas as raw values in arrays rather than as int objects in
111+
# lists: each unique delta stored as an object would live until the end of
112+
# the loop and show up in the following repetition's reference and memory
113+
# block deltas (gh-75400, gh-155981).
117114
rep_range = list(range(repcount))
118-
rc_deltas = [0] * repcount
119-
alloc_deltas = [0] * repcount
120-
fd_deltas = [0] * repcount
115+
rc_deltas = array('q', [0]) * repcount
116+
alloc_deltas = array('q', [0]) * repcount
117+
fd_deltas = array('q', [0]) * repcount
121118
getallocatedblocks = sys.getallocatedblocks
122119
gettotalrefcount = sys.gettotalrefcount
123120
getunicodeinternedsize = sys.getunicodeinternedsize
@@ -161,12 +158,11 @@ def get_pooled_int(value):
161158
rc_after = gettotalrefcount()
162159
fd_after = fd_count()
163160

164-
rc_deltas[i] = get_pooled_int(rc_after - rc_before)
165-
alloc_deltas[i] = get_pooled_int(alloc_after - alloc_before)
166-
fd_deltas[i] = get_pooled_int(fd_after - fd_before)
161+
rc_deltas[i] = rc_after - rc_before
162+
alloc_deltas[i] = alloc_after - alloc_before
163+
fd_deltas[i] = fd_after - fd_before
167164

168165
if not quiet:
169-
# use max, not sum, so total_leaks is one of the pooled ints
170166
total_leaks = max(rc_deltas[i], alloc_deltas[i], fd_deltas[i])
171167
if total_leaks <= 0:
172168
symbol = '.'
@@ -212,13 +208,13 @@ def check_fd_deltas(deltas):
212208
return any(deltas)
213209

214210
failed = False
215-
for deltas, item_name, checker in [
211+
for raw_deltas, item_name, checker in [
216212
(rc_deltas, 'references', check_rc_deltas),
217213
(alloc_deltas, 'memory blocks', check_rc_deltas),
218214
(fd_deltas, 'file descriptors', check_fd_deltas)
219215
]:
220-
# ignore warmup runs
221-
deltas = deltas[warmups:]
216+
# ignore warmup runs; convert to a list for reporting
217+
deltas = list(raw_deltas[warmups:])
222218
failing = checker(deltas)
223219
suspicious = any(deltas)
224220
if failing or suspicious:

Lib/test/ssl_servers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def translate_path(self, path):
6161
6262
"""
6363
# abandon query parameters
64-
path = urllib.parse.urlparse(path)[2]
64+
path = urllib.parse.urlparse(path).path
6565
path = os.path.normpath(urllib.parse.unquote(path))
6666
words = path.split('/')
6767
words = filter(None, words)

Lib/test/support/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,7 @@ def open_urlresource(url, *args, **kw):
868868

869869
check = kw.pop('check', None)
870870

871-
filename = urllib.parse.urlparse(url)[2].split('/')[-1] # '/': it's URL!
871+
filename = urllib.parse.urlparse(url).path.split('/')[-1] # '/': it's URL!
872872

873873
fn = os.path.join(TEST_DATA_DIR, filename)
874874

Lib/test/support/os_helper.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,10 @@ def _rmtree_inner(path):
434434
file=sys.__stderr__)
435435
mode = 0
436436
if stat.S_ISDIR(mode):
437-
_waitfor(_rmtree_inner, fullname, waitall=True)
437+
# Do not follow junctions, which os.lstat() reports
438+
# as directories.
439+
if not os.path.isjunction(fullname):
440+
_waitfor(_rmtree_inner, fullname, waitall=True)
438441
_force_run(fullname, os.rmdir, fullname)
439442
else:
440443
_force_run(fullname, os.unlink, fullname)

Lib/test/test_ast/test_ast.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,15 @@ def test_parse_invalid_ast(self):
162162
self.assertRaises(TypeError, ast.parse, ast.Constant(42),
163163
optimize=optval)
164164

165+
def test_parse_ast_func_type(self):
166+
# see gh-156689
167+
tree = ast.parse('(int, str) -> bool', mode='func_type')
168+
self.assertEqual(ast.dump(ast.parse(tree, mode='func_type')),
169+
ast.dump(tree))
170+
self.assertRaises(TypeError, ast.parse, ast.Constant(42),
171+
mode='func_type')
172+
self.assertRaises(TypeError, ast.parse, tree, mode='exec')
173+
165174
def test_optimization_levels__debug__(self):
166175
cases = [(-1, '__debug__'), (0, '__debug__'), (1, False), (2, False)]
167176
for (optval, expected) in cases:

0 commit comments

Comments
 (0)