Skip to content

Commit c2cb451

Browse files
authored
Merge branch 'main' into frozen-dict-partial
2 parents 5225f6a + 847f83e commit c2cb451

File tree

162 files changed

+5381
-3255
lines changed

Some content is hidden

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

162 files changed

+5381
-3255
lines changed

Doc/c-api/float.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,8 @@ NaNs (if such things exist on the platform) isn't handled correctly, and
201201
attempting to unpack a bytes string containing an IEEE INF or NaN will raise an
202202
exception.
203203
204-
Note that NaNs type may not be preserved on IEEE platforms (signaling NaN become
205-
quiet NaN), for example on x86 systems in 32-bit mode.
204+
Note that NaN type may not be preserved on IEEE platforms (signaling NaNs become
205+
quiet NaNs), for example on x86 systems in 32-bit mode.
206206
207207
On non-IEEE platforms with more precision, or larger dynamic range, than IEEE
208208
754 supports, not all values can be packed; on non-IEEE platforms with less
@@ -216,7 +216,7 @@ Pack functions
216216
217217
The pack routines write 2, 4 or 8 bytes, starting at *p*. *le* is an
218218
:c:expr:`int` argument, non-zero if you want the bytes string in little-endian
219-
format (exponent last, at ``p+1``, ``p+3``, or ``p+6`` ``p+7``), zero if you
219+
format (exponent last, at ``p+1``, ``p+3``, or ``p+6`` and ``p+7``), zero if you
220220
want big-endian format (exponent first, at *p*). The :c:macro:`PY_BIG_ENDIAN`
221221
constant can be used to use the native endian: it is equal to ``1`` on big
222222
endian processor, or ``0`` on little endian processor.

Doc/c-api/typeobj.rst

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3057,6 +3057,24 @@ Buffer Object Structures
30573057

30583058
(5) Return ``0``.
30593059

3060+
**Thread safety:**
3061+
3062+
In the :term:`free-threaded build`, implementations must ensure:
3063+
3064+
* The export counter increment in step (3) is atomic.
3065+
3066+
* The underlying buffer data remains valid and at a stable memory
3067+
location for the lifetime of all exports.
3068+
3069+
* For objects that support resizing or reallocation (such as
3070+
:class:`bytearray`), the export counter is checked atomically before
3071+
such operations, and :exc:`BufferError` is raised if exports exist.
3072+
3073+
* The function is safe to call concurrently from multiple threads.
3074+
3075+
See also :ref:`thread-safety-memoryview` for the Python-level
3076+
thread safety guarantees of :class:`memoryview` objects.
3077+
30603078
If *exporter* is part of a chain or tree of buffer providers, two main
30613079
schemes can be used:
30623080

@@ -3102,6 +3120,16 @@ Buffer Object Structures
31023120

31033121
(2) If the counter is ``0``, free all memory associated with *view*.
31043122

3123+
**Thread safety:**
3124+
3125+
In the :term:`free-threaded build`:
3126+
3127+
* The export counter decrement in step (1) must be atomic.
3128+
3129+
* Resource cleanup when the counter reaches zero must be done atomically,
3130+
as the final release may race with concurrent releases from other
3131+
threads and dellocation must only happen once.
3132+
31053133
The exporter MUST use the :c:member:`~Py_buffer.internal` field to keep
31063134
track of buffer-specific resources. This field is guaranteed to remain
31073135
constant, while a consumer MAY pass a copy of the original buffer as the

Doc/library/asyncio-task.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ Running Tasks Concurrently
557557
provides stronger safety guarantees than *gather* for scheduling a nesting of subtasks:
558558
if a task (or a subtask, a task scheduled by a task)
559559
raises an exception, *TaskGroup* will, while *gather* will not,
560-
cancel the remaining scheduled tasks).
560+
cancel the remaining scheduled tasks.
561561

562562
.. _asyncio_example_gather:
563563

Doc/library/stdtypes.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3514,6 +3514,11 @@ The representation of bytearray objects uses the bytes literal format
35143514
``bytearray([46, 46, 46])``. You can always convert a bytearray object into
35153515
a list of integers using ``list(b)``.
35163516

3517+
.. seealso::
3518+
3519+
For detailed information on thread-safety guarantees for :class:`bytearray`
3520+
objects, see :ref:`thread-safety-bytearray`.
3521+
35173522

35183523
.. _bytes-methods:
35193524

@@ -5040,6 +5045,9 @@ copying.
50405045

50415046
.. versionadded:: 3.3
50425047

5048+
For information on the thread safety of :class:`memoryview` objects in
5049+
the :term:`free-threaded build`, see :ref:`thread-safety-memoryview`.
5050+
50435051

50445052
.. _types-set:
50455053

