Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions Doc/library/datetime.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2611,8 +2611,10 @@ requires, and these work on all supported platforms.
| ``%M`` | Minute as a zero-padded | 00, 01, ..., 59 | \(9) |
| | decimal number. | | |
+-----------+--------------------------------+------------------------+-------+
| ``%n`` | The newline character | ``\n`` | \(0) |
| | (``'\n'``). | | |
| ``%n`` | The newline character | ``\n`` | |
| | (``'\n'``). For | | |
| | :meth:`!strptime`, zero or | | |
| | more whitespace. | | |
+-----------+--------------------------------+------------------------+-------+
| ``%p`` | Locale's equivalent of either || AM, PM (en_US); | \(1), |
| | AM or PM. || am, pm (de_DE) | \(3) |
Expand All @@ -2625,8 +2627,9 @@ requires, and these work on all supported platforms.
| ``%S`` | Second as a zero-padded | 00, 01, ..., 59 | \(4), |
| | decimal number. | | \(9) |
+-----------+--------------------------------+------------------------+-------+
| ``%t`` | The tab character | ``\t`` | \(0) |
| | (``'\t'``). | | |
| ``%t`` | The tab character (``'\t'``). | ``\t`` | |
| | For :meth:`!strptime`, | | |
| | zero or more whitespace. | | |
+-----------+--------------------------------+------------------------+-------+
| ``%T`` | ISO 8601 time format, | 10:01:59 | |
| | equivalent to ``%H:%M:%S``. | | |
Expand Down Expand Up @@ -2717,7 +2720,8 @@ differences between platforms in handling of unsupported format specifiers.
``%:z`` was added for :meth:`~.datetime.strftime`.

.. versionadded:: 3.15
``%:z``, ``%F``, and ``%D`` were added for :meth:`~.datetime.strptime`.
``%D``, ``%F``, ``%n``, ``%t``, and ``%:z`` were added for
:meth:`~.datetime.strptime`.


Technical detail
Expand Down
5 changes: 5 additions & 0 deletions Doc/library/stdtypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5251,6 +5251,11 @@ Note, the *elem* argument to the :meth:`~object.__contains__`,
:meth:`~set.discard` methods may be a set. To support searching for an equivalent
frozenset, a temporary one is created from *elem*.

.. seealso::

For detailed information on thread-safety guarantees for :class:`set`
objects, see :ref:`thread-safety-set`.


.. _typesmapping:

Expand Down
105 changes: 105 additions & 0 deletions Doc/library/threadsafety.rst
Original file line number Diff line number Diff line change
Expand Up @@ -342,3 +342,108 @@ thread, iterate over a copy:

Consider external synchronization when sharing :class:`dict` instances
across threads.


.. _thread-safety-set:

Thread safety for set objects
==============================

The :func:`len` function is lock-free and :term:`atomic <atomic operation>`.

The following read operation is lock-free. It does not block concurrent
modifications and may observe intermediate states from operations that
hold the per-object lock:

.. code-block::
:class: good

elem in s # set.__contains__

This operation may compare elements using :meth:`~object.__eq__`, which can
execute arbitrary Python code. During such comparisons, the set may be
modified by another thread. For built-in types like :class:`str`,
:class:`int`, and :class:`float`, :meth:`!__eq__` does not release the
underlying lock during comparisons and this is not a concern.

All other operations from here on hold the per-object lock.

Adding or removing a single element is safe to call from multiple threads
and will not corrupt the set:

.. code-block::
:class: good

s.add(elem) # add element
s.remove(elem) # remove element, raise if missing
s.discard(elem) # remove element if present
s.pop() # remove and return arbitrary element

These operations also compare elements, so the same :meth:`~object.__eq__`
considerations as above apply.

The :meth:`~set.copy` method returns a new object and holds the per-object lock
for the duration so that it is always atomic.

