You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			179 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			179 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Python
		
	
import pytest
 | 
						|
import sys
 | 
						|
import matplotlib
 | 
						|
from matplotlib import _api
 | 
						|
 | 
						|
 | 
						|
def pytest_configure(config):
 | 
						|
    # config is initialized here rather than in pytest.ini so that `pytest
 | 
						|
    # --pyargs matplotlib` (which would not find pytest.ini) works.  The only
 | 
						|
    # entries in pytest.ini set minversion (which is checked earlier),
 | 
						|
    # testpaths/python_files, as they are required to properly find the tests
 | 
						|
    for key, value in [
 | 
						|
        ("markers", "flaky: (Provided by pytest-rerunfailures.)"),
 | 
						|
        ("markers", "timeout: (Provided by pytest-timeout.)"),
 | 
						|
        ("markers", "backend: Set alternate Matplotlib backend temporarily."),
 | 
						|
        ("markers", "baseline_images: Compare output against references."),
 | 
						|
        ("markers", "pytz: Tests that require pytz to be installed."),
 | 
						|
        ("filterwarnings", "error"),
 | 
						|
        ("filterwarnings",
 | 
						|
         "ignore:.*The py23 module has been deprecated:DeprecationWarning"),
 | 
						|
        ("filterwarnings",
 | 
						|
         r"ignore:DynamicImporter.find_spec\(\) not found; "
 | 
						|
         r"falling back to find_module\(\):ImportWarning"),
 | 
						|
    ]:
 | 
						|
        config.addinivalue_line(key, value)
 | 
						|
 | 
						|
    matplotlib.use('agg', force=True)
 | 
						|
    matplotlib._called_from_pytest = True
 | 
						|
    matplotlib._init_tests()
 | 
						|
 | 
						|
 | 
						|
def pytest_unconfigure(config):
 | 
						|
    matplotlib._called_from_pytest = False
 | 
						|
 | 
						|
 | 
						|
@pytest.fixture(autouse=True)
 | 
						|
def mpl_test_settings(request):
 | 
						|
    from matplotlib.testing.decorators import _cleanup_cm
 | 
						|
 | 
						|
    with _cleanup_cm():
 | 
						|
 | 
						|
        backend = None
 | 
						|
        backend_marker = request.node.get_closest_marker('backend')
 | 
						|
        prev_backend = matplotlib.get_backend()
 | 
						|
        if backend_marker is not None:
 | 
						|
            assert len(backend_marker.args) == 1, \
 | 
						|
                "Marker 'backend' must specify 1 backend."
 | 
						|
            backend, = backend_marker.args
 | 
						|
            skip_on_importerror = backend_marker.kwargs.get(
 | 
						|
                'skip_on_importerror', False)
 | 
						|
 | 
						|
            # special case Qt backend importing to avoid conflicts
 | 
						|
            if backend.lower().startswith('qt5'):
 | 
						|
                if any(sys.modules.get(k) for k in ('PyQt4', 'PySide')):
 | 
						|
                    pytest.skip('Qt4 binding already imported')
 | 
						|
 | 
						|
        matplotlib.testing.setup()
 | 
						|
        with _api.suppress_matplotlib_deprecation_warning():
 | 
						|
            if backend is not None:
 | 
						|
                # This import must come after setup() so it doesn't load the
 | 
						|
                # default backend prematurely.
 | 
						|
                import matplotlib.pyplot as plt
 | 
						|
                try:
 | 
						|
                    plt.switch_backend(backend)
 | 
						|
                except ImportError as exc:
 | 
						|
                    # Should only occur for the cairo backend tests, if neither
 | 
						|
                    # pycairo nor cairocffi are installed.
 | 
						|
                    if 'cairo' in backend.lower() or skip_on_importerror:
 | 
						|
                        pytest.skip("Failed to switch to backend "
 | 
						|
                                    f"{backend} ({exc}).")
 | 
						|
                    else:
 | 
						|
                        raise
 | 
						|
            # Default of cleanup and image_comparison too.
 | 
						|
            matplotlib.style.use(["classic", "_classic_test_patch"])
 | 
						|
        try:
 | 
						|
            yield
 | 
						|
        finally:
 | 
						|
            if backend is not None:
 | 
						|
                plt.close("all")
 | 
						|
                matplotlib.use(prev_backend)
 | 
						|
 | 
						|
 | 
						|
@pytest.fixture
 | 
						|
