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

Skip to content

Commit 0043d9a

Browse files
authored
Merge pull request #10903 from anntzer/py3testing
Py3fy testing machinery.
2 parents 24f04f9 + bec3ca0 commit 0043d9a

File tree

3 files changed

+30
-59
lines changed

3 files changed

+30
-59
lines changed

lib/matplotlib/testing/__init__.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,6 @@ def is_called_from_pytest():
1010
return getattr(mpl, '_called_from_pytest', False)
1111

1212

13-
def _copy_metadata(src_func, tgt_func):
14-
"""Replicates metadata of the function. Returns target function."""
15-
functools.update_wrapper(tgt_func, src_func)
16-
tgt_func.__wrapped__ = src_func # Python2 compatibility.
17-
return tgt_func
18-
19-
2013
def set_font_settings_for_testing():
2114
mpl.rcParams['font.family'] = 'DejaVu Sans'
2215
mpl.rcParams['text.hinting'] = False

lib/matplotlib/testing/compare.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -181,15 +181,14 @@ def __call__(self, orig, dest):
181181
# reported as a regular exception below).
182182
env.pop("DISPLAY", None) # May already be unset.
183183
# Do not load any user options.
184-
# `os.environ` needs native strings on Py2+Windows.
185-
env[str("INKSCAPE_PROFILE_DIR")] = os.devnull
184+
env["INKSCAPE_PROFILE_DIR"] = os.devnull
186185
# Old versions of Inkscape (0.48.3.1, used on Travis as of now)
187186
# seem to sometimes deadlock when stderr is redirected to a pipe,
188187
# so we redirect it to a temporary file instead. This is not
189188
# necessary anymore as of Inkscape 0.92.1.
190189
self._stderr = TemporaryFile()
191190
self._proc = subprocess.Popen(
192-
[str("inkscape"), "--without-gui", "--shell"],
191+
["inkscape", "--without-gui", "--shell"],
193192
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
194193
stderr=self._stderr, env=env)
195194
if not self._read_to_prompt():
@@ -210,7 +209,7 @@ def fsencode(s):
210209
# slow solution (Inkscape uses `fgets` so it will always stop at a
211210
# newline).
212211
return make_external_conversion_command(lambda old, new: [
213-
str('inkscape'), '-z', old, '--export-png', new])(orig, dest)
212+
'inkscape', '-z', old, '--export-png', new])(orig, dest)
214213
self._proc.stdin.write(orig_b + b" --export-png=" + dest_b + b"\n")
215214
self._proc.stdin.flush()
216215
if not self._read_to_prompt():
@@ -329,8 +328,8 @@ def calculate_rms(expectedImage, actualImage):
329328
"Calculate the per-pixel errors, then compute the root mean square error."
330329
if expectedImage.shape != actualImage.shape:
331330
raise ImageComparisonFailure(
332-
"Image sizes do not match expected size: {0} "
333-
"actual size {1}".format(expectedImage.shape, actualImage.shape))
331+
"Image sizes do not match expected size: {} "
332+
"actual size {}".format(expectedImage.shape, actualImage.shape))
334333
# Convert to float to avoid overflowing finite integer types.
335334
return np.sqrt(((expectedImage - actualImage).astype(float) ** 2).mean())
336335

@@ -361,7 +360,7 @@ def compare_images(expected, actual, tol, in_decorator=False):
361360
--------
362361
img1 = "./baseline/plot.png"
363362
img2 = "./output/plot.png"
364-
compare_images( img1, img2, 0.001 ):
363+
compare_images(img1, img2, 0.001):
365364
366365
"""
367366
if not os.path.exists(actual):
@@ -391,7 +390,7 @@ def compare_images(expected, actual, tol, in_decorator=False):
391390

392391
diff_image = make_test_filename(actual, 'failed-diff')
393392

394-
if tol <= 0.0:
393+
if tol <= 0:
395394
if np.array_equal(expectedImage, actualImage):
396395
return None
397396

@@ -431,8 +430,8 @@ def save_diff_image(expected, actual, output):
431430
actualImage = np.array(actualImage).astype(float)
432431
if expectedImage.shape != actualImage.shape:
433432
raise ImageComparisonFailure(
434-
"Image sizes do not match expected size: {0} "
435-
"actual size {1}".format(expectedImage.shape, actualImage.shape))
433+
"Image sizes do not match expected size: {} "
434+
"actual size {}".format(expectedImage.shape, actualImage.shape))
436435
absDiffImage = np.abs(expectedImage - actualImage)
437436

438437
# expand differences in luminance domain

lib/matplotlib/testing/decorators.py

Lines changed: 21 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from distutils.version import StrictVersion
22
import functools
3-
import inspect
43
import os
54
from pathlib import Path
65
import shutil
@@ -23,7 +22,7 @@
2322
from matplotlib import ft2font
2423
from matplotlib.testing.compare import (
2524
comparable_formats, compare_images, make_test_filename)
26-
from . import _copy_metadata, is_called_from_pytest
25+
from . import is_called_from_pytest
2726
from .exceptions import ImageComparisonFailure
2827

2928

@@ -250,9 +249,9 @@ def copy_baseline(self, baseline, extension):
250249
if os.path.exists(orig_expected_fname):
251250
shutil.copyfile(orig_expected_fname, expected_fname)
252251
else:
253-
reason = ("Do not have baseline image {0} because this "
254-
"file does not exist: {1}".format(expected_fname,
255-
orig_expected_fname))
252+
reason = ("Do not have baseline image {} because this "
253+
"file does not exist: {}".format(expected_fname,
254+
orig_expected_fname))
256255
raise ImageComparisonFailure(reason)
257256
return expected_fname
258257

@@ -327,11 +326,12 @@ def __call__(self, func):
327326
self.delayed_init(func)
328327
import nose.tools
329328

329+
@functools.wraps(func)
330330
@nose.tools.with_setup(self.setup, self.teardown)
331331
def runner_wrapper():
332332
yield from self.nose_runner()
333333

334-
return _copy_metadata(func, runner_wrapper)
334+
return runner_wrapper
335335

336336

337337
def _pytest_image_comparison(baseline_images, extensions, tol,
@@ -350,6 +350,7 @@ def _pytest_image_comparison(baseline_images, extensions, tol,
350350
extensions = map(_mark_xfail_if_format_is_uncomparable, extensions)
351351

352352
def decorator(func):
353+
@functools.wraps(func)
353354
# Parameter indirection; see docstring above and comment below.
354355
@pytest.mark.usefixtures('mpl_image_comparison_parameters')
355356
@pytest.mark.parametrize('extension', extensions)
@@ -379,8 +380,7 @@ def wrapper(*args, **kwargs):
379380
for idx, baseline in enumerate(baseline_images):
380381
img.compare(idx, baseline, extension)
381382

382-
wrapper.__wrapped__ = func # For Python 2.7.
383-
return _copy_metadata(func, wrapper)
383+
return wrapper
384384

385385
return decorator
386386

@@ -408,7 +408,7 @@ def image_comparison(baseline_images, extensions=None, tol=0,
408408
extensions : [ None | list ]
409409
410410
If None, defaults to all supported extensions.
411-
Otherwise, a list of extensions to test. For example ['png','pdf'].
411+
Otherwise, a list of extensions to test, e.g. ``['png', 'pdf']``.
412412
413413
tol : float, optional, default: 0
414414
The RMS threshold above which the test is considered failed.
@@ -464,10 +464,10 @@ def _image_directories(func):
464464
# FIXME: this won't work for nested packages in matplotlib.tests
465465
warnings.warn(
466466
'Test module run as script. Guessing baseline image locations.')
467-
script_name = sys.argv[0]
468-
basedir = os.path.abspath(os.path.dirname(script_name))
469-
subdir = os.path.splitext(os.path.split(script_name)[1])[0]
467+
module_path = Path(sys.argv[0]).resolve()
468+
subdir = module_path.stem
470469
else:
470+
module_path = Path(sys.modules[func.__module__].__file__)
471471
mods = module_name.split('.')
472472
if len(mods) >= 3:
473473
mods.pop(0)
@@ -486,50 +486,29 @@ def _image_directories(func):
486486
"file (can be empty).".format(module_name))
487487
subdir = os.path.join(*mods)
488488

489-
import imp
490-
def find_dotted_module(module_name, path=None):
491-
"""A version of imp which can handle dots in the module name.
492-
As for imp.find_module(), the return value is a 3-element
493-
tuple (file, pathname, description)."""
494-
res = None
495-
for sub_mod in module_name.split('.'):
496-
try:
497-
res = file, path, _ = imp.find_module(sub_mod, path)
498-
path = [path]
499-
if file is not None:
500-
file.close()
501-
except ImportError:
502-
# assume namespace package
503-
path = list(sys.modules[sub_mod].__path__)
504-
res = None, path, None
505-
return res
506-
507-
mod_file = find_dotted_module(func.__module__)[1]
508-
basedir = os.path.dirname(mod_file)
489+
baseline_dir = module_path.parent / 'baseline_images' / subdir
490+
result_dir = Path().resolve() / 'result_images' / subdir
491+
result_dir.mkdir(parents=True, exist_ok=True)
509492

510-
baseline_dir = os.path.join(basedir, 'baseline_images', subdir)
511-
result_dir = os.path.abspath(os.path.join('result_images', subdir))
512-
Path(result_dir).mkdir(parents=True, exist_ok=True)
513-
514-
return baseline_dir, result_dir
493+
return str(baseline_dir), str(result_dir)
515494

516495

517496
def switch_backend(backend):
518-
# Local import to avoid a hard nose dependency and only incur the
519-
# import time overhead at actual test-time.
497+
520498
def switch_backend_decorator(func):
499+
521500
@functools.wraps(func)
522501
def backend_switcher(*args, **kwargs):
523502
try:
524503
prev_backend = mpl.get_backend()
525504
matplotlib.testing.setup()
526505
plt.switch_backend(backend)
527-
result = func(*args, **kwargs)
506+
return func(*args, **kwargs)
528507
finally:
529508
plt.switch_backend(prev_backend)
530-
return result
531509

532-
return _copy_metadata(func, backend_switcher)
510+
return backend_switcher
511+
533512
return switch_backend_decorator
534513

535514

0 commit comments

Comments
 (0)