From 46614d326cfac8dc0ac6e1a6d5cad25a30d3bae9 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Mon, 27 Aug 2018 20:55:26 -0400 Subject: [PATCH] Backport PR #11896: Resolve backend in rcParams.__getitem__("backend"). --- lib/matplotlib/__init__.py | 40 ++++++++++++++++------ lib/matplotlib/backends/__init__.py | 9 ++--- lib/matplotlib/pyplot.py | 43 +++++++----------------- lib/matplotlib/testing/__init__.py | 2 +- lib/matplotlib/testing/conftest.py | 4 ++- lib/matplotlib/tests/test_backend_svg.py | 2 +- 6 files changed, 49 insertions(+), 51 deletions(-) diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index 3f2a6a300e30..f7b37ee3b612 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -138,7 +138,7 @@ # cbook must import matplotlib only within function # definitions, so it is safe to import from it here. -from . import cbook +from . import cbook, rcsetup from matplotlib.cbook import ( MatplotlibDeprecationWarning, dedent, get_label, sanitize_sequence) from matplotlib.cbook import mplDeprecation # deprecated @@ -853,6 +853,10 @@ def __setitem__(self, key, val): cbook.warn_deprecated( "3.0", "{} is deprecated; in the future, examples will be " "found relative to the 'datapath' directory.".format(key)) + elif key == 'backend': + if val is rcsetup._auto_backend_sentinel: + if 'backend' in self: + return try: cval = self.validate[key](val) except ValueError as ve: @@ -881,6 +885,12 @@ def __getitem__(self, key): "3.0", "{} is deprecated; in the future, examples will be " "found relative to the 'datapath' directory.".format(key)) + elif key == "backend": + val = dict.__getitem__(self, key) + if val is rcsetup._auto_backend_sentinel: + from matplotlib import pyplot as plt + plt.switch_backend(rcsetup._auto_backend_sentinel) + return dict.__getitem__(self, key) def __repr__(self): @@ -1095,10 +1105,10 @@ def rc_params_from_file(fname, fail_on_error=False, use_default_template=True): _fullpath = os.path.join(_basedir, rcParams['examples.directory']) rcParams['examples.directory'] = _fullpath -rcParamsOrig = rcParams.copy() with warnings.catch_warnings(): warnings.simplefilter("ignore", MatplotlibDeprecationWarning) + rcParamsOrig = RcParams(rcParams.copy()) rcParamsDefault = RcParams([(key, default) for key, (default, converter) in defaultParams.items() if key not in _all_deprecated]) @@ -1222,7 +1232,7 @@ def rc_file_defaults(): with warnings.catch_warnings(): warnings.simplefilter("ignore", mplDeprecation) from .style.core import STYLE_BLACKLIST - rcParams.update({k: v for k, v in rcParamsOrig.items() + rcParams.update({k: rcParamsOrig[k] for k in rcParamsOrig if k not in STYLE_BLACKLIST}) @@ -1238,7 +1248,8 @@ def rc_file(fname): with warnings.catch_warnings(): warnings.simplefilter("ignore", mplDeprecation) from .style.core import STYLE_BLACKLIST - rcParams.update({k: v for k, v in rc_params_from_file(fname).items() + rc_from_file = rc_params_from_file(fname) + rcParams.update({k: rc_from_file[k] for k in rc_from_file if k not in STYLE_BLACKLIST}) @@ -1289,16 +1300,23 @@ def __init__(self, rc=None, fname=None): if rc: rcParams.update(rc) except Exception: - # If anything goes wrong, revert to the original rcs. - dict.update(rcParams, self._orig) + self.__fallback() raise + def __fallback(self): + # If anything goes wrong, revert to the original rcs. + updated_backend = self._orig['backend'] + dict.update(rcParams, self._orig) + # except for the backend. If the context block triggered resloving + # the auto backend resolution keep that value around + if self._orig['backend'] is rcsetup._auto_backend_sentinel: + rcParams['backend'] = updated_backend + def __enter__(self): return self def __exit__(self, exc_type, exc_value, exc_tb): - # No need to revalidate the original values. - dict.update(rcParams, self._orig) + self.__fallback() def use(arg, warn=True, force=False): @@ -1324,14 +1342,14 @@ def use(arg, warn=True, force=False): force : bool, optional If True, attempt to switch the backend. This defaults to - false and using `.pyplot.switch_backend` is preferred. + False. """ name = validate_backend(arg) # if setting back to the same thing, do nothing - if (rcParams['backend'] == name): + if (dict.__getitem__(rcParams, 'backend') == name): pass # Check if we have already imported pyplot and triggered @@ -1361,7 +1379,7 @@ def use(arg, warn=True, force=False): if os.environ.get('MPLBACKEND'): - use(os.environ['MPLBACKEND']) + rcParams['backend'] = os.environ.get('MPLBACKEND') def get_backend(): diff --git a/lib/matplotlib/backends/__init__.py b/lib/matplotlib/backends/__init__.py index e4e6082e7d79..01e230df6804 100644 --- a/lib/matplotlib/backends/__init__.py +++ b/lib/matplotlib/backends/__init__.py @@ -10,12 +10,9 @@ _log = logging.getLogger(__name__) -backend = matplotlib.get_backend() -# FIXME: Remove. -_backend_loading_tb = "".join( - line for line in traceback.format_stack() - # Filter out line noise from importlib line. - if not line.startswith(' File "