def pd():
 | 
						|
    """
 | 
						|
    Fixture to import and configure pandas. Using this fixture, the test is skipped when
 | 
						|
    pandas is not installed. Use this fixture instead of importing pandas in test files.
 | 
						|
 | 
						|
    Examples
 | 
						|
    --------
 | 
						|
    Request the pandas fixture by passing in ``pd`` as an argument to the test ::
 | 
						|
 | 
						|
        def test_matshow_pandas(pd):
 | 
						|
 | 
						|
            df = pd.DataFrame({'x':[1,2,3], 'y':[4,5,6]})
 | 
						|
            im = plt.figure().subplots().matshow(df)
 | 
						|
            np.testing.assert_array_equal(im.get_array(), df)
 | 
						|
    """
 | 
						|
    pd = pytest.importorskip('pandas')
 | 
						|
    try:
 | 
						|
        from pandas.plotting import (
 | 
						|
            deregister_matplotlib_converters as deregister)
 | 
						|
        deregister()
 | 
						|
    except ImportError:
 | 
						|
        pass
 | 
						|
    return pd
 | 
						|
 | 
						|
 | 
						|
@pytest.fixture
 | 
						|
def xr():
 | 
						|
    """
 | 
						|
    Fixture to import xarray so that the test is skipped when xarray is not installed.
 | 
						|
    Use this fixture instead of importing xrray in test files.
 | 
						|
 | 
						|
    Examples
 | 
						|
    --------
 | 
						|
    Request the xarray fixture by passing in ``xr`` as an argument to the test ::
 | 
						|
 | 
						|
        def test_imshow_xarray(xr):
 | 
						|
 | 
						|
            ds = xr.DataArray(np.random.randn(2, 3))
 | 
						|
            im = plt.figure().subplots().imshow(ds)
 | 
						|
            np.testing.assert_array_equal(im.get_array(), ds)
 | 
						|
    """
 | 
						|
 | 
						|
    xr = pytest.importorskip('xarray')
 | 
						|
    return xr
 | 
						|
 | 
						|
 | 
						|
@pytest.fixture
 | 
						|
def text_placeholders(monkeypatch):
 | 
						|
    """
 | 
						|
    Replace texts with placeholder rectangles.
 | 
						|
 | 
						|
    The rectangle size only depends on the font size and the number of characters. It is
 | 
						|
    thus insensitive to font properties and rendering details. This should be used for
 | 
						|
    tests that depend on text geometries but not the actual text rendering, e.g. layout
 | 
						|
    tests.
 | 
						|
    """
 | 
						|
    from matplotlib.patches import Rectangle
 | 
						|
 | 
						|
    def patched_get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi):
 | 
						|
        """
 | 
						|
        Replace ``_get_text_metrics_with_cache`` with fixed results.
 | 
						|
 | 
						|
        The usual ``renderer.get_text_width_height_descent`` would depend on font
 | 
						|
        metrics; instead the fixed results are based on font size and the length of the
 | 
						|
        string only.
 | 
						|
        """
 | 
						|
        # While get_window_extent returns pixels and font size is in points, font size
 | 
						|
        # includes ascenders and descenders. Leaving out this factor and setting
 | 
						|
        # descent=0 ends up with a box that is relatively close to DejaVu Sans.
 | 
						|
        height = fontprop.get_size()
 | 
						|
        width = len(text) * height / 1.618  # Golden ratio for character size.
 | 
						|
        descent = 0
 | 
						|
        return width, height, descent
 | 
						|
 | 
						|
    def patched_text_draw(self, renderer):
 | 
						|
        """
 | 
						|
        Replace ``Text.draw`` with a fixed bounding box Rectangle.
 | 
						|
 | 
						|
        The bounding box corresponds to ``Text.get_window_extent``, which ultimately
 | 
						|
        depends on the above patched ``_get_text_metrics_with_cache``.
 | 
						|
        """
 | 
						|
        if renderer is not None:
 | 
						|
            self._renderer = renderer
 | 
						|
        if not self.get_visible():
 | 
						|
            return
 | 
						|
        if self.get_text() == '':
 | 
						|
            return
 | 
						|
        bbox = self.get_window_extent()
 | 
						|
        rect = Rectangle(bbox.p0, bbox.width, bbox.height,
 | 
						|
                         facecolor=self.get_color(), edgecolor='none')
 | 
						|
        rect.draw(renderer)
 | 
						|
 | 
						|
    monkeypatch.setattr('matplotlib.text._get_text_metrics_with_cache',
 | 
						|
                        patched_get_text_metrics_with_cache)
 | 
						|
    monkeypatch.setattr('matplotlib.text.Text.draw', patched_text_draw)
 |