Skip to content

Commit 9aeb6da

Browse files
committed
Merge branch 'main' into safer-tuples
2 parents 6a1f806 + 02f1385 commit 9aeb6da

File tree

242 files changed

+6314
-1840
lines changed

Some content is hidden

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

242 files changed

+6314
-1840
lines changed

Doc/c-api/unicode.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ APIs:
523523
- Get the fully qualified name of an object type;
524524
call :c:func:`PyType_GetFullyQualifiedName`.
525525
526-
* - ``T#``
526+
* - ``#T``
527527
- :c:expr:`PyObject*`
528528
- Similar to ``T`` format, but use a colon (``:``) as separator between
529529
the module name and the qualified name.
@@ -533,7 +533,7 @@ APIs:
533533
- Get the fully qualified name of a type;
534534
call :c:func:`PyType_GetFullyQualifiedName`.
535535
536-
* - ``N#``
536+
* - ``#N``
537537
- :c:expr:`PyTypeObject*`
538538
- Similar to ``N`` format, but use a colon (``:``) as separator between
539539
the module name and the qualified name.
@@ -574,7 +574,7 @@ APIs:
574574
copied as-is to the result string, and any extra arguments discarded.
575575
576576
.. versionchanged:: 3.13
577-
Support for ``%T``, ``%T#``, ``%N`` and ``%N#`` formats added.
577+
Support for ``%T``, ``%#T``, ``%N`` and ``%#N`` formats added.
578578
579579
580580
.. c:function:: PyObject* PyUnicode_FromFormatV(const char *format, va_list vargs)

Doc/library/asyncio-queue.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,10 @@ Queue
106106
raise once the queue is empty. Set *immediate* to true to make
107107
:meth:`~Queue.get` raise immediately instead.
108108

109-
All blocked callers of :meth:`~Queue.put` will be unblocked. If
110-
*immediate* is true, also unblock callers of :meth:`~Queue.get`
111-
and :meth:`~Queue.join`.
109+
All blocked callers of :meth:`~Queue.put` and :meth:`~Queue.get`
110+
will be unblocked. If *immediate* is true, a task will be marked
111+
as done for each remaining item in the queue, which may unblock
112+
callers of :meth:`~Queue.join`.
112113

113114
.. versionadded:: 3.13
114115

Doc/library/asyncio-stream.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,19 @@ StreamReader
260260
buffer is reset. The :attr:`IncompleteReadError.partial` attribute
261261
may contain a portion of the separator.
262262

263+
The *separator* may also be an :term:`iterable` of separators. In this
264+
case the return value will be the shortest possible that has any
265+
separator as the suffix. For the purposes of :exc:`LimitOverrunError`,
266+
the shortest possible separator is considered to be the one that
267+
matched.
268+
263269
.. versionadded:: 3.5.2
264270

271+
.. versionchanged:: 3.13
272+
273+
The *separator* parameter may now be an :term:`iterable` of
274+
separators.
275+
265276
.. method:: at_eof()
266277

267278
Return ``True`` if the buffer is empty and :meth:`feed_eof`

Doc/library/asyncio-task.rst

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,27 @@ is also included in the exception group.
392392
The same special case is made for
393393
:exc:`KeyboardInterrupt` and :exc:`SystemExit` as in the previous paragraph.
394394

395+
Task groups are careful not to mix up the internal cancellation used to
396+
"wake up" their :meth:`~object.__aexit__` with cancellation requests
397+
for the task in which they are running made by other parties.
398+
In particular, when one task group is syntactically nested in another,
399+
and both experience an exception in one of their child tasks simultaneously,
400+
the inner task group will process its exceptions, and then the outer task group
401+
will receive another cancellation and process its own exceptions.
402+
403+
In the case where a task group is cancelled externally and also must
404+
raise an :exc:`ExceptionGroup`, it will call the parent task's
405+
:meth:`~asyncio.Task.cancel` method. This ensures that a
406+
:exc:`asyncio.CancelledError` will be raised at the next
407+
:keyword:`await`, so the cancellation is not lost.
408+
409+
Task groups preserve the cancellation count
410+
reported by :meth:`asyncio.Task.cancelling`.
411+
412+
.. versionchanged:: 3.13
413+
414+
Improved handling of simultaneous internal and external cancellations
415+
and correct preservation of cancellation counts.
395416

396417
Sleeping
397418
========
@@ -1369,6 +1390,15 @@ Task Object
13691390
catching :exc:`CancelledError`, it needs to call this method to remove
13701391
the cancellation state.
13711392

1393+
When this method decrements the cancellation count to zero,
1394+
the method checks if a previous :meth:`cancel` call had arranged
1395+
for :exc:`CancelledError` to be thrown into the task.
1396+
If it hasn't been thrown yet, that arrangement will be
1397+
rescinded (by resetting the internal ``_must_cancel`` flag).
1398+
1399+
.. versionchanged:: 3.13
1400+
Changed to rescind pending cancellation requests upon reaching zero.
1401+
13721402
.. method:: cancelling()
13731403

13741404
Return the number of pending cancellation requests to this Task, i.e.,

