diff --git a/.flake8 b/.flake8 index 2c48ca999316..f06b760e386a 100644 --- a/.flake8 +++ b/.flake8 @@ -23,7 +23,7 @@ exclude = per-file-ignores = setup.py: E402 - setupext.py: E302, E501 + setupext.py: E501 tools/compare_backend_driver_results.py: E501 tools/subset.py: E221, E231, E251, E261, E302, E501, E701 diff --git a/setup.cfg.template b/setup.cfg.template index 7ccfb7edcbe4..4fed27d31302 100644 --- a/setup.cfg.template +++ b/setup.cfg.template @@ -63,15 +63,9 @@ # behavior # #agg = auto -#cairo = auto -#gtk3agg = auto -#gtk3cairo = auto #macosx = auto -#pyside = auto -#qt4agg = auto #tkagg = auto #windowing = auto -#wxagg = auto [rc_options] # User-configurable options @@ -81,10 +75,9 @@ # # The Agg, Ps, Pdf and SVG backends do not require external dependencies. Do # not choose MacOSX, or TkAgg if you have disabled the relevant extension -# modules. Agg will be used by default. +# modules. The default is determined by fallback. # #backend = Agg -# [package_data] # Package additional files found in the lib/matplotlib directories. diff --git a/setup.py b/setup.py index 6eab9b6b88fd..7e82e94c29c8 100644 --- a/setup.py +++ b/setup.py @@ -70,18 +70,9 @@ setupext.Tests(), setupext.Toolkits_Tests(), 'Optional backend extensions', - # These backends are listed in order of preference, the first - # being the most preferred. The first one that looks like it will - # work will be selected as the default backend. - setupext.BackendMacOSX(), - setupext.BackendQt5(), - setupext.BackendQt4(), - setupext.BackendGtk3Agg(), - setupext.BackendGtk3Cairo(), - setupext.BackendTkAgg(), - setupext.BackendWxAgg(), setupext.BackendAgg(), - setupext.BackendCairo(), + setupext.BackendTkAgg(), + setupext.BackendMacOSX(), setupext.Windowing(), 'Optional package data', setupext.Dlls(), @@ -133,7 +124,6 @@ def run(self): package_dir = {'': 'lib'} install_requires = [] setup_requires = [] - default_backend = None # If the user just queries for information, don't bother figuring out which # packages to build or install. @@ -169,10 +159,6 @@ def run(self): required_failed.append(package) else: good_packages.append(package) - if (isinstance(package, setupext.OptionalBackendPackage) - and package.runtime_check() - and default_backend is None): - default_backend = package.name print_raw('') # Abort if any of the required packages can not be built. @@ -203,14 +189,16 @@ def run(self): setup_requires.extend(package.get_setup_requires()) # Write the default matplotlibrc file - if default_backend is None: - default_backend = 'svg' - if setupext.options['backend']: - default_backend = setupext.options['backend'] with open('matplotlibrc.template') as fd: - template = fd.read() + template_lines = fd.read().splitlines(True) + backend_line_idx, = [ # Also asserts that there is a single such line. + idx for idx, line in enumerate(template_lines) + if line.startswith('#backend ')] + if setupext.options['backend']: + template_lines[backend_line_idx] = ( + 'backend: {}'.format(setupext.options['backend'])) with open('lib/matplotlib/mpl-data/matplotlibrc', 'w') as fd: - fd.write(template) + fd.write(''.join(template_lines)) # Finalize the extension modules so they can get the Numpy include # dirs diff --git a/setupext.py b/setupext.py index 5644bae9dab5..582c7d89c9da 100644 --- a/setupext.py +++ b/setupext.py @@ -384,13 +384,6 @@ def check(self): """ pass - def runtime_check(self): - """ - True if the runtime dependencies of the backend are met. Assumes that - the build-time dependencies are met. - """ - return True - def get_packages(self): """ Get a list of package names to add to the configuration. @@ -1368,10 +1361,6 @@ class BackendTkAgg(OptionalBackendPackage): def check(self): return "installing; run-time loading from Python Tcl / Tk" - def runtime_check(self): - """Checks whether TkAgg runtime dependencies are met.""" - return importlib.util.find_spec("tkinter") is not None - def get_extension(self): sources = [ 'src/_tkagg.cpp' @@ -1391,57 +1380,6 @@ def add_flags(self, ext): ext.libraries.extend(['dl']) -class BackendGtk3Agg(OptionalBackendPackage): - name = "gtk3agg" - - def check_requirements(self): - if not any(map(importlib.util.find_spec, ["cairocffi", "cairo"])): - raise CheckFailed("Requires cairocffi or pycairo to be installed.") - - try: - import gi - except ImportError: - raise CheckFailed("Requires pygobject to be installed.") - - try: - gi.require_version("Gtk", "3.0") - except ValueError: - raise CheckFailed( - "Requires gtk3 development files to be installed.") - except AttributeError: - raise CheckFailed("pygobject version too old.") - - try: - from gi.repository import Gtk, Gdk, GObject - except (ImportError, RuntimeError): - raise CheckFailed("Requires pygobject to be installed.") - - return "version {}.{}.{}".format( - Gtk.get_major_version(), - Gtk.get_minor_version(), - Gtk.get_micro_version()) - - def get_package_data(self): - return {'matplotlib': ['mpl-data/*.glade']} - - -class BackendGtk3Cairo(BackendGtk3Agg): - name = "gtk3cairo" - - -class BackendWxAgg(OptionalBackendPackage): - name = "wxagg" - - def check_requirements(self): - try: - import wx - backend_version = wx.VERSION_STRING - except ImportError: - raise CheckFailed("requires wxPython") - - return "version %s" % backend_version - - class BackendMacOSX(OptionalBackendPackage): name = 'macosx' @@ -1487,174 +1425,6 @@ def get_extension(self): return ext -class BackendQtBase(OptionalBackendPackage): - - def convert_qt_version(self, version): - version = '%x' % version - temp = [] - while len(version) > 0: - version, chunk = version[:-2], version[-2:] - temp.insert(0, str(int(chunk, 16))) - return '.'.join(temp) - - def check_requirements(self): - """ - If PyQt4/PyQt5 is already imported, importing PyQt5/PyQt4 will fail - so we need to test in a subprocess (as for Gtk3). - """ - try: - p = multiprocessing.Pool() - - except: - # Can't do multiprocessing, fall back to normal approach - # (this will fail if importing both PyQt4 and PyQt5). - try: - # Try in-process - msg = self.callback(self) - except RuntimeError: - raise CheckFailed( - "Could not import: are PyQt4 & PyQt5 both installed?") - - else: - # Multiprocessing OK - try: - res = p.map_async(self.callback, [self]) - msg = res.get(timeout=10)[0] - except multiprocessing.TimeoutError: - p.terminate() - # No result returned. Probably hanging, terminate the process. - raise CheckFailed("Check timed out") - except: - # Some other error. - p.close() - raise - else: - # Clean exit - p.close() - finally: - # Tidy up multiprocessing - p.join() - - return msg - - -def backend_pyside_internal_check(self): - try: - from PySide import __version__ - from PySide import QtCore - except ImportError: - raise CheckFailed("PySide not found") - else: - return ("Qt: %s, PySide: %s" % - (QtCore.__version__, __version__)) - - -def backend_pyqt4_internal_check(self): - try: - from PyQt4 import QtCore - except ImportError: - raise CheckFailed("PyQt4 not found") - - try: - qt_version = QtCore.QT_VERSION - pyqt_version_str = QtCore.PYQT_VERSION_STR - except AttributeError: - raise CheckFailed('PyQt4 not correctly imported') - else: - return ("Qt: %s, PyQt: %s" % (self.convert_qt_version(qt_version), pyqt_version_str)) - - -def backend_qt4_internal_check(self): - successes = [] - failures = [] - try: - successes.append(backend_pyside_internal_check(self)) - except CheckFailed as e: - failures.append(str(e)) - - try: - successes.append(backend_pyqt4_internal_check(self)) - except CheckFailed as e: - failures.append(str(e)) - - if len(successes) == 0: - raise CheckFailed('; '.join(failures)) - return '; '.join(successes + failures) - - -class BackendQt4(BackendQtBase): - name = "qt4agg" - - def __init__(self, *args, **kwargs): - BackendQtBase.__init__(self, *args, **kwargs) - self.callback = backend_qt4_internal_check - -def backend_pyside2_internal_check(self): - try: - from PySide2 import __version__ - from PySide2 import QtCore - except ImportError: - raise CheckFailed("PySide2 not found") - else: - return ("Qt: %s, PySide2: %s" % - (QtCore.__version__, __version__)) - -def backend_pyqt5_internal_check(self): - try: - from PyQt5 import QtCore - except ImportError: - raise CheckFailed("PyQt5 not found") - - try: - qt_version = QtCore.QT_VERSION - pyqt_version_str = QtCore.PYQT_VERSION_STR - except AttributeError: - raise CheckFailed('PyQt5 not correctly imported') - else: - return ("Qt: %s, PyQt: %s" % (self.convert_qt_version(qt_version), pyqt_version_str)) - -def backend_qt5_internal_check(self): - successes = [] - failures = [] - try: - successes.append(backend_pyside2_internal_check(self)) - except CheckFailed as e: - failures.append(str(e)) - - try: - successes.append(backend_pyqt5_internal_check(self)) - except CheckFailed as e: - failures.append(str(e)) - - if len(successes) == 0: - raise CheckFailed('; '.join(failures)) - return '; '.join(successes + failures) - -class BackendQt5(BackendQtBase): - name = "qt5agg" - - def __init__(self, *args, **kwargs): - BackendQtBase.__init__(self, *args, **kwargs) - self.callback = backend_qt5_internal_check - - -class BackendCairo(OptionalBackendPackage): - name = "cairo" - - def check_requirements(self): - try: - import cairocffi - except ImportError: - try: - import cairo - except ImportError: - raise CheckFailed("cairocffi or pycairo not found") - else: - return "pycairo version %s" % cairo.version - else: - return "cairocffi version %s" % cairocffi.version - - class OptionalPackageData(OptionalPackage): config_category = "package_data"
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: