Skip to content

Commit 28bec98

Browse files
Merge branch 'python:main' into main
2 parents 5d7a63e + 1259f16 commit 28bec98

99 files changed

Lines changed: 1120 additions & 413 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎Doc/builtins/exceptions.rst‎

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -396,10 +396,9 @@ The following exceptions are the exceptions that are usually raised.
396396

397397
.. attribute:: strerror
398398

399-
The corresponding error message, as provided by
400-
the operating system. It is formatted by the C
401-
functions :c:func:`!perror` under POSIX, and :c:func:`!FormatMessage`
402-
under Windows.
399+
The corresponding error message, as provided by the operating system.
400+
Under POSIX, it is obtained using the C functions :c:func:`!strerror`
401+
or :c:func:`!strerror_r`; under Windows, :c:func:`!FormatMessage` is used.
403402

404403
.. attribute:: filename
405404
filename2
@@ -567,11 +566,6 @@ The following exceptions are the exceptions that are usually raised.
567566
The column in the end line where the error occurred finishes. This is
568567
1-indexed: the first character in the line has an ``offset`` of 1.
569568

570-
For errors in f-string fields, the message is prefixed by "f-string: "
571-
and the offsets are offsets in a text constructed from the replacement
572-
expression. For example, compiling f'Bad {a b} field' results in this
573-
args attribute: ('f-string: ...', ('', 1, 2, '(a b)\n', 1, 5)).
574-
575569
.. versionchanged:: 3.10
576570
Added the :attr:`end_lineno` and :attr:`end_offset` attributes.
577571

‎Doc/builtins/functions.rst‎

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ are always available. They are listed here in alphabetical order.
772772
still access all builtins.
773773

774774
The *closure* argument specifies a closure--a tuple of cellvars.
775-
It's only valid when the *object* is a code object containing
775+
It's only valid when *source* is a code object containing
776776
:term:`free (closure) variables <closure variable>`.
777777
The length of the tuple must exactly match the length of the code object's
778778
:attr:`~codeobject.co_freevars` attribute.
@@ -2166,10 +2166,10 @@ are always available. They are listed here in alphabetical order.
21662166

21672167
When called directly within an ordinary method of a class, both arguments may
21682168
be omitted ("zero-argument :func:`!super`"). In this case, *type* will be the
2169-
enclosing class, and *obj* will be the first argument of the immediately
2170-
enclosing function (typically ``self``). (This means that zero-argument
2169+
enclosing class, and *object_or_type* will be the first argument of the
2170+
immediately enclosing function (typically ``self``). Zero-argument
21712171
:func:`!super` will not work as expected within nested functions, including
2172-
generator expressions, which implicitly create nested functions.)
2172+
generator expressions, which implicitly create nested functions.
21732173

21742174
There are two typical use cases for *super*. In a class hierarchy with
21752175
single inheritance, *super* can be used to refer to parent classes without
@@ -2428,10 +2428,9 @@ are always available. They are listed here in alphabetical order.
24282428
determine the package context of the :keyword:`import` statement.
24292429

24302430
*level* specifies whether to use absolute or relative imports. ``0`` (the
2431-
default) means only perform absolute imports. Positive values for
2432-
*level* indicate the number of parent directories to search relative to the
2433-
directory of the module calling :func:`__import__` (see :pep:`328` for the
2434-
details).
2431+
default) means only perform absolute imports. For relative imports,
2432+
``1`` refers to the current package, ``2`` to its parent package, and so on
2433+
(see :pep:`328` for details).
24352434

24362435
When the *name* variable is of the form ``package.module``, normally, the
24372436
top-level package (the name up till the first dot) is returned, *not* the

‎Doc/builtins/stdtypes.rst‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5667,7 +5667,7 @@ can be used interchangeably to index the same dictionary entry.
56675667

