Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 09bd5dd

Browse files
committed
Simplify/pathlibify image_comparison.
There's no public class that inherits from _ImageComparisonBase anymore, so we can improve it by getting rid of the delayed_init mechanism and by pathlibifying its internals without worrying about API breaks. The changes in compare.py are necessary to make these functions also support Path (now passed by _ImageComparisonBase) as arguments.
1 parent 44803e1 commit 09bd5dd

File tree

2 files changed

+27
-41
lines changed

2 files changed

+27
-41
lines changed

lib/matplotlib/testing/compare.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ def convert(filename, cache):
264264
hash of the exact contents of the input file. There is no limit on the
265265
size of the cache, so it may need to be manually cleared periodically.
266266
"""
267-
base, extension = filename.rsplit('.', 1)
267+
base, extension = os.fspath(filename).rsplit('.', 1)
268268
if extension not in converter:
269269
import pytest
270270
pytest.skip(f"Don't know how to convert {extension} files to png")
@@ -369,18 +369,17 @@ def compare_images(expected, actual, tol, in_decorator=False):
369369
"""
370370
from matplotlib import _png
371371

372+
actual = os.fspath(actual)
372373
if not os.path.exists(actual):
373374
raise Exception("Output image %s does not exist." % actual)
374-
375375
if os.stat(actual).st_size == 0:
376376
raise Exception("Output image file %s is empty." % actual)
377377

378378
# Convert the image to png
379-
extension = expected.split('.')[-1]
380-
379+
expected = os.fspath(expected)
381380
if not os.path.exists(expected):
382381
raise IOError('Baseline image %r does not exist.' % expected)
383-
382+
extension = expected.split('.')[-1]
384383
if extension != 'png':
385384
actual = convert(actual, False)
386385
expected = convert(expected, True)

lib/matplotlib/testing/decorators.py

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,6 @@ def _raise_on_image_difference(expected, actual, tol):
127127
__tracebackhide__ = True
128128

