Skip to content

Commit 373e12a

Browse files
authored
Merge branch 'main' into patch-6
2 parents 6a33ade + 79b91e7 commit 373e12a

33 files changed

+1188
-641
lines changed

Doc/library/datetime.rst

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2611,8 +2611,10 @@ requires, and these work on all supported platforms.
26112611
| ``%M`` | Minute as a zero-padded | 00, 01, ..., 59 | \(9) |
26122612
| | decimal number. | | |
26132613
+-----------+--------------------------------+------------------------+-------+
2614-
| ``%n`` | The newline character | ``\n`` | \(0) |
2615-
| | (``'\n'``). | | |
2614+
| ``%n`` | The newline character | ``\n`` | |
2615+
| | (``'\n'``). For | | |
2616+
| | :meth:`!strptime`, zero or | | |
2617+
| | more whitespace. | | |
26162618
+-----------+--------------------------------+------------------------+-------+
26172619
| ``%p`` | Locale's equivalent of either || AM, PM (en_US); | \(1), |
26182620
| | AM or PM. || am, pm (de_DE) | \(3) |
@@ -2625,8 +2627,9 @@ requires, and these work on all supported platforms.
26252627
| ``%S`` | Second as a zero-padded | 00, 01, ..., 59 | \(4), |
26262628
| | decimal number. | | \(9) |
26272629
+-----------+--------------------------------+------------------------+-------+
2628-
| ``%t`` | The tab character | ``\t`` | \(0) |
2629-
| | (``'\t'``). | | |
2630+
| ``%t`` | The tab character (``'\t'``). | ``\t`` | |
2631+
| | For :meth:`!strptime`, | | |
2632+
| | zero or more whitespace. | | |
26302633
+-----------+--------------------------------+------------------------+-------+
26312634
| ``%T`` | ISO 8601 time format, | 10:01:59 | |
26322635
| | equivalent to ``%H:%M:%S``. | | |
@@ -2717,7 +2720,8 @@ differences between platforms in handling of unsupported format specifiers.
27172720
``%:z`` was added for :meth:`~.datetime.strftime`.
27182721

27192722
.. versionadded:: 3.15
2720-
``%:z``, ``%F``, and ``%D`` were added for :meth:`~.datetime.strptime`.
2723+
``%D``, ``%F``, ``%n``, ``%t``, and ``%:z`` were added for
2724+
:meth:`~.datetime.strptime`.
27212725

27222726

27232727
Technical detail

Doc/library/stdtypes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5251,6 +5251,11 @@ Note, the *elem* argument to the :meth:`~object.__contains__`,
52515251
:meth:`~set.discard` methods may be a set. To support searching for an equivalent
52525252
frozenset, a temporary one is created from *elem*.
52535253

5254+
.. seealso::
5255+
5256+
For detailed information on thread-safety guarantees for :class:`set`
5257+
objects, see :ref:`thread-safety-set`.
5258+
52545259

52555260
.. _typesmapping:
52565261

Doc/library/threadsafety.rst

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,3 +342,108 @@ thread, iterate over a copy:
342342
343343
Consider external synchronization when sharing :class:`dict` instances
344344
across threads.
345+
346+
347+
.. _thread-safety-set:
348+
349+
Thread safety for set objects
350+
==============================
351+
352+
The :func:`len` function is lock-free and :term:`atomic <atomic operation>`.
353+
354+
The following read operation is lock-free. It does not block concurrent
355+
modifications and may observe intermediate states from operations that
356+
hold the per-object lock:
357+
358+
.. code-block::
359+
:class: good
360+
361+
elem in s # set.__contains__
362+
363+
This operation may compare elements using :meth:`~object.__eq__`, which can
364+
execute arbitrary Python code. During such comparisons, the set may be
365+
modified by another thread. For built-in types like :class:`str`,
366+
:class:`int`, and :class:`float`, :meth:`!__eq__` does not release the
367+
underlying lock during comparisons and this is not a concern.
368+
369+
All other operations from here on hold the per-object lock.
370+
371+
Adding or removing a single element is safe to call from multiple threads
372+
and will not corrupt the set:
373+
374+
.. code-block::
375+
:class: good
376+
377+
s.add(elem) # add element
378+
s.remove(elem) # remove element, raise if missing
379+
s.discard(elem) # remove element if present
380+
s.pop() # remove and return arbitrary element
381+
382+
These operations also compare elements, so the same :meth:`~object.__eq__`
383+
considerations as above apply.
384+
385+
The :meth:`~set.copy` method returns a new object and holds the per-object lock
386+
for the duration so that it is always atomic.
387+
388+
The :meth:`~set.clear` method holds the lock for its duration. Other
389+
threads cannot observe elements being removed.
390+
391+
The following operations only accept :class:`set` or :class:`frozenset`
392+
as operands and always lock both objects:
393+
394+
.. code-block::
395+
:class: good
396+
397+
s |= other # other must be set/frozenset
398+
s &= other # other must be set/frozenset
399+
s -= other # other must be set/frozenset
400+
s ^= other # other must be set/frozenset
401+
s & other # other must be set/frozenset
402+
s | other # other must be set/frozenset
403+
s - other # other must be set/frozenset
404+
s ^ other # other must be set/frozenset
405+
406+
:meth:`set.update`, :meth:`set.union`, :meth:`set.intersection` and
407+
:meth:`set.difference` can take multiple iterables as arguments. They all
408+
iterate through all the passed iterables and do the following:
409+
410+
* :meth:`set.update` and :meth:`set.union` lock both objects only when
411+
the other operand is a :class:`set`, :class:`frozenset`, or :class:`dict`.
412+
* :meth:`set.intersection` and :meth:`set.difference` always try to lock
413+
all objects.
414+
415+
:meth:`set.symmetric_difference` tries to lock both objects.
416+
417+
The update variants of the above methods also have some differences between
418+
them:
419+
420+
* :meth:`set.difference_update` and :meth:`set.intersection_update` try
421+
to lock all objects one-by-one.
422+
* :meth:`set.symmetric_difference_update` only locks the arguments if it is
423+
of type :class:`set`, :class:`frozenset`, or :class:`dict`.
424+
425+
The following methods always try to lock both objects:
426+
427+
.. code-block::
428+
:class: good
429+
430+
s.isdisjoint(other) # both locked
431+
s.issubset(other) # both locked
432+
s.issuperset(other) # both locked
433+
434+
Operations that involve multiple accesses, as well as iteration, are never
435+
atomic:
436+
437+
.. code-block::
438+
:class: bad
439+
440+
# NOT atomic: check-then-act
441+
if elem in s:
442+
s.remove(elem)
443+
444+
# NOT thread-safe: iteration while modifying
445+
for elem in s:
446+
process(elem) # another thread may modify s
447+
448+
Consider external synchronization when sharing :class:`set` instances
449+
across threads. See :ref:`freethreading-python-howto` for more information.

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/tutorial/errors.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ A :keyword:`try` statement may have more than one *except clause*, to specify
121121
handlers for different exceptions. At most one handler will be executed.
122122
Handlers only handle exceptions that occur in the corresponding *try clause*,
123123
not in other handlers of the same :keyword:`!try` statement. An *except clause*
124-
may name multiple exceptions as a parenthesized tuple, for example::
124+
may name multiple exceptions, for example::
125125