56685668
* Use a comma-separated list of ``key: value`` pairs within braces:
56695669
``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: 'jack', 4127: 'sjoerd'}``
5670-
* Use a dict comprehension: ``{}``, ``{x: x ** 2 for x in range(10)}``
5670+
* Use a dict comprehension: ``{x: x ** 2 for x in range(10)}``
56715671
* Use the type constructor: ``dict()``,
56725672
``dict([('foo', 100), ('bar', 200)])``, ``dict(foo=100, bar=200)``
56735673

@@ -5878,9 +5878,8 @@ can be used interchangeably to index the same dictionary entry.
58785878
Return a new view of the dictionary's values. See the
58795879
:ref:`documentation of view objects <dict-views>`.
58805880

5881-
An equality comparison between one ``dict.values()`` view and another
5882-
will always return ``False``. This also applies when comparing
5883-
``dict.values()`` to itself::
5881+
An equality comparison between two distinct ``dict.values()`` views
5882+
will always return ``False``, even for views of the same dictionary::
58845883

58855884
>>> d = {'a': 1}
58865885
>>> d.values() == d.values()

‎Doc/deprecations/pending-removal-in-3.20.rst‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,27 @@ Pending removal in Python 3.20
3939

4040
(Contributed by Hugo van Kemenade and Stan Ulbrych in :gh:`76007`.)
4141

42+
* The ``__author__``, ``__credits__``, ``__copyright__`` and ``__date__``
43+
attributes have been deprecated in these standard library modules and will
44+
be removed in Python 3.20. Attribution is preserved in the source code
45+
and the version control history.
46+
47+
- :mod:`bz2`
48+
- :mod:`concurrent.futures`
49+
- :mod:`inspect`
50+
- :mod:`io`
51+
- :mod:`json`
52+
- :mod:`logging`
53+
- :mod:`optparse`
54+
- :mod:`platform`
55+
- :mod:`pydoc`
56+
- :mod:`tarfile`
57+
- :mod:`tkinter.ttk`
58+
- :mod:`tokenize`
59+
- :mod:`uuid`
60+
61+
(Contributed by Stan Ulbrych in :gh:`159240`.)
62+
4263
* Deprecations defined by :pep:`829`:
4364

4465
* Warnings are produced for ``import`` lines found in :file:`{name}.pth`

‎Doc/library/inspect.rst‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,12 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
284284
| | | ``AGEN_SUSPENDED``, or |
285285
| | | ``AGEN_CLOSED`` |
286286
+-----------------+-------------------+---------------------------+
287+
| async generator | aga_gen | async generator driven by |
288+
| awaitable | | the awaitable returned |
289+
| | | from ``asend()``, |
290+
| | | ``athrow()``, or |
291+
| | | ``aclose()`` |
292+
+-----------------+-------------------+---------------------------+
287293
| coroutine | __name__ | name |
288294
+-----------------+-------------------+---------------------------+
289295
| | __qualname__ | qualified name |
@@ -360,6 +366,11 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
360366
Add ``gi_state`` attribute to generators, ``cr_state`` attribute to
361367
coroutines, and ``ag_state`` attribute to async generators.
362368

369+
.. versionchanged:: 3.16
370+
371+
Add ``aga_gen`` attribute to the awaitables returned by the ``asend()``,
372+
``athrow()`` and ``aclose()`` methods of async generators.
373+
363374
.. function:: getmembers(object[, predicate])
364375

365376
Return all the members of an object in a list of ``(name, value)``

‎Doc/library/shutil.rst‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules.
753753
unpacked. If not provided, the current working directory is used.
754754

755755
*format* is the archive format: one of "zip", "tar", "gztar", "bztar",
756-
"xztar", or "zstdtar". Or any other format registered with
756+
"xztar", "zstdtar", or "whl". Or any other format registered with
757757
:func:`register_unpack_format`. If not provided, :func:`unpack_archive`
758758
will use the archive file name extension and see if an unpacker was
759759
registered for that extension. In case none is found,
@@ -786,6 +786,9 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules.
786786
.. versionchanged:: 3.12
787787
Added the *filter* argument.
788788

789+
.. versionchanged:: next
790+
Added the "whl" format.
791+
789792
.. function:: register_unpack_format(name, extensions, function[, extra_args[, description]])
790793

