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

Skip to content

Commit adfb193

Browse files
committed
Resolve backend in rcParams.__getitem__("backend").
... to avoid leaking the non-string sentinel. Changes to `backends/__init__` and `_backend_selection()` were necessary to avoid import-time cycles. The fallback order in `backend_fallback` slightly changed in that the FooCairo backends now fallback to WxAgg instead of Wx when a wx event loop is active, but I wouldn't worry too much about it anyways given that the Wx backend is deprecated and the correct fallback would be WxCairo to start with.
1 parent f1b64ad commit adfb193

File tree

5 files changed

+23
-40
lines changed

5 files changed

+23
-40
lines changed

lib/matplotlib/__init__.py

Lines changed: 8 additions & 2 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
@@ -877,6 +877,12 @@ def __getitem__(self, key):
877877
"3.0", "{} is deprecated; in the future, examples will be "
878878
"found relative to the 'datapath' directory.".format(key))
879879

880+
elif key == "backend":
881+
val = dict.__getitem__(self, key)
882+
if val is rcsetup._auto_backend_sentinel:
883+
from matplotlib import pyplot as plt
884+
plt.switch_backend(rcsetup._auto_backend_sentinel)
885+
880886
return dict.__getitem__(self, key)
881887

882888
def __repr__(self):
@@ -1357,7 +1363,7 @@ def use(arg, warn=True, force=False):
13571363

13581364

13591365
if os.environ.get('MPLBACKEND'):
1360-
use(os.environ['MPLBACKEND'])
1366+
rcParams['backend'] = os.environ.get('MPLBACKEND')
13611367

13621368

13631369
def get_backend():

lib/matplotlib/backends/__init__.py

Lines 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

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -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()

lib/matplotlib/testing/__init__.py

Lines 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

Lines changed: 1 addition & 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

0 commit comments

Comments
 (0)