Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 32ad86f

Browse filesBrowse files
authored
Merge pull request #11896 from anntzer/auto-backend-resolution
ENH: Resolve backend in rcParams.__getitem__("backend").
2 parents 9298960 + ad91933 commit 32ad86f
Copy full SHA for 32ad86f

File tree

Expand file treeCollapse file tree

6 files changed

+49
-51
lines changed
Filter options
Expand file treeCollapse file tree

6 files changed

+49
-51
lines changed

‎lib/matplotlib/__init__.py

Copy file name to clipboardExpand all lines: lib/matplotlib/__init__.py
+29-11Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137

138138
# cbook must import matplotlib only within function
139139
# definitions, so it is safe to import from it here.
140-
from . import cbook
140+
from . import cbook, rcsetup
141141
from matplotlib.cbook import (
142142
MatplotlibDeprecationWarning, dedent, get_label, sanitize_sequence)
143143
from matplotlib.cbook import mplDeprecation # deprecated
@@ -849,6 +849,10 @@ def __setitem__(self, key, val):
849849
cbook.warn_deprecated(
850850
"3.0", "{} is deprecated; in the future, examples will be "
851851
"found relative to the 'datapath' directory.".format(key))
852+
elif key == 'backend':
853+
if val is rcsetup._auto_backend_sentinel:
854+
if 'backend' in self:
855+
return
852856
try:
853857
cval = self.validate[key](val)
854858
except ValueError as ve:
@@ -877,6 +881,12 @@ def __getitem__(self, key):
877881
"3.0", "{} is deprecated; in the future, examples will be "
878882
"found relative to the 'datapath' directory.".format(key))
879883

884+
elif key == "backend":
885+
val = dict.__getitem__(self, key)
886+
if val is rcsetup._auto_backend_sentinel:
887+
from matplotlib import pyplot as plt
888+
plt.switch_backend(rcsetup._auto_backend_sentinel)
889+
880890
return dict.__getitem__(self, key)
881891

882892
def __repr__(self):
@@ -1091,10 +1101,10 @@ def rc_params_from_file(fname, fail_on_error=False, use_default_template=True):
10911101
_fullpath = os.path.join(_basedir, rcParams['examples.directory'])
10921102
rcParams['examples.directory'] = _fullpath
10931103

1094-
rcParamsOrig = rcParams.copy()
10951104