791794
Registers an unpack format. *name* is the name of the format and
@@ -827,10 +830,16 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules.
827830
- *xztar*: xz'ed tar-file (if the :mod:`lzma` module is available).
828831
- *zstdtar*: Zstandard compressed tar-file (if the :mod:`compression.zstd`
829832
module is available).
833+
- *whl*: `wheel file <https://packaging.python.org/en/latest/discussions/package-formats/#what-is-a-wheel>`__
834+
(unpacking compressed files works only if the corresponding module is
835+
available).
830836

831837
You can register new formats or provide your own unpacker for any existing
832838
formats, by using :func:`register_unpack_format`.
833839

840+
.. versionchanged:: next
841+
Added the *whl* format.
842+
834843

835844
.. _shutil-archiving-example:
836845

‎Doc/library/test.rst‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,14 @@ The :mod:`!test.support` module defines the following functions:
10871087

10881088
.. versionadded:: 3.6
10891089

1090+
1091+
.. function:: check_deprecated_module_attributes(test_case, module, *names, remove)
1092+
1093+
Assert that accessing each attribute in *names* on *module* emits a
1094+
:exc:`DeprecationWarning` naming the attribute and the Python version
1095+
*remove*, given as a ``(major, minor)`` tuple, in which it will be removed.
1096+
1097+
10901098
.. function:: skip_if_broken_multiprocessing_synchronize()
10911099

10921100
Skip tests if the :mod:`!multiprocessing.synchronize` module is missing, if

‎Doc/whatsnew/3.16.rst‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,9 @@ shutil
681681
:func:`shutil.copystat`, e.g. when copying a read-only tree.
682682
(Contributed by Łukasz Langa in :gh:`89721`.)
683683

684+
* :func:`shutil.unpack_archive` can now unpack wheel files using the ``whl`` format.
685+
(Contributed by Emma Harper Smith and Stan Ulbrych in :gh:`84027`.)
686+
684687

685688
socket
686689
------
@@ -1189,6 +1192,29 @@ New deprecations
11891192
3.9, now issues a deprecation warning on use. This property is slated for
11901193
removal in 3.21. Use ``ast.Tuple.elts`` instead.
11911194

1195+
* ``__author__``, ``__credits__``, ``__copyright__`` and ``__date__``:
1196+
1197+
* The ``__author__``, ``__credits__``, ``__copyright__`` and ``__date__``
1198+
attributes have been deprecated in these standard library modules and will
1199+
be removed in Python 3.20. Attribution is preserved in the source code
1200+
and the version control history.
1201+
1202+
- :mod:`bz2`
1203+
- :mod:`concurrent.futures`
1204+
- :mod:`inspect`
1205+
- :mod:`io`
1206+
- :mod:`json`
1207+
- :mod:`logging`
1208+
- :mod:`optparse`
1209+
- :mod:`platform`
1210+
- :mod:`pydoc`
1211+
- :mod:`tarfile`
1212+
- :mod:`tkinter.ttk`
1213+
- :mod:`tokenize`
1214+
- :mod:`uuid`
1215+
1216+
(Contributed by Stan Ulbrych in :gh:`159240`.)
1217+
11921218
* :mod:`functools`:
11931219

11941220
* Using a return annotation to infer the dispatch type for

