Skip to content

Commit 7bcaa51

Browse files
authored
Merge pull request #7935 from QuLogic/pytest-remove-nose
[MRG+1] Finish removing nose
2 parents ec8cf08 + bbc45cc commit 7bcaa51

20 files changed

+90
-198
lines changed

lib/matplotlib/testing/__init__.py

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,8 @@ def is_called_from_pytest():
2020
return getattr(matplotlib, '_called_from_pytest', False)
2121

2222

23-
def xfail(msg=""):
24-
"""Explicitly fail an currently-executing test with the given message."""
25-
__tracebackhide__ = True
26-
if is_called_from_pytest():
27-
import pytest
28-
pytest.xfail(msg)
29-
else:
30-
from .nose import knownfail
31-
knownfail(msg)
32-
33-
34-
def skip(msg=""):
35-
"""Skip an executing test with the given message."""
36-
__tracebackhide__ = True
37-
if is_called_from_pytest():
38-
import pytest
39-
pytest.skip(msg)
40-
else:
41-
from nose import SkipTest
42-
raise SkipTest(msg)
43-
44-
4523
# stolen from pytest
46-
def getrawcode(obj, trycall=True):
24+
def _getrawcode(obj, trycall=True):
4725
"""Return code object for given function."""
4826
try:
4927
return obj.__code__
@@ -60,7 +38,7 @@ def getrawcode(obj, trycall=True):
6038
return obj
6139

6240

63-
def copy_metadata(src_func, tgt_func):
41+
def _copy_metadata(src_func, tgt_func):
6442
"""Replicates metadata of the function. Returns target function."""
6543
tgt_func.__dict__.update(src_func.__dict__)
6644
tgt_func.__doc__ = src_func.__doc__
@@ -69,7 +47,7 @@ def copy_metadata(src_func, tgt_func):
6947
if hasattr(src_func, '__qualname__'):
7048
tgt_func.__qualname__ = src_func.__qualname__
7149
if not hasattr(tgt_func, 'compat_co_firstlineno'):
72-
tgt_func.compat_co_firstlineno = getrawcode(src_func).co_firstlineno
50+
tgt_func.compat_co_firstlineno = _getrawcode(src_func).co_firstlineno
7351
return tgt_func
7452

7553

lib/matplotlib/testing/_nose/decorators.py

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,50 +4,11 @@
44
import os
55
import six
66
import sys
7-
from .. import copy_metadata, skip
7+
from .. import _copy_metadata
88
from . import knownfail
99
from .exceptions import KnownFailureDidNotFailTest
1010

1111

12-
def skipif(skip_condition, *args, **kwargs):
13-
if isinstance(skip_condition, bool) and 'reason' not in kwargs:
14-
raise ValueError("you need to specify reason=STRING "
15-
"when using booleans as conditions.")
16-
17-
def skip_decorator(func):
18-
import inspect
19-
20-
def skipper(*_args, **_kwargs):
21-
condition, msg = skip_condition, kwargs.get('reason') # local copy
22-
if isinstance(condition, six.string_types):
23-
globs = {'os': os, 'sys': sys}
24-
try:
25-
globs.update(func.__globals__)
26-
except AttributeError:
27-
globs.update(func.func_globals)
28-
if msg is None:
29-
msg = condition
30-
condition = eval(condition, globs)
31-
else:
32-
condition = bool(condition)
33-
34-
if condition:
35-
skip(msg)
36-
else:
37-
return func(*_args, **_kwargs)
38-
39-
if inspect.isclass(func):
40-
setup = getattr(func, 'setup_class', classmethod(lambda _: None))
41-
setup = skip_decorator(setup.__func__)
42-
setup = setup.__get__(func)
43-
setattr(func, 'setup_class', setup)
44-
return func
45-
46-
return copy_metadata(func, skipper)
47-
48-
return skip_decorator
49-
50-
5112
def knownfailureif(fail_condition, msg=None, known_exception_class=None):
5213
# based on numpy.testing.dec.knownfailureif
5314
if msg is None:
@@ -70,5 +31,5 @@ def failer(*args, **kwargs):
7031
if fail_condition and fail_condition != 'indeterminate':
7132
raise KnownFailureDidNotFailTest(msg)
7233
return result
73-
return copy_metadata(f, failer)
34+
return _copy_metadata(f, failer)
7435
return known_fail_decorator