126-
... except (RuntimeError, TypeError, NameError):
126+
... except RuntimeError, TypeError, NameError:
127127
... pass
128128

129129
A class in an :keyword:`except` clause matches exceptions which are instances of the

Doc/whatsnew/3.15.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,9 @@ shelve
913913
* Added new :meth:`!reorganize` method to :mod:`shelve` used to recover unused free
914914
space previously occupied by deleted entries.
915915
(Contributed by Andrea Oliveri in :gh:`134004`.)
916+
* Add support for custom serialization and deserialization functions
917+
in the :mod:`shelve` module.
918+
(Contributed by Furkan Onder in :gh:`99631`.)
916919

917920

918921
socket
@@ -1516,6 +1519,21 @@ typing
15161519
wave
15171520
----
15181521

1522+
* Added support for IEEE floating-point WAVE audio
1523+
(``WAVE_FORMAT_IEEE_FLOAT``) in :mod:`wave`.
1524+
1525+
* Added :meth:`wave.Wave_read.getformat`, :meth:`wave.Wave_write.getformat`,
1526+
and :meth:`wave.Wave_write.setformat` for explicit frame format handling.
1527+
1528+
* :meth:`wave.Wave_write.setparams` accepts both 7-item tuples including
1529+
``format`` and 6-item tuples for backwards compatibility (defaulting to
1530+
``WAVE_FORMAT_PCM``).
1531+
1532+
* ``WAVE_FORMAT_IEEE_FLOAT`` output now includes a ``fact`` chunk,
1533+
as required for non-PCM WAVE formats.
1534+
1535+
(Contributed by Lionel Koenig and Michiel W. Beijen in :gh:`60729`.)
1536+
15191537
* Removed the ``getmark()``, ``setmark()`` and ``getmarkers()`` methods
15201538
of the :class:`~wave.Wave_read` and :class:`~wave.Wave_write` classes,
15211539
which were deprecated since Python 3.13.

Lib/_strptime.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,10 @@ def __init__(self, locale_time=None):
382382
'Z': self.__seqToRE((tz for tz_names in self.locale_time.timezone
383383
for tz in tz_names),
384384
'Z'),
385-
'%': '%'}
385+
'n': r'\s*',
386+
't': r'\s*',
387+
'%': '%',
388+
}
386389
if self.locale_time.LC_alt_digits is None:
387390
for d in 'dmyCHIMS':
388391
mapping['O' + d] = r'(?P<%s>\d\d|\d| \d)' % d

Lib/pprint.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ def _pprint_dict(self, object, stream, indent, allowance, context, level):
238238
def _pprint_frozendict(self, object, stream, indent, allowance, context, level):
239239
write = stream.write
240240
cls = object.__class__
241-
stream.write(cls.__name__ + '(')
241+
write(cls.__name__ + '(')
242242
length = len(object)
243243
if length:
244244
self._pprint_dict(object, stream,
25.9 KB
Binary file not shown.

0 commit comments

Comments
 (0)