‎Lib/asyncio/graph.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ def _build_graph_for_future(
7070
if coro.gi_frame is not None:
7171
st.append(FrameCallGraphEntry(coro.gi_frame))
7272
coro = coro.gi_yieldfrom
73+
elif hasattr(coro, 'aga_gen'):
74+
# An asend()/athrow() awaitable: step over it to its generator
75+
coro = coro.aga_gen
7376
else:
7477
break
7578

‎Lib/asyncio/streams.py‎

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,16 @@ async def _wait_for_data(self, func_name):
553553
finally:
554554
self._waiter = None
555555

556+
def _readuntil_fast(self, separator):
557+
# Fast linear search inside already buffered data.
558+
if type(separator) is bytes and separator and self._exception is None:
559+
isep = self._buffer.find(separator)
560+
if 0 <= isep <= self._limit:
561+
chunk = self._buffer.take_bytes(isep + len(separator))
562+
self._maybe_resume_transport()
563+
return chunk
564+
return None
565+
556566
async def readline(self):
557567
r"""Read chunk of data from the stream until newline (b'\n') is found.
558568
@@ -570,19 +580,18 @@ async def readline(self):
570580
needed.
571581
"""
572582
sep = b'\n'
573-
seplen = len(sep)
583+
if (line := self._readuntil_fast(sep)) is not None:
584+
return line
574585
try:
575-
line = await self.readuntil(sep)
586+
return await self.readuntil(sep)
576587
except exceptions.IncompleteReadError as e:
577588
return e.partial
578589
except exceptions.LimitOverrunError as e:
579-
if self._buffer.startswith(sep, e.consumed):
580-
del self._buffer[:e.consumed + seplen]
581-
else:
582-
self._buffer.clear()
590+
# e.consumed is the newline's index, or len(self._buffer) if
591+
# there is none: drop the line, or everything.
592+
del self._buffer[:e.consumed + 1]
583593
self._maybe_resume_transport()
584594
raise ValueError(e.args[0])
585-
return line
586595

587596
async def readuntil(self, separator=b'\n'):
588597
"""Read data from the stream until ``separator`` is found.
@@ -610,17 +619,18 @@ async def readuntil(self, separator=b'\n'):
610619
the shortest possible separator is considered to be the one that
611620
matched.
612621
"""
622+
if (chunk := self._readuntil_fast(separator)) is not None:
623+
return chunk
613624
if isinstance(separator, tuple):
614625
# Makes sure shortest matches wins
615626
separator = sorted(separator, key=len)
616627
else:
617628
separator = [separator]
618629
if not separator:
619630
raise ValueError('Separator should contain at least one element')
620-
min_seplen = len(separator[0])
621-
max_seplen = len(separator[-1])
622-
if min_seplen == 0:
631+
if len(separator[0]) == 0:
623632
raise ValueError('Separator should be at least one-byte string')
633+
max_seplen = len(separator[-1])
624634

625635
if self._exception is not None:
626636
raise self._exception
@@ -650,32 +660,23 @@ async def readuntil(self, separator=b'\n'):
650660
# or an EOF has happened.
651661
while True:
652662
buflen = len(self._buffer)
653-
654-
# Check if we now have enough data in the buffer for shortest
655-
# separator to fit.
656-
if buflen - offset >= min_seplen:
657-
match_start = None
658-
match_end = None
659-
for sep in separator:
660-
isep = self._buffer.find(sep, offset)
661-
662-
if isep != -1:
663-
# `separator` is in the buffer. `match_start` and
664-
# `match_end` will be used later to retrieve the
665-
# data.
666-
end = isep + len(sep)
667-
if match_end is None or end < match_end:
668-
match_end = end
669-
match_start = isep
670-
if match_end is not None:
671-
break
672-
673-
# see upper comment for explanation.
674-
offset = max(0, buflen + 1 - max_seplen)
675-
if offset > self._limit:
676-
raise exceptions.LimitOverrunError(
677-
'Separator is not found, and chunk exceed the limit',
678-
offset)
663+
match_end = buflen + 1
664+
for sep in separator:
665+
# Only a match that ends before the best one so far wins,
666+
# so don't search past it.
667+
isep = self._buffer.find(sep, offset, match_end - 1)
668+
if isep != -1:
669+
match_start = isep
670+
match_end = isep + len(sep)
671+
if match_end <= buflen:
672+
break
673+
674+
# see upper comment for explanation.
675+
offset = max(0, buflen + 1 - max_seplen)
676+
if offset > self._limit:
677+
raise exceptions.LimitOverrunError(
678+
'Separator is not found, and chunk exceed the limit',
679+
offset)
679680

680681
# Complete message (with full separator) may be present in buffer
681682
# even when EOF flag is set. This may happen when the last chunk

0 commit comments

Comments
 (0)