10961105
with warnings.catch_warnings():
10971106
warnings.simplefilter("ignore", MatplotlibDeprecationWarning)
1107+
rcParamsOrig = RcParams(rcParams.copy())
10981108
rcParamsDefault = RcParams([(key, default) for key, (default, converter) in
10991109
defaultParams.items()
11001110
if key not in _all_deprecated])
@@ -1218,7 +1228,7 @@ def rc_file_defaults():
12181228
with warnings.catch_warnings():
12191229
warnings.simplefilter("ignore", mplDeprecation)
12201230
from .style.core import STYLE_BLACKLIST
1221-
rcParams.update({k: v for k, v in rcParamsOrig.items()
1231+
rcParams.update({k: rcParamsOrig[k] for k in rcParamsOrig
12221232
if k not in STYLE_BLACKLIST})
12231233

12241234

@@ -1234,7 +1244,8 @@ def rc_file(fname):
12341244
with warnings.catch_warnings():
12351245
warnings.simplefilter("ignore", mplDeprecation)
12361246
from .style.core import STYLE_BLACKLIST
1237-
rcParams.update({k: v for k, v in rc_params_from_file(fname).items()
1247+
rc_from_file = rc_params_from_file(fname)
1248+
rcParams.update({k: rc_from_file[k] for k in rc_from_file
12381249
if k not in STYLE_BLACKLIST})
12391250

12401251

@@ -1285,16 +1296,23 @@ def __init__(self, rc=None, fname=None):
12851296
if rc:
12861297
rcParams.update(rc)
12871298
except Exception:
1288-
# If anything goes wrong, revert to the original rcs.
1289-
dict.update(rcParams, self._orig)
1299+
self.__fallback()
12901300
raise
12911301

1302+
def __fallback(self):
1303+
# If anything goes wrong, revert to the original rcs.
1304+
updated_backend = self._orig['backend']
1305+
dict.update(rcParams, self._orig)
1306+
# except for the backend. If the context block triggered resloving
1307+
# the auto backend resolution keep that value around
1308+
if self._orig['backend'] is rcsetup._auto_backend_sentinel:
1309+
rcParams['backend'] = updated_backend
1310+
12921311
def __enter__(self):
12931312
return self
12941313

12951314
def __exit__(self, exc_type, exc_value, exc_tb):
1296-
# No need to revalidate the original values.
1297-
dict.update(rcParams, self._orig)
1315+
self.__fallback()
12981316

12991317

13001318
def use(arg, warn=True, force=False):
@@ -1320,14 +1338,14 @@ def use(arg, warn=True, force=False):
13201338
13211339
force : bool, optional
13221340
If True, attempt to switch the backend. This defaults to
1323-
false and using `.pyplot.switch_backend` is preferred.
1341+
False.
13241342
13251343
13261344
"""
13271345
name = validate_backend(arg)
13281346

13291347
# if setting back to the same thing, do nothing
1330-
if (rcParams['backend'] == name):
1348+
if (dict.__getitem__(rcParams, 'backend') == name):
13311349
pass
13321350

13331351
# Check if we have already imported pyplot and triggered
@@ -1357,7 +1375,7 @@ def use(arg, warn=True, force=False):
13571375

13581376

13591377
if os.environ.get('MPLBACKEND'):
1360-
use(os.environ['MPLBACKEND'])
1378+
rcParams['backend'] = os.environ.get('MPLBACKEND')
13611379

13621380

13631381
def get_backend():

‎lib/matplotlib/backends/__init__.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backends/__init__.py
+3-6Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,9 @@
1010

1111
_log = logging.getLogger(__name__)
1212

13-
backend = matplotlib.get_backend()
14-
# FIXME: Remove.
15-
_backend_loading_tb = "".join(
16-
line for line in traceback.format_stack()
17-
# Filter out line noise from importlib line.
18-
if not line.startswith(' File "<frozen importlib._bootstrap'))
13+
14+
# NOTE: plt.switch_backend() (called at import time) will add a "backend"
15+
# attribute here for backcompat.
1916

2017

2118
def _get_running_interactive_framework():

‎lib/matplotlib/pyplot.py

Copy file name to clipboardExpand all lines: lib/matplotlib/pyplot.py
+12-31Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
from matplotlib.backend_bases import FigureCanvasBase
4040
from matplotlib.figure import Figure, figaspect
4141
from matplotlib.gridspec import GridSpec
42-
from matplotlib import rcParams, rcParamsDefault, get_backend
42+
from matplotlib import rcParams, rcParamsDefault, get_backend, rcParamsOrig
4343
from matplotlib import rc_context
4444
from matplotlib.rcsetup import interactive_bk as _interactive_bk
4545
from matplotlib.artist import getp, get, Artist
@@ -67,7 +67,7 @@
6767
Locator, IndexLocator, FixedLocator, NullLocator,\
6868
LinearLocator, LogLocator, AutoLocator, MultipleLocator,\
6969
MaxNLocator
70-
from matplotlib.backends import pylab_setup
70+
from matplotlib.backends import pylab_setup, _get_running_interactive_framework
7171

7272
_log = logging.getLogger(__name__)
7373

@@ -78,35 +78,15 @@
7878
# FIXME: Deprecate.
7979
def _backend_selection():
8080
"""
81-
If rcParams['backend_fallback'] is true, check to see if the
82-
current backend is compatible with the current running event loop,
83-
and if not switches to a compatible one.
84-
"""
85-
backend = rcParams['backend']
86-
if not rcParams['backend_fallback'] or backend not in _interactive_bk:
87-
return
88-
is_agg_backend = rcParams['backend'].endswith('Agg')
89-
if 'wx' in sys.modules and backend not in ('WX', 'WXAgg'):
90-
import wx
91-
if wx.App.IsMainLoopRunning():
92-
rcParams['backend'] = 'wx' + 'Agg' * is_agg_backend
93-
elif 'PyQt4.QtCore' in sys.modules and not backend == 'Qt4Agg':
94-
import PyQt4.QtGui
95-
if not PyQt4.QtGui.qApp.startingUp():
96-
# The mainloop is running.
97-
rcParams['backend'] = 'qt4Agg'
98-
elif 'PyQt5.QtCore' in sys.modules and not backend == 'Qt5Agg':
99-
import PyQt5.QtWidgets
100-
if not PyQt5.QtWidgets.qApp.startingUp():
101-
# The mainloop is running.
102-
rcParams['backend'] = 'qt5Agg'
103-
elif 'gtk' in sys.modules and 'gi' in sys.modules:
104-
from gi.repository import GLib
105-
if GLib.MainLoop().is_running():
106-
rcParams['backend'] = 'GTK3Agg'
107-
elif 'Tkinter' in sys.modules and not backend == 'TkAgg':
108-
# import Tkinter
109-
pass # what if anything do we need to do for tkinter?
81+
If rcParams['backend_fallback'] is true, we will check (at backend
82+
load-time) to see if the current backend is compatible with the current
83+
running event loop, and if not switches to a compatible one.
84+
"""
85+
if rcParams["backend_fallback"]:
86+
if (dict.__getitem__(rcParams, "backend") in _interactive_bk
87+
and _get_running_interactive_framework()):
88+
dict.__setitem__(
89+
rcParams, "backend", rcsetup._auto_backend_sentinel)
11090

11191

11292
_backend_selection()
@@ -237,6 +217,7 @@ def switch_backend(newbackend):
237217
except ImportError:
238218
continue
239219
else:
220+
rcParamsOrig['backend'] = candidate
240221
return
241222

242223
backend_name = (

‎lib/matplotlib/testing/__init__.py

Copy file name to clipboardExpand all lines: lib/matplotlib/testing/__init__.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def setup():
3636
"Could not set locale to English/United States. "
3737
"Some date-related tests may fail.")
3838

39-
mpl.use('Agg', warn=False) # use Agg backend for these tests
39+
mpl.use('Agg', force=True, warn=False) # use Agg backend for these tests
4040

4141
with warnings.catch_warnings():
4242
warnings.simplefilter("ignore", MatplotlibDeprecationWarning)

‎lib/matplotlib/testing/conftest.py

Copy file name to clipboardExpand all lines: lib/matplotlib/testing/conftest.py
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99

1010
def pytest_configure(config):
11-
matplotlib.use('agg')
11+
matplotlib.use('agg', force=True)
1212
matplotlib._called_from_pytest = True
1313
matplotlib._init_tests()
1414

@@ -53,6 +53,8 @@ def mpl_test_settings(request):
5353
if backend is not None:
5454
plt.switch_backend(prev_backend)
5555

56+
assert matplotlib.get_backend() == 'agg'
57+
5658

5759
@pytest.fixture
5860
def mpl_image_comparison_parameters(request, extension):

‎lib/matplotlib/tests/test_backend_svg.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_backend_svg.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ def test_determinism(filename, usetex):
139139
[sys.executable, '-R', '-c',
140140
'import matplotlib; '
141141
'matplotlib._called_from_pytest = True; '
142-
'matplotlib.use("svg"); '
142+
'matplotlib.use("svg", force=True); '
143143
'from matplotlib.tests.test_backend_svg '
144144
'import _test_determinism_save;'
145145
'_test_determinism_save(%r, %r)' % (filename, usetex)],

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.