Doc/library/os.path.rst

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ the :mod:`glob` module.)
145145

146146
.. function:: lexists(path)
147147

148-
Return ``True`` if *path* refers to an existing path. Returns ``True`` for
148+
Return ``True`` if *path* refers to an existing path, including
149149
broken symbolic links. Equivalent to :func:`exists` on platforms lacking
150150
:func:`os.lstat`.
151151

@@ -409,9 +409,8 @@ the :mod:`glob` module.)
409409
style names such as ``C:\\PROGRA~1`` to ``C:\\Program Files``.
410410

411411
If a path doesn't exist or a symlink loop is encountered, and *strict* is
412-
``True``, :exc:`OSError` is raised. If *strict* is ``False``, the path is
413-
resolved as far as possible and any remainder is appended without checking
414-
whether it exists.
412+
``True``, :exc:`OSError` is raised. If *strict* is ``False`` these errors
413+
are ignored, and so the result might be missing or otherwise inaccessible.
415414

416415
.. note::
417416
This function emulates the operating system's procedure for making a path

Doc/library/queue.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,10 @@ them down.
245245
queue is empty. Set *immediate* to true to make :meth:`~Queue.get` raise
246246
immediately instead.
247247

248-
All blocked callers of :meth:`~Queue.put` will be unblocked. If *immediate*
249-
is true, also unblock callers of :meth:`~Queue.get` and :meth:`~Queue.join`.
248+
All blocked callers of :meth:`~Queue.put` and :meth:`~Queue.get` will be
249+
unblocked. If *immediate* is true, a task will be marked as done for each
250+
remaining item in the queue, which may unblock callers of
251+
:meth:`~Queue.join`.
250252

251253
.. versionadded:: 3.13
252254

Doc/library/sqlite3.rst

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
src = sqlite3.connect(":memory:", isolation_level=None)
1717
dst = sqlite3.connect("tutorial.db", isolation_level=None)
1818
src.backup(dst)
19+
src.close()
20+
dst.close()
1921
del src, dst
2022

2123
.. _sqlite3-intro:
@@ -220,6 +222,7 @@ creating a new cursor, then querying the database:
220222
>>> title, year = res.fetchone()
221223
>>> print(f'The highest scoring Monty Python movie is {title!r}, released in {year}')
222224
The highest scoring Monty Python movie is 'Monty Python and the Holy Grail', released in 1975
225+
>>> new_con.close()
223226

224227
You've now created an SQLite database using the :mod:`!sqlite3` module,
225228
inserted data and retrieved values from it in multiple ways.
@@ -394,29 +397,11 @@ Module functions
394397
will get tracebacks from callbacks on :data:`sys.stderr`. Use ``False``
395398
to disable the feature again.
396399

397-
Register an :func:`unraisable hook handler <sys.unraisablehook>` for an
398-
improved debug experience:
399-
400-
.. testsetup:: sqlite3.trace
401-
402-
import sqlite3
400+
.. note::
403401

404-
.. doctest:: sqlite3.trace
405-
406-
>>> sqlite3.enable_callback_tracebacks(True)
407-
>>> con = sqlite3.connect(":memory:")
408-
>>> def evil_trace(stmt):
409-
... 5/0
410-
...
411-
>>> con.set_trace_callback(evil_trace)
412-
>>> def debug(unraisable):
413-
... print(f"{unraisable.exc_value!r} in callback {unraisable.object.__name__}")
414-
... print(f"Error message: {unraisable.err_msg}")
415-
>>> import sys
416-
>>> sys.unraisablehook = debug
417-
>>> cur = con.execute("SELECT 1")
418-
ZeroDivisionError('division by zero') in callback evil_trace
419-
Error message: None
402+
Errors in user-defined function callbacks are logged as unraisable exceptions.
403+
Use an :func:`unraisable hook handler <sys.unraisablehook>` for
404+
introspection of the failed callback.
420405

421406
.. function:: register_adapter(type, adapter, /)
422407

@@ -762,6 +747,7 @@ Connection objects
762747
>>> for row in con.execute("SELECT md5(?)", (b"foo",)):
763748
... print(row)
764749
('acbd18db4cc2f85cedef654fccc4a4d8',)
750+
>>> con.close()
765751

766752
.. versionchanged:: 3.13
767753