The :meth:`~set.clear` method holds the lock for its duration. Other
threads cannot observe elements being removed.

The following operations only accept :class:`set` or :class:`frozenset`
as operands and always lock both objects:

.. code-block::
:class: good

s |= other # other must be set/frozenset
s &= other # other must be set/frozenset
s -= other # other must be set/frozenset
s ^= other # other must be set/frozenset
s & other # other must be set/frozenset
s | other # other must be set/frozenset
s - other # other must be set/frozenset
s ^ other # other must be set/frozenset

:meth:`set.update`, :meth:`set.union`, :meth:`set.intersection` and
:meth:`set.difference` can take multiple iterables as arguments. They all
iterate through all the passed iterables and do the following:

* :meth:`set.update` and :meth:`set.union` lock both objects only when
the other operand is a :class:`set`, :class:`frozenset`, or :class:`dict`.
* :meth:`set.intersection` and :meth:`set.difference` always try to lock
all objects.

:meth:`set.symmetric_difference` tries to lock both objects.

The update variants of the above methods also have some differences between
them:

* :meth:`set.difference_update` and :meth:`set.intersection_update` try
to lock all objects one-by-one.
* :meth:`set.symmetric_difference_update` only locks the arguments if it is
of type :class:`set`, :class:`frozenset`, or :class:`dict`.

The following methods always try to lock both objects:

.. code-block::
:class: good

s.isdisjoint(other) # both locked
s.issubset(other) # both locked
s.issuperset(other) # both locked

Operations that involve multiple accesses, as well as iteration, are never
atomic:

.. code-block::
:class: bad

# NOT atomic: check-then-act
if elem in s:
s.remove(elem)

# NOT thread-safe: iteration while modifying
for elem in s:
process(elem) # another thread may modify s

Consider external synchronization when sharing :class:`set` instances
across threads. See :ref:`freethreading-python-howto` for more information.
69 changes: 62 additions & 7 deletions Doc/library/wave.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,19 @@
--------------

The :mod:`!wave` module provides a convenient interface to the Waveform Audio
"WAVE" (or "WAV") file format. Only uncompressed PCM encoded wave files are
supported.
"WAVE" (or "WAV") file format.

The module supports uncompressed PCM and IEEE floating-point WAV formats.

.. versionchanged:: 3.12

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

.. versionchanged:: next

Support for reading and writing ``WAVE_FORMAT_IEEE_FLOAT`` files was added.

The :mod:`!wave` module defines the following function and exception:


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


.. data:: WAVE_FORMAT_PCM

Format code for uncompressed PCM audio.


.. data:: WAVE_FORMAT_IEEE_FLOAT

Format code for IEEE floating-point audio.


.. data:: WAVE_FORMAT_EXTENSIBLE

Format code for WAVE extensible headers.


.. _wave-read-objects:

Wave_read Objects
Expand Down Expand Up @@ -98,6 +118,14 @@ Wave_read Objects
Returns number of audio frames.


.. method:: getformat()

Returns the frame format code.

This is one of :data:`WAVE_FORMAT_PCM`,
:data:`WAVE_FORMAT_IEEE_FLOAT`, or :data:`WAVE_FORMAT_EXTENSIBLE`.


.. method:: getcomptype()

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

Returns a :func:`~collections.namedtuple` ``(nchannels, sampwidth,
framerate, nframes, comptype, compname)``, equivalent to output of the
``get*()`` methods.
framerate, nframes, comptype, compname)``, equivalent to output
of the ``get*()`` methods.


.. method:: readframes(n)
Expand Down Expand Up @@ -190,6 +218,9 @@ Wave_write Objects

Set the sample width to *n* bytes.

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


.. method:: getsampwidth()

Expand Down Expand Up @@ -238,11 +269,32 @@ Wave_write Objects
Return the human-readable compression type name.


.. method:: setformat(format)

Set the frame format code.

