Skip to content

Commit d70e699

Browse files
authored
Merge branch 'main' into ziplongest_ft
2 parents 94fd7d7 + 847f83e commit d70e699

90 files changed

Lines changed: 3723 additions & 2260 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/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/stdtypes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5045,6 +5045,9 @@ copying.
50455045

50465046
.. versionadded:: 3.3
50475047

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

50495052
.. _types-set:
50505053

Doc/library/threadsafety.rst

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,3 +548,59 @@ Thread safety for bytearray objects
548548
549549
Consider external synchronization when sharing :class:`bytearray` instances
550550
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.

Doc/reference/datamodel.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3637,12 +3637,25 @@ implement the protocol in Python.
36373637
provides a convenient way to interpret the flags. The method must return
36383638
a :class:`memoryview` object.
36393639

3640+
**Thread safety:** In :term:`free-threaded <free threading>` Python,
3641+
implementations must manage any internal export counter using atomic
3642+
operations. The method must be safe to call concurrently from multiple
3643+
threads, and the returned buffer's underlying data must remain valid
3644+
until the corresponding :meth:`~object.__release_buffer__` call
3645+
completes. See :ref:`thread-safety-memoryview` for details.
3646+
36403647
.. method:: object.__release_buffer__(self, buffer)
36413648

36423649
Called when a buffer is no longer needed. The *buffer* argument is a
36433650
:class:`memoryview` object that was previously returned by
36443651
:meth:`~object.__buffer__`. The method must release any resources associated
36453652
with the buffer. This method should return ``None``.
3653+
3654+
**Thread safety:** In :term:`free-threaded <free threading>` Python,
3655+
any export counter decrement must use atomic operations. Resource
3656+
cleanup must be thread-safe, as the final release may race with
3657+
concurrent releases from other threads.
3658+
36463659
Buffer objects that do not need to perform any cleanup are not required
36473660
to implement this method.
36483661

Doc/tutorial/datastructures.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,9 @@ Curly braces or the :func:`set` function can be used to create sets. Note: to
493493
create an empty set you have to use ``set()``, not ``{}``; the latter creates an
494494
empty dictionary, a data structure that we discuss in the next section.
495495

496+
Because sets are unordered, iterating over them or printing them can
497+
produce the elements in a different order than you expect.
498+
496499
Here is a brief demonstration::
497500

498501
>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}

Doc/whatsnew/3.15.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,6 +1511,21 @@ typing
15111511
wave
15121512
----
15131513

1514+
* Added support for IEEE floating-point WAVE audio
1515+
(``WAVE_FORMAT_IEEE_FLOAT``) in :mod:`wave`.
1516+
1517+
* Added :meth:`wave.Wave_read.getformat`, :meth:`wave.Wave_write.getformat`,
1518+
and :meth:`wave.Wave_write.setformat` for explicit frame format handling.
1519+
1520+
* :meth:`wave.Wave_write.setparams` accepts both 7-item tuples including
1521+
``format`` and 6-item tuples for backwards compatibility (defaulting to
1522+
``WAVE_FORMAT_PCM``).
1523+
1524+
* ``WAVE_FORMAT_IEEE_FLOAT`` output now includes a ``fact`` chunk,
1525+
as required for non-PCM WAVE formats.
1526+
1527+
(Contributed by Lionel Koenig and Michiel W. Beijen in :gh:`60729`.)
1528+
15141529
* Removed the ``getmark()``, ``setmark()`` and ``getmarkers()`` methods
15151530
of the :class:`~wave.Wave_read` and :class:`~wave.Wave_write` classes,
15161531
which were deprecated since Python 3.13.

Include/internal/pycore_call.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ PyAPI_FUNC(PyObject*) _PyObject_CallMethod(
6565
const char *format, ...);
6666

6767

68+
extern PyObject *_PyObject_VectorcallPrepend(
69+
PyThreadState *tstate,
70+
PyObject *callable,
71+
PyObject *arg,
72+
PyObject *const *args,
73+
size_t nargsf,
74+
PyObject *kwnames);
75+
6876
/* === Vectorcall protocol (PEP 590) ============================= */
6977

7078
// Call callable using tp_call. Arguments are like PyObject_Vectorcall(),

Include/internal/pycore_function.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ static inline PyObject* _PyFunction_GET_BUILTINS(PyObject *func) {
4646
#define _PyFunction_GET_BUILTINS(func) _PyFunction_GET_BUILTINS(_PyObject_CAST(func))
4747

4848

49+
/* Get the callable wrapped by a classmethod.
50+
Returns a borrowed reference.
51+
The caller must ensure 'cm' is a classmethod object. */
52+
extern PyObject *_PyClassMethod_GetFunc(PyObject *cm);
53+
4954
/* Get the callable wrapped by a staticmethod.
5055
Returns a borrowed reference.
5156
The caller must ensure 'sm' is a staticmethod object. */

Include/internal/pycore_object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ extern PyObject *_PyType_LookupRefAndVersion(PyTypeObject *, PyObject *,
895895
extern unsigned int
896896
_PyType_LookupStackRefAndVersion(PyTypeObject *type, PyObject *name, _PyStackRef *out);
897897

898-
PyAPI_FUNC(int) _PyObject_GetMethodStackRef(PyThreadState *ts, PyObject *obj,
898+
extern int _PyObject_GetMethodStackRef(PyThreadState *ts, _PyStackRef *self,
899899
PyObject *name, _PyStackRef *method);
900900

901901
// Like PyObject_GetAttr but returns a _PyStackRef. For types, this can

0 commit comments

Comments
 (0)