Skip to content

Commit 4a9ade0

Browse files
committed
Warn if an animation is gc'd before doing anything.
Fixes #18438.
1 parent bd765e0 commit 4a9ade0

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

lib/matplotlib/animation.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import sys
2929
from tempfile import TemporaryDirectory
3030
import uuid
31+
import warnings
3132

3233
import numpy as np
3334

@@ -907,6 +908,8 @@ class Animation:
907908
"""
908909

909910
def __init__(self, fig, event_source=None, blit=False):
911+
self._anim_was_inited = False
912+
910913
self._fig = fig
911914
# Disables blitting for backends that don't support it. This
912915
# allows users to request it if available, but still have a
@@ -931,6 +934,11 @@ def __init__(self, fig, event_source=None, blit=False):
931934
if self._blit:
932935
self._setup_blit()
933936

937+
def __del__(self):
938+
if not getattr(self, '_anim_was_inited', True):
939+
warnings.warn('Animation was garbage-collected before saving any '
940+
'frames; did you forget to save it to a variable?')
941+
934942
def _start(self, *args):
935943
"""
936944
Starts interactive animation. Adds the draw frame command to the GUI
@@ -1166,7 +1174,7 @@ def _draw_next_frame(self, framedata, blit):
11661174
def _init_draw(self):
11671175
# Initial draw to clear the frame. Also used by the blitting code
11681176
# when a clean base is required.
1169-
pass
1177+
self._anim_was_inited = True
11701178

11711179
def _pre_draw(self, framedata, blit):
11721180
# Perform any cleaning or whatnot before the drawing of the frame.
@@ -1484,6 +1492,7 @@ def __init__(self, fig, artists, *args, **kwargs):
14841492
super().__init__(fig, *args, **kwargs)
14851493

14861494
def _init_draw(self):
1495+
super()._init_draw()
14871496
# Make all the artists involved in *any* frame invisible
14881497
figs = set()
14891498
for f in self.new_frame_seq():
@@ -1695,6 +1704,7 @@ def gen():
16951704
return gen()
16961705

16971706
def _init_draw(self):
1707+
super()._init_draw()
16981708
# Initialize the drawing either using the given init_func or by
16991709
# calling the draw function with the first item of the frame sequence.
17001710
# For blitting, the init_func should return a sequence of modified

lib/matplotlib/tests/test_animation.py

+9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import gc
12
import os
23
from pathlib import Path
34
import subprocess
@@ -75,6 +76,14 @@ def test_null_movie_writer():
7576
assert writer._count == num_frames
7677

7778

79+
def test_animation_delete():
80+
anim = make_animation(frames=5)
81+
82+
with pytest.warns(Warning, match='Animation was garbage-collected'):
83+
del anim
84+
gc.collect()
85+
86+
7887
def test_movie_writer_dpi_default():
7988
class DummyMovieWriter(animation.MovieWriter):
8089
def _run(self):

0 commit comments

Comments
 (0)