Supported values are :data:`WAVE_FORMAT_PCM` and
:data:`WAVE_FORMAT_IEEE_FLOAT`.

When setting :data:`WAVE_FORMAT_IEEE_FLOAT`, the sample width must be
4 or 8 bytes.


.. method:: getformat()

Return the current frame format code.


.. method:: setparams(tuple)

The *tuple* should be ``(nchannels, sampwidth, framerate, nframes, comptype,
compname)``, with values valid for the ``set*()`` methods. Sets all
parameters.
The *tuple* should be
``(nchannels, sampwidth, framerate, nframes, comptype, compname, format)``,
with values valid for the ``set*()`` methods. Sets all parameters.

For backwards compatibility, a 6-item tuple without *format* is also
accepted and defaults to :data:`WAVE_FORMAT_PCM`.

For ``format=WAVE_FORMAT_IEEE_FLOAT``, *sampwidth* must be 4 or 8.


.. method:: getparams()
Expand Down Expand Up @@ -279,3 +331,6 @@ Wave_write Objects
Note that it is invalid to set any parameters after calling :meth:`writeframes`
or :meth:`writeframesraw`, and any attempt to do so will raise
:exc:`wave.Error`.

For :data:`WAVE_FORMAT_IEEE_FLOAT` output, a ``fact`` chunk is written as
required by the WAVE specification for non-PCM formats.
18 changes: 18 additions & 0 deletions Doc/whatsnew/3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,9 @@ shelve
* Added new :meth:`!reorganize` method to :mod:`shelve` used to recover unused free
space previously occupied by deleted entries.
(Contributed by Andrea Oliveri in :gh:`134004`.)
* Add support for custom serialization and deserialization functions
in the :mod:`shelve` module.
(Contributed by Furkan Onder in :gh:`99631`.)


socket
Expand Down Expand Up @@ -1515,6 +1518,21 @@ typing
wave
----

* Added support for IEEE floating-point WAVE audio
(``WAVE_FORMAT_IEEE_FLOAT``) in :mod:`wave`.

* Added :meth:`wave.Wave_read.getformat`, :meth:`wave.Wave_write.getformat`,
and :meth:`wave.Wave_write.setformat` for explicit frame format handling.

* :meth:`wave.Wave_write.setparams` accepts both 7-item tuples including
``format`` and 6-item tuples for backwards compatibility (defaulting to
``WAVE_FORMAT_PCM``).

* ``WAVE_FORMAT_IEEE_FLOAT`` output now includes a ``fact`` chunk,
as required for non-PCM WAVE formats.

(Contributed by Lionel Koenig and Michiel W. Beijen in :gh:`60729`.)

* Removed the ``getmark()``, ``setmark()`` and ``getmarkers()`` methods
of the :class:`~wave.Wave_read` and :class:`~wave.Wave_write` classes,
which were deprecated since Python 3.13.
Expand Down
5 changes: 4 additions & 1 deletion Lib/_strptime.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,10 @@ def __init__(self, locale_time=None):
'Z': self.__seqToRE((tz for tz_names in self.locale_time.timezone
for tz in tz_names),
'Z'),
'%': '%'}
'n': r'\s*',
't': r'\s*',
'%': '%',
}
if self.locale_time.LC_alt_digits is None:
for d in 'dmyCHIMS':
mapping['O' + d] = r'(?P<%s>\d\d|\d| \d)' % d
Expand Down
2 changes: 1 addition & 1 deletion Lib/pprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ def _pprint_dict(self, object, stream, indent, allowance, context, level):
def _pprint_frozendict(self, object, stream, indent, allowance, context, level):
write = stream.write
cls = object.__class__
stream.write(cls.__name__ + '(')
write(cls.__name__ + '(')
length = len(object)
if length:
self._pprint_dict(object, stream,
Expand Down
Binary file added Lib/test/audiodata/pluck-float32.wav
Binary file not shown.
Loading
Loading