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

Skip to content

Commit f1be02c

Browse files
committed
Make image_comparison wrapper match check_figure_equal.
Namely, use signature manipulation, instead of an indirection via fixtures, to add `extension` and `request`. Also, use the closure of `baseline_images`, instead of passing it indirectly by marker.
1 parent 5f3446f commit f1be02c

File tree

1 file changed

+33
-17
lines changed

1 file changed

+33
-17
lines changed

lib/matplotlib/testing/decorators.py

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -227,44 +227,60 @@ def _pytest_image_comparison(baseline_images, extensions, tol,
227227
Decorate function with image comparison for pytest.
228228
229229
This function creates a decorator that wraps a figure-generating function
230-
with image comparison code. Pytest can become confused if we change the
231-
signature of the function, so we indirectly pass anything we need via the
232-
`mpl_image_comparison_parameters` fixture and extra markers.
230+
with image comparison code.
233231
"""
234232
import pytest
235233

236234
extensions = map(_mark_skip_if_format_is_uncomparable, extensions)
235+
KEYWORD_ONLY = inspect.Parameter.KEYWORD_ONLY
237236

238237
def decorator(func):
238+
old_sig = inspect.signature(func)
239+
239240
@functools.wraps(func)
240-
# Parameter indirection; see docstring above and comment below.
241-
@pytest.mark.usefixtures('mpl_image_comparison_parameters')
242241
@pytest.mark.parametrize('extension', extensions)
243-
@pytest.mark.baseline_images(baseline_images)
244-
# END Parameter indirection.
245242
@pytest.mark.style(style)
246243
@_checked_on_freetype_version(freetype_version)
247244
@functools.wraps(func)
248-
def wrapper(*args, **kwargs):
245+
def wrapper(*args, extension, request, **kwargs):
249246
__tracebackhide__ = True
247+
if 'extension' in old_sig.parameters:
248+
kwargs['extension'] = extension
249+
if 'request' in old_sig.parameters:
250+
kwargs['request'] = request
251+
250252
img = _ImageComparisonBase(func, tol=tol, remove_text=remove_text,
251253
savefig_kwargs=savefig_kwargs)
252254
matplotlib.testing.set_font_settings_for_testing()
253255
func(*args, **kwargs)
254256

255-
# Parameter indirection:
256-
# This is hacked on via the mpl_image_comparison_parameters fixture
257-
# so that we don't need to modify the function's real signature for
258-
# any parametrization. Modifying the signature is very very tricky
259-
# and likely to confuse pytest.
260-
baseline_images, extension = func.parameters
257+
if baseline_images is not None:
258+
our_baseline_images = baseline_images
259+
else:
260+
# Allow baseline image list to be produced on the fly based on
261+
# current parametrization.
262+
our_baseline_images = request.getfixturevalue(
263+
'baseline_images')
261264

262-
assert len(plt.get_fignums()) == len(baseline_images), (
265+
assert len(plt.get_fignums()) == len(our_baseline_images), (
263266
"Test generated {} images but there are {} baseline images"
264-
.format(len(plt.get_fignums()), len(baseline_images)))
265-
for idx, baseline in enumerate(baseline_images):
267+
.format(len(plt.get_fignums()), len(our_baseline_images)))
268+
for idx, baseline in enumerate(our_baseline_images):
266269
img.compare(idx, baseline, extension)
267270

271+
parameters = list(old_sig.parameters.values())
272+
if 'extension' not in old_sig.parameters:
273+
parameters += [inspect.Parameter('extension', KEYWORD_ONLY)]
274+
if 'request' not in old_sig.parameters:
275+
parameters += [inspect.Parameter("request", KEYWORD_ONLY)]
276+
new_sig = old_sig.replace(parameters=parameters)
277+
wrapper.__signature__ = new_sig
278+
279+
# Reach a bit into pytest internals to hoist the marks from our wrapped
280+
# function.
281+
new_marks = getattr(func, 'pytestmark', []) + wrapper.pytestmark
282+
wrapper.pytestmark = new_marks
283+
268284
return wrapper
269285

270286
return decorator

0 commit comments

Comments
 (0)