Doc/library/threadsafety.rst

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,3 +447,160 @@ atomic:
447447
448448
Consider external synchronization when sharing :class:`set` instances
449449
across threads. See :ref:`freethreading-python-howto` for more information.
450+
451+
452+
.. _thread-safety-bytearray:
453+
454+
Thread safety for bytearray objects
455+
===================================
456+
457+
The :func:`len` function is lock-free and :term:`atomic <atomic operation>`.
458+
459+
Concatenation and comparisons use the buffer protocol, which prevents
460+
resizing but does not hold the per-object lock. These operations may
461+
observe intermediate states from concurrent modifications:
462+
463+
.. code-block::
464+
:class: maybe
465+
466+
ba + other # may observe concurrent writes
467+
ba == other # may observe concurrent writes
468+
ba < other # may observe concurrent writes
469+
470+
All other operations from here on hold the per-object lock.
471+
472+
Reading a single element or slice is safe to call from multiple threads:
473+
474+
.. code-block::
475+
:class: good
476+
477+
ba[i] # bytearray.__getitem__
478+
ba[i:j] # slice
479+
480+
The following operations are safe to call from multiple threads and will
481+
not corrupt the bytearray:
482+
483+
.. code-block::
484+
:class: good
485+
486+
ba[i] = x # write single byte
487+
ba[i:j] = values # write slice
488+
ba.append(x) # append single byte
489+
ba.extend(other) # extend with iterable
490+
ba.insert(i, x) # insert single byte
491+
ba.pop() # remove and return last byte
492+
ba.pop(i) # remove and return byte at index
493+
ba.remove(x) # remove first occurrence
494+
ba.reverse() # reverse in place
495+
ba.clear() # remove all bytes
496+
497+
Slice assignment locks both objects when *values* is a :class:`bytearray`:
498+
499+
.. code-block::
500+
:class: good
501+
502+
ba[i:j] = other_bytearray # both locked
503+
504+
The following operations return new objects and hold the per-object lock
505+
for the duration:
506+
507+
.. code-block::
508+
:class: good
509+
510+
ba.copy() # returns a shallow copy
511+
ba * n # repeat into new bytearray
512+
513+
The membership test holds the lock for its duration:
514+
515+
.. code-block::
516+
:class: good
517+
518+
x in ba # bytearray.__contains__
519+
520+
All other bytearray methods (such as :meth:`~bytearray.find`,
521+
:meth:`~bytearray.replace`, :meth:`~bytearray.split`,
522+
:meth:`~bytearray.decode`, etc.) hold the per-object lock for their
523+
duration.
524+
525+
Operations that involve multiple accesses, as well as iteration, are never
526+
atomic:
527+
528+
.. code-block::
529+
:class: bad
530+
531+
# NOT atomic: check-then-act
532+
if x in ba:
533+
ba.remove(x)
534+
535+
# NOT thread-safe: iteration while modifying
536+
for byte in ba:
537+
process(byte) # another thread may modify ba
538+
539+
To safely iterate over a bytearray that may be modified by another
540+
thread, iterate over a copy:
541+
542+
.. code-block::
543+
:class: good
544+
545+
# Make a copy to iterate safely
546+
for byte in ba.copy():
547+
process(byte)
548+
549+
Consider external synchronization when sharing :class:`bytearray` instances
550+
across threads. See :ref:`freethreading-python-howto` for more information.
551+
552+
553+
.. _thread-safety-memoryview:
554+
555+
Thread safety for memoryview objects
556+
====================================
557+
558+
:class:`memoryview` objects provide access to the internal data of an
559+
underlying object without copying. Thread safety depends on both the
560+
memoryview itself and the underlying buffer exporter.
561+
562+
The memoryview implementation uses atomic operations to track its own
563+
exports in the :term:`free-threaded build`. Creating and
564+
releasing a memoryview are thread-safe. Attribute access (e.g.,
565+
:attr:`~memoryview.shape`, :attr:`~memoryview.format`) reads fields that
566+
are immutable for the lifetime of the memoryview, so concurrent reads
567+
are safe as long as the memoryview has not been released.
568+
569+
However, the actual data accessed through the memoryview is owned by the
570+
underlying object. Concurrent access to this data is only safe if the
571+
underlying object supports it:
572+
573+
* For immutable objects like :class:`bytes`, concurrent reads through
574+
multiple memoryviews are safe.
575+
576+
* For mutable objects like :class:`bytearray`, reading and writing the
577+
same memory region from multiple threads without external
578+
synchronization is not safe and may result in data corruption.
579+
Note that even read-only memoryviews of mutable objects do not
580+
prevent data races if the underlying object is modified from
581+
another thread.
582+
583+
.. code-block::
584+
:class: bad
585+
586+
# NOT safe: concurrent writes to the same buffer
587+
data = bytearray(1000)
588+
view = memoryview(data)
589+
# Thread 1: view[0:500] = b'x' * 500
590+
# Thread 2: view[0:500] = b'y' * 500
591+
592+
.. code-block::
593+
:class: good
594+
595+
# Safe: use a lock for concurrent access
596+
import threading
597+
lock = threading.Lock()
598+
data = bytearray(1000)
599+
view = memoryview(data)
600+
601+
with lock:
602+
view[0:500] = b'x' * 500
603+
604+
Resizing or reallocating the underlying object (such as calling
605+
:meth:`bytearray.resize`) while a memoryview is exported raises
606+
:exc:`BufferError`. This is enforced regardless of threading.

