Skip to content
Open
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Add everything to code blocks
  • Loading branch information
lysnikolaou committed Dec 11, 2025
commit 22928961a9d2ee7d0123ba4dd9f8c7c575af6636
13 changes: 9 additions & 4 deletions Doc/library/stdtypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1460,7 +1460,7 @@ application).
lst.reverse()
lst.sort()

The following operations/methods are not atomic:
The following operations/methods are not fully atomic:

.. code-block::
:class: maybe
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this could say something like “Operations/methods that involve iteration are generally not atomic, except when used with specific built-in types”, and iteration itself can be moved here?
Mentioning iteration might help people make sense of this, i.e. it's no longer two arbitrary lists of operations/methods.

Then the bad section below would be left only with examples of “manually” combining multiple operations.

Copy link
Member Author

@lysnikolaou lysnikolaou Dec 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how I feel about this. "Operations/methods that involve iteration are generally not atomic" is probably not a mnemonic we want people to use, because there are methods that are atomic but traverse the list. Granted most of those are ones that also mutate it, but e.g. list.copy doesn't.

But the idea of separating iteration from manually combining multiple operations is good. Maybe we should do just that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good.
(I guess it's “operations that involve arbitrary iterators and/or comparison functions”, but that's too long; readers whom that would help can figure it out from the list.)

As for iteration, it sounds like the guarantees are the same for single-threaded code: iteration of a list that is being modified may skip elements or yield repeated elements, but will not crash or produce elements that were never part of the list. Is that right?


Is this the place to document list iterators -- i.e. what happens if you use a shared iterator in several threads?

Expand All @@ -1469,6 +1469,11 @@ application).
lst.count(item)
item in lst

lst.extend(iterable)
lst += iterable

lst[i:j] = iterable

The :meth:`~list.index` and :meth:`~list.count` methods, and the ``in``
operator, iterate the list without holding a lock. They are safe to call
concurrently but may return results affected by concurrent modifications.
Expand All @@ -1482,9 +1487,9 @@ application).
applies to inplace concatenation of list with other iterables when using
``lst += iterable``.

Similarly, assigning to a list slice with ``lst[i:j] = obj`` is always
atomic with respect to the target list, but ``obj`` is only locked when it
is also a :class:`list`.
Similarly, assigning to a list slice with ``lst[i:j] = iterable`` is always
atomic with respect to the target list, but ``iterable`` is only locked when
it is also a :class:`list`.

Operations that involve multiple accesses, as well as iteration, are not
atomic. For example:
Expand Down
Loading