Skip to content

Commit f7acefc

Browse files
authored
Merge branch 'main' into gh-159091-pyfunction-getannotations
2 parents b06dedf + 627eabf commit f7acefc

118 files changed

Lines changed: 3564 additions & 1317 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.

‎.github/ISSUE_TEMPLATE/bug.yml‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ body:
3434
label: "CPython versions tested on:"
3535
multiple: true
3636
options:
37-
- "3.10"
3837
- "3.11"
3938
- "3.12"
4039
- "3.13"

‎.github/ISSUE_TEMPLATE/crash.yml‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ body:
2828
label: "CPython versions tested on:"
2929
multiple: true
3030
options:
31-
- "3.10"
3231
- "3.11"
3332
- "3.12"
3433
- "3.13"

‎.github/dependabot.yml‎

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,6 @@ updates:
9292
cooldown:
9393
default-days: 14
9494

95-
- package-ecosystem: "github-actions"
96-
target-branch: "3.10"
97-
directory: "/"
98-
schedule:
99-
interval: "quarterly"
100-
labels: ["skip issue", "skip news"]
101-
groups:
102-
actions:
103-
patterns: ["*"]
104-
cooldown:
105-
default-days: 14
106-
10795
# Only bump bugfix branches for pip. Remove
10896
# the entry when branch goes security-only.
10997
- package-ecosystem: "pip"
@@ -129,15 +117,3 @@ updates:
129117
patterns: ["*"]
130118
cooldown:
131119
default-days: 14
132-
133-
- package-ecosystem: "pip"
134-
target-branch: "3.13"
135-
directory: "/Tools/"
136-
schedule:
137-
interval: "quarterly"
138-
labels: ["skip issue", "skip news"]
139-
groups:
140-
pip:
141-
patterns: ["*"]
142-
cooldown:
143-
default-days: 14

‎.github/workflows/mypy.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ jobs:
6969
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
7070
with:
7171
persist-credentials: false
72-
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
72+
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
7373
with:
7474
python-version: "3.15"
7575
activate-environment: true

‎.github/workflows/reusable-cifuzz.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jobs:
4343
path: ./out/artifacts
4444
- name: Upload SARIF
4545
if: always() && steps.build.outcome == 'success'
46-
uses: github/codeql-action/upload-sarif@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0
46+
uses: github/codeql-action/upload-sarif@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2
4747
with:
4848
sarif_file: cifuzz-sarif/results.sarif
4949
checkout_path: cifuzz-sarif

‎Doc/c-api/bytes.rst‎

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,3 +464,112 @@ Low-level API
464464
return NULL;
465465
}
466466
return (char*)PyBytesWriter_GetData(writer) + pos;
467+
468+
469+
Example creating the string ``b'abc'``
470+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
471+
472+
Example creating the bytes string ``b"abc"``, with a fixed size of 3 bytes::
473+
474+
PyObject* create_abc(void)
475+
{
476+
PyBytesWriter *writer = PyBytesWriter_Create(3);
477+
if (writer == NULL) {
478+
return NULL;
479+
}
480+
481+
char *str = PyBytesWriter_GetData(writer);
482+
memcpy(str, "abc", 3);
483+
return PyBytesWriter_Finish(writer);
484+
}
485+
486+
Variant using a pointer to compute the final size::
487+
488+
PyObject* create_abc_ptr(void)
489+
{
490+
PyBytesWriter *writer = PyBytesWriter_Create(3);
491+
if (writer == NULL) {
492+
return NULL;
493+
}
494+
495+
char *str = PyBytesWriter_GetData(writer);
496+
memcpy(str, "abc", 3);
497+
str += 1;
498+
return PyBytesWriter_FinishWithPointer(writer, str);
499+
}
500+
501+
502+
Update ``PyBytes_FromStringAndSize()`` code
503+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
504+
505+
Example of code using the soft deprecated
506+
``PyBytes_FromStringAndSize(NULL, size)`` API::
507+
508+
int copy_bytes(char *dest, const char *src, Py_ssize_t num_bytes)
509+
{
510+
...
511+
}
512+
513+
PyObject* create_string(const char *start, Py_ssize_t num_bytes)
514+
{
515+
PyObject *result = PyBytes_FromStringAndSize(NULL, num_bytes);
516+
if (result == NULL) {
517+
return NULL;
518+
}
519+
if (copy_bytes(PyBytes_AS_STRING(result), start, num_bytes) < 0) {
520+
Py_CLEAR(result);
521+
}
522+
return result;
523+
}
524+
525+
It can now be updated to::
526+
527+
PyObject* create_string(const char *start, Py_ssize_t num_bytes)
528+
{
529+
PyBytesWriter *writer = PyBytesWriter_Create(num_bytes);
530+
if (writer == NULL) {
531+
return NULL;
532+
}
533+
if (copy_bytes(PyBytesWriter_GetData(writer), start, num_bytes) < 0) {
534+
PyBytesWriter_Discard(writer);
535+
return NULL;
536+
}
537+
return PyBytesWriter_Finish(writer);
538+
}
539+
540+
541+
Update ``_PyBytes_Resize()`` code
542+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
543+
544+
Example of code using the soft deprecated ``_PyBytes_Resize()`` API::
545+
546+
void create_string(Py_ssize_t size)
547+
{
548+
PyObject *bytes = PyBytes_FromStringAndSize(NULL, size);
549+
if (bytes == NULL) {
550+
return NULL;
551+
}
552+
char *str = PyBytes_AS_STRING(bytes);
553+
554+
// ... write data into str ...
555+
556+
if (_PyBytes_Resize(&bytes, (str - PyBytes_AS_STRING(bytes)))) {
557+
return NULL;
558+
}
559+
return bytes;
560+
}
561+
562+
It can now be updated to::
563+
564+
void create_string(Py_ssize_t size)
565+
{
566+
PyBytesWriter *writer = PyBytesWriter_Create(size);
567+
if (writer == NULL) {
568+
return NULL;
569+
}
570+
char *str = PyBytesWriter_GetData(writer);
571+
572+
// ... write data into str ...
573+
574+
return PyBytesWriter_FinishWithPointer(writer, str);
575+
}

