From 842fb24cb17ee9bfec1348afed11d39a91d73ff6 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Mon, 25 Jan 2021 10:43:49 +0100 Subject: [PATCH] Don't trigger `matplotlib.__getattr__("__version__")` if possible. --- lib/mplcairo/__init__.py | 22 +++++++++++++++++++--- lib/mplcairo/base.py | 5 +++-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/lib/mplcairo/__init__.py b/lib/mplcairo/__init__.py index a8d69fba..a103777a 100644 --- a/lib/mplcairo/__init__.py +++ b/lib/mplcairo/__init__.py @@ -1,8 +1,10 @@ import ast +import functools import os import sys import warnings + try: from ._version import version as __version__ except ImportError: @@ -54,18 +56,32 @@ def _init_options(): _init_options() +@functools.lru_cache(1) +def _get_mpl_version(): + # Don't trigger a git subprocess for Matplotlib's __version__ resolution if + # possible, and cache the result as early versions of importlib.metadata + # are slow. We can't cache get_versions() directly as the result depends + # on whether raqm is loaded. + try: + import importlib.metadata + return importlib.metadata.version("matplotlib") + except ImportError: + # No importlib.metadata on Py<3.8 *or* not-installed Matplotlib. + return matplotlib.__version__ + + def get_versions(): """ Return a mapping indicating the versions of mplcairo and its dependencies. - This function is solely intended to help gather information for bug - reports; its output may change without notice. + This function is intended to help gather information for bug reports, and + not part of the stable API. """ versions = _mplcairo.get_versions() return { "python": sys.version, "mplcairo": __version__, - "matplotlib": matplotlib.__version__, + "matplotlib": _get_mpl_version(), **versions, } diff --git a/lib/mplcairo/base.py b/lib/mplcairo/base.py index fefd11db..cf789361 100644 --- a/lib/mplcairo/base.py +++ b/lib/mplcairo/base.py @@ -22,7 +22,7 @@ from matplotlib.backends import backend_ps from matplotlib.mathtext import MathTextParser -from . import _mplcairo, _util +from . import _mplcairo, _util, get_versions from ._backports import get_glyph_name from ._mplcairo import _StreamSurfaceType @@ -406,7 +406,8 @@ def print_png(self, path_or_stream, *, return metadata = { "Software": - f"matplotlib version {mpl.__version__}, https://matplotlib.org", + f"matplotlib version {get_versions()['matplotlib']}, " + f"https://matplotlib.org", **(metadata if metadata is not None else {}), } if pil_kwargs is None: