8000 FIX: make safe to add / remove artists during ArtistList iteration by tacaswell · Pull Request #22229 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

FIX: make safe to add / remove artists during ArtistList iteration #22229

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 27, 2022
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
18 changes: 18 additions & 0 deletions doc/api/next_api_changes/behavior/22229-TAC.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
AritistList proxies copy contents on iteration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

When iterating over the contents of the the dynamically generated proxy lists
for the Artist-type accessors (see :ref:`Behavioural API Changes 3.5 - Axes
children combined`), a copy of the contents is made. This ensure that artists
can safely be added or removed from the Axes while iterating over their children.

This is a departure from the expected behavior of mutable iterable data types
in Python -- iterating over list while mutating it has surprising consequences
and dictionaries will error if they change size during iteration.
Because all of the accessors are filtered views of the same underlying list, it
is possible for seemingly unrelated changes, such as removing a Line, to affect
the iteration over any of the other accessors. In this case, we have opted to
make a copy of the relevant children before yielding them to the user.

This change is also consistent with our plan to make these accessors immutable
in Matplotlib 3.7.
2 changes: 1 addition & 1 deletion lib/matplotlib/axes/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1366,7 +1366,7 @@ def __len__(self):
for artist in self._axes._children)

def __iter__(self):
for artist in self._axes._children:
for artist in list(self._axes._children):
if self._type_check(artist):
yield artist

Expand Down
4 changes: 4 additions & 0 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7360,6 +7360,10 @@ def test_artist_sublists():
assert ax.lines + [1, 2, 3] == [*lines, 1, 2, 3]
assert [1, 2, 3] + ax.lines == [1, 2, 3, *lines]

for ln in ax.lines:
ln.remove()
assert len(ax.lines) == 0


def test_empty_line_plots():
# Incompatible nr columns, plot "nothing"
Expand Down
0