lib/matplotlib/testing/compare.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,14 @@ def convert(filename, cache):
174174
"""
175175
base, extension = filename.rsplit('.', 1)
176176
if extension not in converter:
177-
from nose import SkipTest
178-
raise SkipTest("Don't know how to convert %s files to png" % extension)
177+
reason = "Don't know how to convert %s files to png" % extension
178+
from . import is_called_from_pytest
179+
if is_called_from_pytest():
180+
import pytest
181+
pytest.skip(reason)
182+
else:
183+
from nose import SkipTest
184+
raise SkipTest(reason)
179185
newname = base + '_' + extension + '.png'
180186
if not os.path.exists(filename):
181187
raise IOError("'%s' does not exist" % filename)

lib/matplotlib/testing/decorators.py

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,11 @@
2626
from matplotlib import ft2font
2727
from matplotlib.testing.compare import comparable_formats, compare_images, \
2828
make_test_filename
29-
from . import copy_metadata, is_called_from_pytest, xfail
29+
from . import _copy_metadata, is_called_from_pytest
3030
from .exceptions import ImageComparisonFailure
3131

3232

33-
def skipif(condition, *args, **kwargs):
34-
"""Skip the given test function if eval(condition) results in a True
35-
value.
36-
37-
Optionally specify a reason for better reporting.
38-
"""
39-
if is_called_from_pytest():
40-
import pytest
41-
return pytest.mark.skipif(condition, *args, **kwargs)
42-
else:
43-
from ._nose.decorators import skipif
44-
return skipif(condition, *args, **kwargs)
45-
46-
47-
def knownfailureif(fail_condition, msg=None, known_exception_class=None):
33+
def _knownfailureif(fail_condition, msg=None, known_exception_class=None):
4834
"""
4935
5036
Assume a will fail if *fail_condition* is True. *fail_condition*
@@ -69,6 +55,12 @@ def knownfailureif(fail_condition, msg=None, known_exception_class=None):
6955
return knownfailureif(fail_condition, msg, known_exception_class)
7056

7157

58+
@cbook.deprecated('2.1',
59+
alternative='pytest.xfail or import the plugin')
60+
def knownfailureif(fail_condition, msg=None, known_exception_class=None):
61+
_knownfailureif(fail_condition, msg, known_exception_class)
62+
63+
7264
def _do_cleanup(original_units_registry, original_settings):
7365
plt.close('all')
7466

@@ -175,15 +167,15 @@ def check_freetype_version(ver):
175167
return found >= ver[0] and found <= ver[1]
176168

177169

178-
def checked_on_freetype_version(required_freetype_version):
170+
def _checked_on_freetype_version(required_freetype_version):
179171
if check_freetype_version(required_freetype_version):
180172
return lambda f: f
181173

182174
reason = ("Mismatched version of freetype. "
183175
"Test requires '%s', you have '%s'" %
184176
(required_freetype_version, ft2font.__freetype_version__))
185-
return knownfailureif('indeterminate', msg=reason,
186-
known_exception_class=ImageComparisonFailure)
177+
return _knownfailureif('indeterminate', msg=reason,
178+
known_exception_class=ImageComparisonFailure)
187179

188180

189181
def remove_ticks_and_titles(figure):
@@ -202,7 +194,7 @@ def remove_ticks_and_titles(figure):
202194
pass
203195

204196

205-
def raise_on_image_difference(expected, actual, tol):
197+
def _raise_on_image_difference(expected, actual, tol):
206198
__tracebackhide__ = True
207199