129129
err = compare_images(expected, actual, tol, in_decorator=True)
130-
131-
if not os.path.exists(expected):
132-
raise ImageComparisonFailure('image does not exist: %s' % expected)
133-
134130
if err:
135131
for key in ["actual", "expected"]:
136132
err[key] = os.path.relpath(err[key])
@@ -172,38 +168,33 @@ class _ImageComparisonBase:
172168
This class provides *just* the comparison-related functionality and avoids
173169
any code that would be specific to any testing framework.
174170
"""
175-
def __init__(self, tol, remove_text, savefig_kwargs):
176-
self.func = self.baseline_dir = self.result_dir = None
177-
self.tol = tol
178-
self.remove_text = remove_text
179-
self.savefig_kwargs = savefig_kwargs
180171

181-
def delayed_init(self, func):
182-
assert self.func is None, "it looks like same decorator used twice"
172+
def __init__(self, func, tol, remove_text, savefig_kwargs):
183173
self.func = func
184174
self.baseline_dir, self.result_dir = _image_directories(func)
175+
self.tol = tol
176+
self.remove_text = remove_text
177+
self.savefig_kwargs = savefig_kwargs
185178

186179
def copy_baseline(self, baseline, extension):
187-
baseline_path = os.path.join(self.baseline_dir, baseline)
188-
orig_expected_fname = baseline_path + '.' + extension
189-
if extension == 'eps' and not os.path.exists(orig_expected_fname):
190-
orig_expected_fname = baseline_path + '.pdf'
180+
baseline_path = self.baseline_dir / baseline
181+
orig_expected_path = baseline_path.with_suffix(f'.{extension}')
182+
if extension == 'eps' and not orig_expected_path.exists():
183+
orig_expected_path = orig_expected_path.with_suffix('.pdf')
191184
expected_fname = make_test_filename(
192-
os.path.join(self.result_dir,
193-
os.path.basename(orig_expected_fname)),
194-
'expected')
185+
self.result_dir / orig_expected_path.name, 'expected')
195186
try:
196187
# os.symlink errors if the target already exists.
197188
with contextlib.suppress(OSError):
198189
os.remove(expected_fname)
199190
try:
200-
os.symlink(orig_expected_fname, expected_fname)
191+
os.symlink(orig_expected_path, expected_fname)
201192
except OSError: # On Windows, symlink *may* be unavailable.
202-
shutil.copyfile(orig_expected_fname, expected_fname)
193+
shutil.copyfile(orig_expected_path, expected_fname)
203194
except OSError:
204195
raise ImageComparisonFailure(
205196
f"Missing baseline image {expected_fname} because the "
206-
f"following file cannot be accessed: {orig_expected_fname}")
197+
f"following file cannot be accessed: {orig_expected_path}")
207198
return expected_fname
208199

209200
def compare(self, idx, baseline, extension):
@@ -214,17 +205,16 @@ def compare(self, idx, baseline, extension):
214205
if self.remove_text:
215206
remove_ticks_and_titles(fig)
216207

217-
actual_fname = (
218-
os.path.join(self.result_dir, baseline) + '.' + extension)
208+
actual_path = (self.result_dir / baseline).with_suffix(f'.{extension}')
219209
kwargs = self.savefig_kwargs.copy()
220210
if extension == 'pdf':
221211
kwargs.setdefault('metadata',
222212
{'Creator': None, 'Producer': None,
223213
'CreationDate': None})
224-
fig.savefig(actual_fname, **kwargs)
214+
fig.savefig(actual_path, **kwargs)
225215

226-
expected_fname = self.copy_baseline(baseline, extension)
227-
_raise_on_image_difference(expected_fname, actual_fname, self.tol)
216+
expected_path = self.copy_baseline(baseline, extension)
217+
_raise_on_image_difference(expected_path, actual_path, self.tol)
228218

229219

230220
def _pytest_image_comparison(baseline_images, extensions, tol,
@@ -254,9 +244,8 @@ def decorator(func):
254244
@functools.wraps(func)
255245
def wrapper(*args, **kwargs):
256246
__tracebackhide__ = True
257-
img = _ImageComparisonBase(tol=tol, remove_text=remove_text,
247+
img = _ImageComparisonBase(func, tol=tol, remove_text=remove_text,
258248
savefig_kwargs=savefig_kwargs)
259-
img.delayed_init(func)
260249
matplotlib.testing.set_font_settings_for_testing()
261250
func(*args, **kwargs)
262251

@@ -395,7 +384,7 @@ def test_plot(fig_test, fig_ref):
395384
def decorator(func):
396385
import pytest
397386

398-
_, result_dir = map(Path, _image_directories(func))
387+
_, result_dir = _image_directories(func)
399388

400389
if len(inspect.signature(func).parameters) == 2:
401390
# Free-standing function.
@@ -404,9 +393,8 @@ def wrapper(ext):
404393
fig_test = plt.figure("test")
405394
fig_ref = plt.figure("reference")
406395
func(fig_test, fig_ref)
407-
test_image_path = str(
408-
result_dir / (func.__name__ + "." + ext))
409-
ref_image_path = str(
396+
test_image_path = result_dir / (func.__name__ + "." + ext)
397+
ref_image_path = (
410398
result_dir / (func.__name__ + "-expected." + ext))
411399
fig_test.savefig(test_image_path)
412400
fig_ref.savefig(ref_image_path)
@@ -420,9 +408,8 @@ def wrapper(self, ext):
420408
fig_test = plt.figure("test")
421409
fig_ref = plt.figure("reference")
422410
func(self, fig_test, fig_ref)
423-
test_image_path = str(
424-
result_dir / (func.__name__ + "." + ext))
425-
ref_image_path = str(
411+
test_image_path = result_dir / (func.__name__ + "." + ext)
412+
ref_image_path = (
426413
result_dir / (func.__name__ + "-expected." + ext))
427414
fig_test.savefig(test_image_path)
428415
fig_ref.savefig(ref_image_path)
@@ -447,7 +434,7 @@ def _image_directories(func):
447434
baseline_dir = module_path.parent / "baseline_images" / module_path.stem
448435
result_dir = Path().resolve() / "result_images" / module_path.stem
449436
result_dir.mkdir(parents=True, exist_ok=True)
450-
return str(baseline_dir), str(result_dir)
437+
return baseline_dir, result_dir
451438

452439

453440
@cbook.deprecated("3.1", alternative="pytest.mark.backend")

0 commit comments

Comments
 (0)