@@ -908,6 +894,7 @@ Connection objects
908894
FROM test ORDER BY x
909895
""")
910896
print(cur.fetchall())
897+
con.close()
911898

912899
.. testoutput::
913900
:hide:
@@ -1068,13 +1055,10 @@ Connection objects
10681055
.. versionchanged:: 3.10
10691056
Added the ``sqlite3.enable_load_extension`` auditing event.
10701057

1071-
.. testsetup:: sqlite3.loadext
1072-
1073-
import sqlite3
1074-
con = sqlite3.connect(":memory:")
1058+
.. We cannot doctest the load extension API, since there is no convenient
1059+
way to skip it.
10751060
1076-
.. testcode:: sqlite3.loadext
1077-
:skipif: True # not testable at the moment
1061+
.. code-block::
10781062
10791063
con.enable_load_extension(True)
10801064
@@ -1098,14 +1082,6 @@ Connection objects
10981082
for row in con.execute("SELECT rowid, name, ingredients FROM recipe WHERE name MATCH 'pie'"):
10991083
print(row)
11001084
1101-
con.close()
1102-
1103-
.. testoutput:: sqlite3.loadext
1104-
:hide:
1105-
1106-
(2, 'broccoli pie', 'broccoli cheese onions flour')
1107-
(3, 'pumpkin pie', 'pumpkin sugar flour butter')
1108-
11091085
.. method:: load_extension(path, /, *, entrypoint=None)
11101086

11111087
Load an SQLite extension from a shared library.
@@ -1230,6 +1206,8 @@ Connection objects
12301206
src = sqlite3.connect('example.db')
12311207
dst = sqlite3.connect(':memory:')
12321208
src.backup(dst)
1209+
dst.close()
1210+
src.close()
12331211

12341212
.. versionadded:: 3.7
12351213

@@ -1296,6 +1274,10 @@ Connection objects
12961274
>>> con.getlimit(sqlite3.SQLITE_LIMIT_ATTACHED)
12971275
1
12981276

1277+
.. testcleanup:: sqlite3.limits
1278+
1279+
con.close()
1280+
12991281
.. versionadded:: 3.11
13001282

13011283
.. _SQLite limit category: https://www.sqlite.org/c3ref/c_limit_attached.html
@@ -1577,6 +1559,10 @@ Cursor objects
15771559
# cur is an sqlite3.Cursor object
15781560
cur.executemany("INSERT INTO data VALUES(?)", rows)
15791561

1562+
.. testcleanup:: sqlite3.cursor
1563+
1564+
con.close()
1565+
15801566
.. note::
15811567

15821568
Any resulting rows are discarded,
@@ -1682,6 +1668,7 @@ Cursor objects
16821668
>>> cur = con.cursor()
16831669
>>> cur.connection == con
16841670
True
1671+
>>> con.close()
16851672

16861673
.. attribute:: description
16871674

@@ -1802,6 +1789,7 @@ Blob objects
18021789
greeting = blob.read()
18031790

18041791
print(greeting) # outputs "b'Hello, world!'"
1792+
con.close()
18051793

18061794
.. testoutput::
18071795
:hide:
@@ -2114,6 +2102,7 @@ Here's an example of both styles:
21142102
params = (1972,)
21152103
cur.execute("SELECT * FROM lang WHERE first_appeared = ?", params)
21162104
print(cur.fetchall())
2105+
con.close()
21172106

21182107
.. testoutput::
21192108
:hide:
@@ -2172,6 +2161,7 @@ The object passed to *protocol* will be of type :class:`PrepareProtocol`.
21722161

21732162
cur.execute("SELECT ?", (Point(4.0, -3.2),))
21742163
print(cur.fetchone()[0])
2164+
con.close()
21752165

21762166
.. testoutput::
21772167
:hide:
@@ -2202,6 +2192,7 @@ This function can then be registered using :func:`register_adapter`.
22022192

22032193
cur.execute("SELECT ?", (Point(1.0, 2.5),))
22042194
print(cur.fetchone()[0])
2195+
con.close()
22052196

22062197
.. testoutput::
22072198
:hide:
@@ -2286,6 +2277,8 @@ The following example illustrates the implicit and explicit approaches:
22862277
cur.execute("INSERT INTO test(p) VALUES(?)", (p,))
22872278
cur.execute('SELECT p AS "p [point]" FROM test')
22882279
print("with column names:", cur.fetchone()[0])
2280+
cur.close()
2281+
con.close()
22892282

22902283
.. testoutput::
22912284
:hide:
@@ -2492,6 +2485,8 @@ Some useful URI tricks include:
24922485
res = con2.execute("SELECT data FROM shared")
24932486
assert res.fetchone() == (28,)
24942487

2488+
con1.close()
2489+
con2.close()
24952490

24962491
More information about this feature, including a list of parameters,
24972492
can be found in the `SQLite URI documentation`_.
@@ -2538,6 +2533,7 @@ Queries now return :class:`!Row` objects:
25382533
'Earth'
25392534
>>> row["RADIUS"] # Column names are case-insensitive.
25402535
6378
2536+
>>> con.close()
25412537

25422538
.. note::
25432539

@@ -2564,6 +2560,7 @@ Using it, queries now return a :class:`!dict` instead of a :class:`!tuple`:
25642560
>>> for row in con.execute("SELECT 1 AS a, 2 AS b"):
25652561
... print(row)
25662562
{'a': 1, 'b': 2}
2563+
>>> con.close()
25672564

25682565
The following row factory returns a :term:`named tuple`:
25692566

@@ -2590,6 +2587,7 @@ The following row factory returns a :term:`named tuple`:
25902587
1
25912588
>>> row.b # Attribute access.
25922589
2
2590+
>>> con.close()
25932591

25942592
With some adjustments, the above recipe can be adapted to use a
25952593
:class:`~dataclasses.dataclass`, or any other custom class,

0 commit comments

Comments
 (0)