‎Doc/c-api/marshal.rst‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,40 @@ and :exc:`MemoryError` if memory allocation fails.
4343
This function can fail, in which case it sets the error indicator.
4444
Use :c:func:`PyErr_Occurred` to check for that.
4545
46+
.. note::
47+
48+
In Python 3.15 and earlier, this function does not set the error
49+
indicator if writing to *file* fails.
50+
The same caveat applies as for :c:func:`PyMarshal_WriteObjectToFile`.
51+
4652
.. c:function:: void PyMarshal_WriteObjectToFile(PyObject *value, FILE *file, int version)
4753
4854
Marshal a Python object, *value*, to *file*.
4955
*version* indicates the file format.
5056
57+
The marshalled representation of *value* is built in memory
58+
and then written to *file*.
59+
Nothing is written if *value* cannot be marshalled.
60+
5161
This function can fail, in which case it sets the error indicator.
5262
Use :c:func:`PyErr_Occurred` to check for that.
5363
64+
.. note::
65+
66+
In Python 3.15 and earlier, this function can write only part of the
67+
data to *file* and return without setting the error indicator, for
68+
example if *value* contains an object which cannot be marshalled or
69+
if writing to *file* fails (see :gh:`155907`).
70+
Code which has to support these versions cannot rely on
71+
:c:func:`PyErr_Occurred` alone to know that all the data was written.
72+
It can use :c:func:`PyMarshal_WriteObjectToString` and write the
73+
result itself, or validate what was written.
74+
75+
.. versionchanged:: next
76+
Previously, the data was written to *file* as it was produced,
77+
using a buffer of constant size,
78+
and incomplete data was written if *value* could not be marshalled.
79+
5480
.. c:function:: PyObject* PyMarshal_WriteObjectToString(PyObject *value, int version)
5581
5682
Return a bytes object containing the marshalled representation of *value*.

‎Doc/library/concurrent.interpreters.rst‎

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -224,11 +224,15 @@ This module defines the following functions:
224224
Initialize a new (idle) Python interpreter
225225
and return a :class:`Interpreter` object for it.
226226

227-
.. function:: create_queue()
227+
.. function:: create_queue(maxsize=0)
228228

229229
Initialize a new cross-interpreter queue and return a :class:`Queue`
230230
object for it.
231231

232+
*maxsize* is an integer that sets the upperbound limit on the number of
233+
items that can be placed in the queue. Insertion will be blocked once this
234+
size has been reached, until queue items are consumed. If *maxsize* is
235+
less than or equal to zero, the queue size is infinite.
232236

233237
Interpreter objects
234238
^^^^^^^^^^^^^^^^^^^
@@ -268,7 +272,7 @@ Interpreter objects
268272
Some objects are actually shared and some are copied efficiently,
269273
but most are copied via :mod:`pickle`. See :ref:`interp-object-sharing`.
270274

271-
.. method:: exec(code, /, dedent=True)
275+
.. method:: exec(code, /)
272276

273277
Run the given source code in the interpreter (in the current thread).
274278

@@ -319,7 +323,9 @@ Communicating Between Interpreters
319323
.. class:: Queue(id)
320324

321325
A wrapper around a low-level, cross-interpreter queue, which
322-
implements the :class:`queue.Queue` interface. The underlying queue
326+
implements all the methods of :class:`queue.Queue` except for
327+
:meth:`~queue.Queue.task_done`, :meth:`~queue.Queue.join`
328+
and :meth:`~queue.Queue.shutdown`. The underlying queue
323329
can only be created through :func:`create_queue`.
324330

325331
Some objects are actually shared and some are copied efficiently,
@@ -331,17 +337,59 @@ Communicating Between Interpreters
331337

332338
The queue's ID.
333339

340+
.. method:: qsize()
334341

335-
.. exception:: QueueEmptyError
342+
Return the number of items in the queue.
343+
344+
.. method:: empty()
345+
346+
Return ``True`` if the queue is empty, ``False`` otherwise.
347+
348+
.. method:: full()
349+
350+
Return ``True`` if the queue is full, ``False`` otherwise.
351+
352+
.. method:: put(obj, block=True, timeout=None)
353+
354+
Put *obj* into the queue. If optional args *block* is true and
355+
*timeout* is ``None`` (the default), block if necessary until a free
356+
slot is available. If *timeout* is a positive number, it blocks at
357+
most *timeout* seconds and raises the :exc:`QueueFull` exception if
358+
no free slot was available within that time. Otherwise (*block* is
359+
false), put an object on the queue if a free slot is immediately
360+
available, else raise the :exc:`QueueFull` exception (*timeout* is
361+
ignored in that case).
362+
363+
.. method:: put_nowait(obj)
364+
365+
Equivalent to ``put(obj, block=False)``.
366+
367+
.. method:: get(block=True, timeout=None)
368+
369+
Remove and return an object from the queue. If optional args *block*
370+
is true and *timeout* is ``None`` (the default), block if necessary
371+
until an object is available. If *timeout* is a positive number, it
372+
blocks at most *timeout* seconds and raises the :exc:`QueueEmpty`
373+
exception if no object was available within that time. Otherwise
374+
(*block* is false), return an object if one is immediately available,
375+
else raise the :exc:`QueueEmpty` exception (*timeout* is ignored in
376+
that case).
377+
378+
.. method:: get_nowait()
379+
380+
Equivalent to ``get(block=False)``.
381+
382+
383+
.. exception:: QueueEmpty
336384

337385
This exception, a subclass of :exc:`queue.Empty`, is raised from
338-
:meth:`!Queue.get` and :meth:`!Queue.get_nowait` when the queue
386+
:meth:`Queue.get` and :meth:`Queue.get_nowait` when the queue
339387
is empty.
340388

341-
.. exception:: QueueFullError
389+
.. exception:: QueueFull
342390

343391
This exception, a subclass of :exc:`queue.Full`, is raised from
344-
:meth:`!Queue.put` and :meth:`!Queue.put_nowait` when the queue
392+
:meth:`Queue.put` and :meth:`Queue.put_nowait` when the queue
345393
is full.
346394

347395

@@ -382,3 +430,17 @@ Creating an interpreter and running code in it::
382430

383431
t = interp.call_in_thread(run)
384432
t.join()
433+
434+
Communicating between interpreters with a queue::
435+
436+
from concurrent import interpreters
437+
438+
interp = interpreters.create()
439+
queue = interpreters.create_queue()
440+
441+
def worker(queue):
442+
queue.put('spam!')
443+
444+
t = interp.call_in_thread(worker, queue)
445+
print(queue.get())
446+
t.join()

‎Doc/library/ctypes.rst‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1579,7 +1579,10 @@ way is to instantiate :py:class:`CDLL` or one of its subclasses:
15791579
:mod:`!ctypes` maintains a thread-local copy of the system's :data:`errno`
15801580
variable; if you call foreign functions created with ``use_errno=True`` then the
15811581
:data:`errno` value before the function call is swapped with the ctypes private
1582-
copy, the same happens immediately after the function call.
1582+
copy, the same happens immediately after the function call. This mechanism only
1583+
works for libraries that use the same C runtime library as the interpreter itself.
1584+
A library linked against a different C runtime (for example, a different CRT on
1585+
Windows) has its own :data:`errno`, which :mod:`!ctypes` cannot observe.
15831586

15841587
The function :func:`ctypes.get_errno` returns the value of the ctypes private
15851588
copy, and the function :func:`ctypes.set_errno` changes the ctypes private copy

‎Doc/library/idle.rst‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,8 @@ the mainloop call. One then gets a shell prompt immediately and can
931931
interact with the live application. One just has to remember to
932932
re-enable the mainloop call when running in standard Python.
933933

934+
.. _idle-no-subprocess:
935+
934936
Running without a subprocess
935937
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
936938

0 commit comments

Comments
 (0)