208200
err = compare_images(expected, actual, tol, in_decorator=True)
@@ -216,18 +208,18 @@ def raise_on_image_difference(expected, actual, tol):
216208
'(RMS %(rms).3f)' % err)
217209

218210

219-
def xfail_if_format_is_uncomparable(extension):
211+
def _xfail_if_format_is_uncomparable(extension):
220212
will_fail = extension not in comparable_formats()
221213
if will_fail:
222214
fail_msg = 'Cannot compare %s files on this system' % extension
223215
else:
224216
fail_msg = 'No failure expected'
225217

226-
return knownfailureif(will_fail, fail_msg,
227-
known_exception_class=ImageComparisonFailure)
218+
return _knownfailureif(will_fail, fail_msg,
219+
known_exception_class=ImageComparisonFailure)
228220

229221

230-
def mark_xfail_if_format_is_uncomparable(extension):
222+
def _mark_xfail_if_format_is_uncomparable(extension):
231223
will_fail = extension not in comparable_formats()
232224
if will_fail:
233225
fail_msg = 'Cannot compare %s files on this system' % extension
@@ -284,9 +276,15 @@ def copy_baseline(self, baseline, extension):
284276
if os.path.exists(orig_expected_fname):
285277
shutil.copyfile(orig_expected_fname, expected_fname)
286278
else:
287-
xfail("Do not have baseline image {0} because this "
288-
"file does not exist: {1}".format(expected_fname,
289-
orig_expected_fname))
279+
reason = ("Do not have baseline image {0} because this "
280+
"file does not exist: {1}".format(expected_fname,
281+
orig_expected_fname))
282+
if is_called_from_pytest():
283+
import pytest
284+
pytest.xfail(reason)
285+
else:
286+
from ._nose import knownfail
287+
knownfail(reason)
290288
return expected_fname
291289

292290
def compare(self, idx, baseline, extension):
@@ -306,12 +304,12 @@ def compare(self, idx, baseline, extension):
306304
fig.savefig(actual_fname, **kwargs)
307305

308306
expected_fname = self.copy_baseline(baseline, extension)
309-
raise_on_image_difference(expected_fname, actual_fname, self.tol)
307+
_raise_on_image_difference(expected_fname, actual_fname, self.tol)
310308

