Skip to content

Commit 64950dd

Browse files
authored
Merge pull request #15932 from anntzer/testcache
TST: Use test cache for test result images too.
2 parents bf3827a + 138df72 commit 64950dd

File tree

1 file changed

+35
-1
lines changed

1 file changed

+35
-1
lines changed

lib/matplotlib/testing/compare.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
"""
44

55
import atexit
6+
import functools
67
import hashlib
8+
import logging
79
import os
810
from pathlib import Path
911
import re
@@ -19,6 +21,8 @@
1921
from matplotlib import cbook
2022
from matplotlib.testing.exceptions import ImageComparisonFailure
2123

24+
_log = logging.getLogger(__name__)
25+
2226
__all__ = ['compare_images', 'comparable_formats']
2327

2428

@@ -285,20 +289,50 @@ def convert(filename, cache):
285289
cache_dir = Path(get_cache_dir()) if cache else None
286290

287291
if cache_dir is not None:
292+
_register_conversion_cache_cleaner_once()
288293
hash_value = get_file_hash(path)
289294
cached_path = cache_dir / (hash_value + newpath.suffix)
290295
if cached_path.exists():
296+
_log.debug("For %s: reusing cached conversion.", filename)
291297
shutil.copyfile(cached_path, newpath)
292298
return str(newpath)
293299

300+
_log.debug("For %s: converting to png.", filename)
294301
converter[path.suffix[1:]](path, newpath)
295302

296303
if cache_dir is not None:
304+
_log.debug("For %s: caching conversion result.", filename)
297305
shutil.copyfile(newpath, cached_path)
298306

299307
return str(newpath)
300308

301309

310+
def _clean_conversion_cache():
311+
# This will actually ignore mpl_toolkits baseline images, but they're
312+
# relatively small.
313+
baseline_images_size = sum(
314+
path.stat().st_size
315+
for path in Path(mpl.__file__).parent.glob("**/baseline_images/**/*"))
316+
# 2x: one full copy of baselines, and one full copy of test results
317+
# (actually an overestimate: we don't convert png baselines and results).
318+
max_cache_size = 2 * baseline_images_size
319+
# Reduce cache until it fits.
320+
cache_stat = {
321+
path: path.stat() for path in Path(get_cache_dir()).glob("*")}
322+
cache_size = sum(stat.st_size for stat in cache_stat.values())
323+
paths_by_atime = sorted( # Oldest at the end.
324+
cache_stat, key=lambda path: cache_stat[path].st_atime, reverse=True)
325+
while cache_size > max_cache_size:
326+
path = paths_by_atime.pop()
327+
cache_size -= cache_stat[path].st_size
328+
path.unlink()
329+
330+
331+
@functools.lru_cache() # Ensure this is only registered once.
332+
def _register_conversion_cache_cleaner_once():
333+
atexit.register(_clean_conversion_cache)
334+
335+
302336
def crop_to_same(actual_path, actual_image, expected_path, expected_image):
303337
# clip the images to the same size -- this is useful only when
304338
# comparing eps to pdf
@@ -387,7 +421,7 @@ def compare_images(expected, actual, tol, in_decorator=False):
387421
raise IOError('Baseline image %r does not exist.' % expected)
388422
extension = expected.split('.')[-1]
389423
if extension != 'png':
390-
actual = convert(actual, cache=False)
424+
actual = convert(actual, cache=True)
391425
expected = convert(expected, cache=True)
392426

393427
# open the image files and remove the alpha channel (if it exists)

0 commit comments

Comments
 (0)