Skip to content

Commit 954e84d

Browse files
committed
Propagate changes to backend loading to setup/setupext.
1) Restore the ability to set the default backend from setup.cfg. 2) Remove the backend fallback code. Note that not including `mpl-data/*.glade` in the package data is fine: that file had been removed in 962388f anyways.
1 parent 32ad86f commit 954e84d

File tree

4 files changed

+12
-261
lines changed

4 files changed

+12
-261
lines changed

.flake8

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ exclude =
2323

2424
per-file-ignores =
2525
setup.py: E402
26-
setupext.py: E302, E501
26+
setupext.py: E501
2727

2828
tools/compare_backend_driver_results.py: E501
2929
tools/subset.py: E221, E231, E251, E261, E302, E501, E701

setup.cfg.template

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,9 @@
6363
# behavior
6464
#
6565
#agg = auto
66-
#cairo = auto
67-
#gtk3agg = auto
68-
#gtk3cairo = auto
6966
#macosx = auto
70-
#pyside = auto
71-
#qt4agg = auto
7267
#tkagg = auto
7368
#windowing = auto
74-
#wxagg = auto
7569

7670
[rc_options]
7771
# User-configurable options
@@ -81,10 +75,9 @@
8175
#
8276
# The Agg, Ps, Pdf and SVG backends do not require external dependencies. Do
8377
# not choose MacOSX, or TkAgg if you have disabled the relevant extension
84-
# modules. Agg will be used by default.
78+
# modules. The default is determined by fallback.
8579
#
8680
#backend = Agg
87-
#
8881

8982
[package_data]
9083
# Package additional files found in the lib/matplotlib directories.

setup.py

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,9 @@
7070
setupext.Tests(),
7171
setupext.Toolkits_Tests(),
7272
'Optional backend extensions',
73-
# These backends are listed in order of preference, the first
74-
# being the most preferred. The first one that looks like it will
75-
# work will be selected as the default backend.
76-
setupext.BackendMacOSX(),
77-
setupext.BackendQt5(),
78-
setupext.BackendQt4(),
79-
setupext.BackendGtk3Agg(),
80-
setupext.BackendGtk3Cairo(),
81-
setupext.BackendTkAgg(),
82-
setupext.BackendWxAgg(),
8373
setupext.BackendAgg(),
84-
setupext.BackendCairo(),
74+
setupext.BackendTkAgg(),
75+
setupext.BackendMacOSX(),
8576
setupext.Windowing(),
8677
'Optional package data',
8778
setupext.Dlls(),
@@ -133,7 +124,6 @@ def run(self):
133124
package_dir = {'': 'lib'}
134125
install_requires = []
135126
setup_requires = []
136-
default_backend = None
137127

138128
# If the user just queries for information, don't bother figuring out which
139129
# packages to build or install.
@@ -169,10 +159,6 @@ def run(self):
169159
required_failed.append(package)
170160
else:
171161
good_packages.append(package)
172-
if (isinstance(package, setupext.OptionalBackendPackage)
173-
and package.runtime_check()
174-
and default_backend is None):
175-
default_backend = package.name
176162
print_raw('')
177163

178164
# Abort if any of the required packages can not be built.
@@ -203,14 +189,16 @@ def run(self):
203189
setup_requires.extend(package.get_setup_requires())
204190

205191
# Write the default matplotlibrc file
206-
if default_backend is None:
207-
default_backend = 'svg'
208-
if setupext.options['backend']:
209-
default_backend = setupext.options['backend']
210192
with open('matplotlibrc.template') as fd:
211-
template = fd.read()
193+
template_lines = fd.read().splitlines(True)
194+
backend_line_idx, = [ # Also asserts that there is a single such line.
195+
idx for idx, line in enumerate(template_lines)
196+
if line.startswith('#backend ')]
197+
if setupext.options['backend']:
198+
template_lines[backend_line_idx] = (
199+
'backend: {}'.format(setupext.options['backend']))
212200
with open('lib/matplotlib/mpl-data/matplotlibrc', 'w') as fd:
213-
fd.write(template)
201+
fd.write(''.join(template_lines))
214202

215203
# Finalize the extension modules so they can get the Numpy include
216204
# dirs

setupext.py