311309
def nose_runner(self):
312310
func = self.compare
313-
func = checked_on_freetype_version(self.freetype_version)(func)
314-
funcs = {extension: xfail_if_format_is_uncomparable(extension)(func)
311+
func = _checked_on_freetype_version(self.freetype_version)(func)
312+
funcs = {extension: _xfail_if_format_is_uncomparable(extension)(func)
315313
for extension in self.extensions}
316314
for idx, baseline in enumerate(self.baseline_images):
317315
for extension in self.extensions:
@@ -320,19 +318,20 @@ def nose_runner(self):
320318
def pytest_runner(self):
321319
from pytest import mark
322320

323-
extensions = map(mark_xfail_if_format_is_uncomparable, self.extensions)
321+
extensions = map(_mark_xfail_if_format_is_uncomparable,
322+
self.extensions)
324323

325324
if len(set(self.baseline_images)) == len(self.baseline_images):
326325
@mark.parametrize("extension", extensions)
327326
@mark.parametrize("idx,baseline", enumerate(self.baseline_images))
328-
@checked_on_freetype_version(self.freetype_version)
327+
@_checked_on_freetype_version(self.freetype_version)
329328
def wrapper(idx, baseline, extension):
330329
__tracebackhide__ = True
331330
self.compare(idx, baseline, extension)
332331
else:
333332
# Some baseline images are repeated, so run this in serial.
334333
@mark.parametrize("extension", extensions)
335-
@checked_on_freetype_version(self.freetype_version)
334+
@_checked_on_freetype_version(self.freetype_version)
336335
def wrapper(extension):
337336
__tracebackhide__ = True
338337
for idx, baseline in enumerate(self.baseline_images):
@@ -348,7 +347,7 @@ def wrapper(extension):
348347
def __call__(self, func):
349348
self.delayed_init(func)
350349
if is_called_from_pytest():
351-
return copy_metadata(func, self.pytest_runner())
350+
return _copy_metadata(func, self.pytest_runner())
352351
else:
353352
import nose.tools
354353

@@ -361,7 +360,7 @@ def runner_wrapper():
361360
# nose bug...
362361
self.teardown()
363362

364-
return copy_metadata(func, runner_wrapper)
363+
return _copy_metadata(func, runner_wrapper)
365364

366365

367366
def image_comparison(baseline_images=None, extensions=None, tol=0,
@@ -497,7 +496,7 @@ def backend_switcher(*args, **kwargs):
497496
plt.switch_backend(prev_backend)
498497
return result
499498

500-
return copy_metadata(func, backend_switcher)
499+
return _copy_metadata(func, backend_switcher)
501500
return switch_backend_decorator
502501

503502

@@ -516,6 +515,7 @@ def skip_if_command_unavailable(cmd):
516515
try:
517516
check_output(cmd)
518517
except:
519-
return skipif(True, reason='missing command: %s' % cmd[0])
518+
import pytest
519+
return pytest.mark.skip(reason='missing command: %s' % cmd[0])
520520

521521
return lambda f: f

lib/matplotlib/tests/test_agg.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from matplotlib.image import imread
1212
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
1313
from matplotlib.figure import Figure
14-
from matplotlib.testing import skip
1514
from matplotlib.testing.decorators import cleanup, image_comparison
1615
from matplotlib import pyplot as plt
1716
from matplotlib import collections
@@ -180,9 +179,6 @@ def process_image(self, padded_src, dpi):
180179
t2 = self.offset_filter.process_image(t1, dpi)
181180
return t2
182181

183-
if LooseVersion(np.__version__) < LooseVersion('1.7.0'):
184-
skip('Disabled on Numpy < 1.7.0')
185-
186182
fig = plt.figure()
187183
ax = fig.add_subplot(111)
188184

lib/matplotlib/tests/test_animation.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import matplotlib as mpl
1414
from matplotlib import pyplot as plt
1515
from matplotlib import animation
16-
from matplotlib.testing import xfail, skip
1716
from matplotlib.testing.decorators import cleanup
1817

1918

@@ -121,7 +120,7 @@ def test_save_animation_smoketest(tmpdir, writer, extension):
121120
except AttributeError:
122121
pass
123122
if not animation.writers.is_available(writer):
124-
skip("writer '%s' not available on this system" % writer)
123+
pytest.skip("writer '%s' not available on this system" % writer)
125124
fig, ax = plt.subplots()
126125
line, = ax.plot([], [])
127126

@@ -145,8 +144,8 @@ def animate(i):
145144
try:
146145
anim.save('movie.' + extension, fps=30, writer=writer, bitrate=500)
147146
except UnicodeDecodeError:
148-
xfail("There can be errors in the numpy import stack, "
149-
"see issues #1891 and #2679")
147+
pytest.xfail("There can be errors in the numpy import stack, "
148+
"see issues #1891 and #2679")
150149

151150

152151
@cleanup

lib/matplotlib/tests/test_axes.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
import matplotlib
2323
from matplotlib.testing.decorators import image_comparison, cleanup
24-
from matplotlib.testing import skip
2524
import matplotlib.pyplot as plt
2625
import matplotlib.markers as mmarkers
2726
import matplotlib.patches as mpatches
@@ -90,7 +89,7 @@ def test_formatter_ticker():
9089
def test_formatter_large_small():
9190
# github issue #617, pull #619
9291
if LooseVersion(np.__version__) >= LooseVersion('1.11.0'):
93-
skip("Fall out from a fixed numpy bug")
92+
pytest.skip("Fall out from a fixed numpy bug")
9493
fig, ax = plt.subplots(1)
9594
x = [0.500000001, 0.500000002]
9695
y = [1e64, 1.1e64]

0 commit comments

Comments
 (0)