Doc/library/wave.rst

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,19 @@
99
--------------
1010

1111
The :mod:`!wave` module provides a convenient interface to the Waveform Audio
12-
"WAVE" (or "WAV") file format. Only uncompressed PCM encoded wave files are
13-
supported.
12+
"WAVE" (or "WAV") file format.
13+
14+
The module supports uncompressed PCM and IEEE floating-point WAV formats.
1415

1516
.. versionchanged:: 3.12
1617

1718
Support for ``WAVE_FORMAT_EXTENSIBLE`` headers was added, provided that the
1819
extended format is ``KSDATAFORMAT_SUBTYPE_PCM``.
1920

21+
.. versionchanged:: next
22+
23+
Support for reading and writing ``WAVE_FORMAT_IEEE_FLOAT`` files was added.
24+
2025
The :mod:`!wave` module defines the following function and exception:
2126

2227

@@ -60,6 +65,21 @@ The :mod:`!wave` module defines the following function and exception:
6065
specification or hits an implementation deficiency.
6166

6267

68+
.. data:: WAVE_FORMAT_PCM
69+
70+
Format code for uncompressed PCM audio.
71+
72+
73+
.. data:: WAVE_FORMAT_IEEE_FLOAT
74+
75+
Format code for IEEE floating-point audio.
76+
77+
78+
.. data:: WAVE_FORMAT_EXTENSIBLE
79+
80+
Format code for WAVE extensible headers.
81+
82+
6383
.. _wave-read-objects:
6484

6585
Wave_read Objects
@@ -98,6 +118,14 @@ Wave_read Objects
98118
Returns number of audio frames.
99119

100120

121+
.. method:: getformat()
122+
123+
Returns the frame format code.
124+
125+
This is one of :data:`WAVE_FORMAT_PCM`,
126+
:data:`WAVE_FORMAT_IEEE_FLOAT`, or :data:`WAVE_FORMAT_EXTENSIBLE`.
127+
128+
101129
.. method:: getcomptype()
102130

103131
Returns compression type (``'NONE'`` is the only supported type).
@@ -112,8 +140,8 @@ Wave_read Objects
112140
.. method:: getparams()
113141

114142
Returns a :func:`~collections.namedtuple` ``(nchannels, sampwidth,
115-
framerate, nframes, comptype, compname)``, equivalent to output of the
116-
``get*()`` methods.
143+
framerate, nframes, comptype, compname)``, equivalent to output
144+
of the ``get*()`` methods.
117145

118146

119147
.. method:: readframes(n)
@@ -190,6 +218,9 @@ Wave_write Objects
190218

191219
Set the sample width to *n* bytes.
192220

221+
For :data:`WAVE_FORMAT_IEEE_FLOAT`, only 4-byte (32-bit) and
222+
8-byte (64-bit) sample widths are supported.
223+
193224

194225
.. method:: getsampwidth()
195226

@@ -238,11 +269,32 @@ Wave_write Objects
238269
Return the human-readable compression type name.
239270

240271

272+
.. method:: setformat(format)
273+
274+
Set the frame format code.
275+
276+
Supported values are :data:`WAVE_FORMAT_PCM` and
277+
:data:`WAVE_FORMAT_IEEE_FLOAT`.
278+
279+
When setting :data:`WAVE_FORMAT_IEEE_FLOAT`, the sample width must be
280+
4 or 8 bytes.
281+
282+
283+
.. method:: getformat()
284+
285+
Return the current frame format code.
286+
287+
241288
.. method:: setparams(tuple)
242289

243-
The *tuple* should be ``(nchannels, sampwidth, framerate, nframes, comptype,
244-
compname)``, with values valid for the ``set*()`` methods. Sets all
245-
parameters.
290+
The *tuple* should be
291+
``(nchannels, sampwidth, framerate, nframes, comptype, compname, format)``,
292+
with values valid for the ``set*()`` methods. Sets all parameters.
293+
294+
For backwards compatibility, a 6-item tuple without *format* is also
295+
accepted and defaults to :data:`WAVE_FORMAT_PCM`.
296+
297+
For ``format=WAVE_FORMAT_IEEE_FLOAT``, *sampwidth* must be 4 or 8.
246298

247299

248300
.. method:: getparams()
@@ -279,3 +331,6 @@ Wave_write Objects
279331
Note that it is invalid to set any parameters after calling :meth:`writeframes`
280332
or :meth:`writeframesraw`, and any attempt to do so will raise
281333
:exc:`wave.Error`.
334+
335+
For :data:`WAVE_FORMAT_IEEE_FLOAT` output, a ``fact`` chunk is written as
336+
required by the WAVE specification for non-PCM formats.

0 commit comments

Comments
 (0)