Lines changed: 0 additions & 230 deletions
Original file line numberDiff line numberDiff line change
@@ -384,13 +384,6 @@ def check(self):
384384
"""
385385
pass
386386

387-
def runtime_check(self):
388-
"""
389-
True if the runtime dependencies of the backend are met. Assumes that
390-
the build-time dependencies are met.
391-
"""
392-
return True
393-
394387
def get_packages(self):
395388
"""
396389
Get a list of package names to add to the configuration.
@@ -1368,10 +1361,6 @@ class BackendTkAgg(OptionalBackendPackage):
13681361
def check(self):
13691362
return "installing; run-time loading from Python Tcl / Tk"
13701363

1371-
def runtime_check(self):
1372-
"""Checks whether TkAgg runtime dependencies are met."""
1373-
return importlib.util.find_spec("tkinter") is not None
1374-
13751364
def get_extension(self):
13761365
sources = [
13771366
'src/_tkagg.cpp'
@@ -1391,57 +1380,6 @@ def add_flags(self, ext):
13911380
ext.libraries.extend(['dl'])
13921381

13931382

1394-
class BackendGtk3Agg(OptionalBackendPackage):
1395-
name = "gtk3agg"
1396-
1397-
def check_requirements(self):
1398-
if not any(map(importlib.util.find_spec, ["cairocffi", "cairo"])):
1399-
raise CheckFailed("Requires cairocffi or pycairo to be installed.")
1400-
1401-
try:
1402-
import gi
1403-
except ImportError:
1404-
raise CheckFailed("Requires pygobject to be installed.")
1405-
1406-
try:
1407-
gi.require_version("Gtk", "3.0")
1408-
except ValueError:
1409-
raise CheckFailed(
1410-
"Requires gtk3 development files to be installed.")
1411-
except AttributeError:
1412-
raise CheckFailed("pygobject version too old.")
1413-
1414-
try:
1415-
from gi.repository import Gtk, Gdk, GObject
1416-
except (ImportError, RuntimeError):
1417-
raise CheckFailed("Requires pygobject to be installed.")
1418-
1419-
return "version {}.{}.{}".format(
1420-
Gtk.get_major_version(),
1421-
Gtk.get_minor_version(),
1422-
Gtk.get_micro_version())
1423-
1424-
def get_package_data(self):
1425-
return {'matplotlib': ['mpl-data/*.glade']}
1426-
1427-
1428-
class BackendGtk3Cairo(BackendGtk3Agg):
1429-
name = "gtk3cairo"
1430-
1431-
1432-
class BackendWxAgg(OptionalBackendPackage):
1433-
name = "wxagg"
1434-
1435-
def check_requirements(self):
1436-
try:
1437-
import wx
1438-
backend_version = wx.VERSION_STRING
1439-
except ImportError:
1440-
raise CheckFailed("requires wxPython")
1441-
1442-
return "version %s" % backend_version
1443-
1444-
14451383
class BackendMacOSX(OptionalBackendPackage):
14461384
name = 'macosx'
14471385

@@ -1487,174 +1425,6 @@ def get_extension(self):
14871425
return ext
14881426

14891427

1490-
class BackendQtBase(OptionalBackendPackage):
1491-
1492-
def convert_qt_version(self, version):
1493-
version = '%x' % version
1494-
temp = []
1495-
while len(version) > 0:
1496-
version, chunk = version[:-2], version[-2:]
1497-
temp.insert(0, str(int(chunk, 16)))
1498-
return '.'.join(temp)
1499-
1500-
def check_requirements(self):
1501-
"""
1502-
If PyQt4/PyQt5 is already imported, importing PyQt5/PyQt4 will fail
1503-
so we need to test in a subprocess (as for Gtk3).
1504-
"""
1505-
try:
1506-
p = multiprocessing.Pool()
1507-
1508-
except:
1509-
# Can't do multiprocessing, fall back to normal approach
1510-
# (this will fail if importing both PyQt4 and PyQt5).
1511-
try:
1512-
# Try in-process
1513-
msg = self.callback(self)
1514-
except RuntimeError:
1515-
raise CheckFailed(
1516-
"Could not import: are PyQt4 & PyQt5 both installed?")
1517-
1518-
else:
1519-
# Multiprocessing OK
1520-
try:
1521-
res = p.map_async(self.callback, [self])
1522-
msg = res.get(timeout=10)[0]
1523-
except multiprocessing.TimeoutError:
1524-
p.terminate()
1525-
# No result returned. Probably hanging, terminate the process.
1526-
raise CheckFailed("Check timed out")
1527-
except:
1528-
# Some other error.
1529-
p.close()
1530-
raise
1531-
else:
1532-
# Clean exit
1533-
p.close()
1534-
finally:
1535-
# Tidy up multiprocessing
1536-
p.join()
1537-
1538-
return msg
1539-
1540-
1541-
def backend_pyside_internal_check(self):
1542-
try:
1543-
from PySide import __version__
1544-
from PySide import QtCore
1545-
except ImportError:
1546-
raise CheckFailed("PySide not found")
1547-
else:
1548-
return ("Qt: %s, PySide: %s" %
1549-
(QtCore.__version__, __version__))
1550-
1551-
1552-
def backend_pyqt4_internal_check(self):
1553-
try:
1554-
from PyQt4 import QtCore
1555-
except ImportError:
1556-
raise CheckFailed("PyQt4 not found")
1557-
1558-
try:
1559-
qt_version = QtCore.QT_VERSION
1560-
pyqt_version_str = QtCore.PYQT_VERSION_STR
1561-
except AttributeError:
1562-
raise CheckFailed('PyQt4 not correctly imported')
1563-
else:
1564-
return ("Qt: %s, PyQt: %s" % (self.convert_qt_version(qt_version), pyqt_version_str))
1565-
1566-
1567-
def backend_qt4_internal_check(self):
1568-
successes = []
1569-
failures = []
1570-
try:
1571-
successes.append(backend_pyside_internal_check(self))
1572-
except CheckFailed as e:
1573-
failures.append(str(e))
1574-
1575-
try:
1576-
successes.append(backend_pyqt4_internal_check(self))
1577-
except CheckFailed as e:
1578-
failures.append(str(e))
1579-
1580-
if len(successes) == 0:
1581-
raise CheckFailed('; '.join(failures))
1582-
return '; '.join(successes + failures)
1583-
1584-
1585-
class BackendQt4(BackendQtBase):
1586-
name = "qt4agg"
1587-
1588-
def __init__(self, *args, **kwargs):
1589-
BackendQtBase.__init__(self, *args, **kwargs)
1590-
self.callback = backend_qt4_internal_check
1591-
1592-
def backend_pyside2_internal_check(self):
1593-
try:
1594-
from PySide2 import __version__
1595-
from PySide2 import QtCore
1596-
except ImportError:
1597-
raise CheckFailed("PySide2 not found")
1598-
else:
1599-
return ("Qt: %s, PySide2: %s" %
1600-
(QtCore.__version__, __version__))
1601-
1602-
def backend_pyqt5_internal_check(self):
1603-
try:
1604-
from PyQt5 import QtCore
1605-
except ImportError:
1606-
raise CheckFailed("PyQt5 not found")
1607-
1608-
try:
1609-
qt_version = QtCore.QT_VERSION
1610-
pyqt_version_str = QtCore.PYQT_VERSION_STR
1611-
except AttributeError:
1612-
raise CheckFailed('PyQt5 not correctly imported')
1613-
else:
1614-
return ("Qt: %s, PyQt: %s" % (self.convert_qt_version(qt_version), pyqt_version_str))
1615-
1616-
def backend_qt5_internal_check(self):
1617-
successes = []
1618-
failures = []
1619-
try:
1620-
successes.append(backend_pyside2_internal_check(self))
1621-
except CheckFailed as e:
1622-
failures.append(str(e))
1623-
1624-
try:
1625-
successes.append(backend_pyqt5_internal_check(self))
1626-
except CheckFailed as e:
1627-
failures.append(str(e))
1628-
1629-
if len(successes) == 0:
1630-
raise CheckFailed('; '.join(failures))
1631-
return '; '.join(successes + failures)
1632-
1633-
class BackendQt5(BackendQtBase):
1634-
name = "qt5agg"
1635-
1636-
def __init__(self, *args, **kwargs):
1637-
BackendQtBase.__init__(self, *args, **kwargs)
1638-
self.callback = backend_qt5_internal_check
1639-
1640-
1641-
class BackendCairo(OptionalBackendPackage):
1642-
name = "cairo"
1643-
1644-
def check_requirements(self):
1645-
try:
1646-
import cairocffi
1647-
except ImportError:
1648-
try:
1649-
import cairo
1650-
except ImportError:
1651-
raise CheckFailed("cairocffi or pycairo not found")
1652-
else:
1653-
return "pycairo version %s" % cairo.version
1654-
else:
1655-
return "cairocffi version %s" % cairocffi.version
1656-
1657-
16581428
class OptionalPackageData(OptionalPackage):
16591429
config_category = "package_data"
16601430

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy