From f453421f31b108eada6e12acb0729c7cebc2f853 Mon Sep 17 00:00:00 2001 From: Tobias Megies Date: Fri, 23 Aug 2013 00:58:42 +0200 Subject: [PATCH 1/7] make all optional backends respect the cfg file --- setupext.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/setupext.py b/setupext.py index 50feab9eb988..d9fdfd1e1e01 100644 --- a/setupext.py +++ b/setupext.py @@ -1458,6 +1458,9 @@ class BackendGtk3Agg(OptionalBackendPackage): name = "gtk3agg" def check(self): + if self.get_config() is False: + raise CheckFailed("skipping due to configuration") + if 'TRAVIS' in os.environ: raise CheckFailed("Can't build with Travis") @@ -1521,6 +1524,9 @@ class BackendGtk3Cairo(OptionalBackendPackage): name = "gtk3cairo" def check(self): + if self.get_config() is False: + raise CheckFailed("skipping due to configuration") + if 'TRAVIS' in os.environ: raise CheckFailed("Can't build with Travis") @@ -1549,6 +1555,9 @@ class BackendWxAgg(OptionalBackendPackage): name = "wxagg" def check(self): + if self.get_config() is False: + raise CheckFailed("skipping due to configuration") + try: import wxversion except ImportError: @@ -1617,6 +1626,9 @@ class Windowing(OptionalBackendPackage): name = "windowing" def check(self): + if self.get_config() is False: + raise CheckFailed("skipping due to configuration") + if sys.platform != 'win32': raise CheckFailed("Microsoft Windows only") config = self.get_config() @@ -1648,6 +1660,9 @@ def convert_qt_version(self, version): return '.'.join(temp) def check(self): + if self.get_config() is False: + raise CheckFailed("skipping due to configuration") + try: from PyQt4 import pyqtconfig except ImportError: @@ -1666,6 +1681,9 @@ class BackendPySide(OptionalBackendPackage): name = "pyside" def check(self): + if self.get_config() is False: + raise CheckFailed("skipping due to configuration") + try: from PySide import __version__ from PySide import QtCore @@ -1682,6 +1700,9 @@ class BackendCairo(OptionalBackendPackage): name = "cairo" def check(self): + if self.get_config() is False: + raise CheckFailed("skipping due to configuration") + try: import cairo except ImportError: From 162cf125649419c9122f697a0e80ee26843387e8 Mon Sep 17 00:00:00 2001 From: Tobias Megies Date: Tue, 27 Aug 2013 00:03:11 +0200 Subject: [PATCH 2/7] cleaning up OptionalBackendPackage a tiny bit - check for `if config is not None` before the try/except/pass adds nothing, just makes it less readable - much clearer to handle of the default value of the `install` variable with the base class and not nested in a try/except of the `get_config` method (and even duplicated outside of the try/except) - the `force` attribute (only used for BackendAgg right now it seems) should also have a more prominent default state in the base class rather than in just one subclass --- setupext.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/setupext.py b/setupext.py index d9fdfd1e1e01..f00f90d71d51 100644 --- a/setupext.py +++ b/setupext.py @@ -455,18 +455,17 @@ def check(self): class OptionalBackendPackage(SetupPackage): optional = True + force = False + install = 'auto' def get_config(self): - install = 'auto' - if config is not None: - try: - install = config.getboolean( - 'gui_support', self.name) - except: - install = 'auto' - if install is True: + try: + self.install = config.getboolean('gui_support', self.name) + except: + pass + if self.install is True: self.optional = False - return install + return self.install class Platform(SetupPackage): @@ -981,7 +980,6 @@ def get_install_requires(self): class BackendAgg(OptionalBackendPackage): name = "agg" - force = False def check(self): # The Agg backend extension needs to be built even From fc759eebe6ce9ff6fbbcaab6e9bb0a6f0381a19e Mon Sep 17 00:00:00 2001 From: Tobias Megies Date: Tue, 27 Aug 2013 00:16:45 +0200 Subject: [PATCH 3/7] move general check() method of optional backend to base class also split up the if/else in 3 branches to show a separate message if an configuration file backend opt-out was overridden by a forced backend install --- setupext.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/setupext.py b/setupext.py index f00f90d71d51..88ef44ba794b 100644 --- a/setupext.py +++ b/setupext.py @@ -467,6 +467,21 @@ def get_config(self): self.optional = False return self.install + def check(self): + """ + This method should be called using super() even when overriding this + method in a base class to check for a opt-out in the config file. + """ + if self.get_config() is True: + return "installing" + else: + # Some backend extensions (e.g. Agg) need to be built for certain + # other GUI backends (e.g. TkAgg) even when manually disabled + if self.force is True: + return "installation is forced (overriding configuration)" + else: + raise CheckFailed("skipping due to configuration") + class Platform(SetupPackage): name = "platform" @@ -981,15 +996,6 @@ def get_install_requires(self): class BackendAgg(OptionalBackendPackage): name = "agg" - def check(self): - # The Agg backend extension needs to be built even - # for certain GUI backends, such as TkAgg - config = self.get_config() - if config is False and self.force is False: - raise CheckFailed("skipping due to configuration") - else: - return "installing" - def get_extension(self): sources = [ "src/mplutils.cpp", From db54c3904b678de506dc7b4e13cf86b7c2fe8092 Mon Sep 17 00:00:00 2001 From: Tobias Megies Date: Tue, 27 Aug 2013 00:20:27 +0200 Subject: [PATCH 4/7] replace checking of configuration of optional backends in overridden check() methods by a super() call --- setupext.py | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/setupext.py b/setupext.py index 88ef44ba794b..3ed91ed82544 100644 --- a/setupext.py +++ b/setupext.py @@ -1017,8 +1017,7 @@ def __init__(self): self.tcl_tk_cache = None def check(self): - if self.get_config() is False: - raise CheckFailed("skipping due to configuration") + super(BackendTkAgg, self).check() try: if sys.version_info[0] < 3: @@ -1306,8 +1305,7 @@ class BackendGtk(OptionalBackendPackage): name = "gtk" def check(self): - if self.get_config() is False: - raise CheckFailed("skipping due to configuration") + super(BackendGtk, self).check() try: import gtk @@ -1462,8 +1460,7 @@ class BackendGtk3Agg(OptionalBackendPackage): name = "gtk3agg" def check(self): - if self.get_config() is False: - raise CheckFailed("skipping due to configuration") + super(BackendGtk3Agg, self).check() if 'TRAVIS' in os.environ: raise CheckFailed("Can't build with Travis") @@ -1528,8 +1525,7 @@ class BackendGtk3Cairo(OptionalBackendPackage): name = "gtk3cairo" def check(self): - if self.get_config() is False: - raise CheckFailed("skipping due to configuration") + super(BackendGtk3Cairo, self).check() if 'TRAVIS' in os.environ: raise CheckFailed("Can't build with Travis") @@ -1559,8 +1555,7 @@ class BackendWxAgg(OptionalBackendPackage): name = "wxagg" def check(self): - if self.get_config() is False: - raise CheckFailed("skipping due to configuration") + super(BackendWxAgg, self).check() try: import wxversion @@ -1600,8 +1595,7 @@ class BackendMacOSX(OptionalBackendPackage): name = 'macosx' def check(self): - if self.get_config() is False: - raise CheckFailed("skipping due to configuration") + super(BackendMacOSX, self).check() if sys.platform != 'darwin': raise CheckFailed("Mac OS-X only") @@ -1630,8 +1624,7 @@ class Windowing(OptionalBackendPackage): name = "windowing" def check(self): - if self.get_config() is False: - raise CheckFailed("skipping due to configuration") + super(Windowing, self).check() if sys.platform != 'win32': raise CheckFailed("Microsoft Windows only") @@ -1664,8 +1657,7 @@ def convert_qt_version(self, version): return '.'.join(temp) def check(self): - if self.get_config() is False: - raise CheckFailed("skipping due to configuration") + super(BackendQt4, self).check() try: from PyQt4 import pyqtconfig @@ -1685,8 +1677,7 @@ class BackendPySide(OptionalBackendPackage): name = "pyside" def check(self): - if self.get_config() is False: - raise CheckFailed("skipping due to configuration") + super(BackendPySide, self).check() try: from PySide import __version__ @@ -1704,8 +1695,7 @@ class BackendCairo(OptionalBackendPackage): name = "cairo" def check(self): - if self.get_config() is False: - raise CheckFailed("skipping due to configuration") + super(BackendCairo, self).check() try: import cairo From a4ac003d3235e21af687d51f5f68eefe93b3028c Mon Sep 17 00:00:00 2001 From: Tobias Megies Date: Tue, 27 Aug 2013 01:39:09 +0200 Subject: [PATCH 5/7] refactoring/separating backend checks for config file/dependencies - config check is handled handled in optional backend base class and calls separate dependency check - dependency check is an empty stub in base class and can be overriden in subclasses --- setupext.py | 70 ++++++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/setupext.py b/setupext.py index 3ed91ed82544..2669e4d9ad14 100644 --- a/setupext.py +++ b/setupext.py @@ -457,6 +457,7 @@ class OptionalBackendPackage(SetupPackage): optional = True force = False install = 'auto' + check = "installing" def get_config(self): try: @@ -469,19 +470,38 @@ def get_config(self): def check(self): """ - This method should be called using super() even when overriding this - method in a base class to check for a opt-out in the config file. + Do not override this method! + + For custom dependency checks override self.check_requirements(). """ - if self.get_config() is True: - return "installing" + # check configuration file + if self.get_config() in [True, 'auto']: + self.check = "installing" else: # Some backend extensions (e.g. Agg) need to be built for certain # other GUI backends (e.g. TkAgg) even when manually disabled if self.force is True: - return "installation is forced (overriding configuration)" + self.check = "installing forced (config override)" else: raise CheckFailed("skipping due to configuration") + # check requirements and add extra information (if any) to message + custom_info = self.check_requirements() + if custom_info: + self.check += ", " + self.check_requirements() + + return self.check + + def check_requirements(self): + """ + Override this method to do custom dependency checks. + + - Raise CheckFailed() if requirements are not met. + - Return message with additional information, or an empty string + (or None) for no additional information. + """ + return "" + class Platform(SetupPackage): name = "platform" @@ -1016,9 +1036,7 @@ class BackendTkAgg(OptionalBackendPackage): def __init__(self): self.tcl_tk_cache = None - def check(self): - super(BackendTkAgg, self).check() - + def check_requirements(self): try: if sys.version_info[0] < 3: import Tkinter @@ -1304,9 +1322,7 @@ def add_flags(self, ext): class BackendGtk(OptionalBackendPackage): name = "gtk" - def check(self): - super(BackendGtk, self).check() - + def check_requirements(self): try: import gtk except ImportError: @@ -1459,9 +1475,7 @@ def backend_gtk3agg_internal_check(x): class BackendGtk3Agg(OptionalBackendPackage): name = "gtk3agg" - def check(self): - super(BackendGtk3Agg, self).check() - + def check_requirements(self): if 'TRAVIS' in os.environ: raise CheckFailed("Can't build with Travis") @@ -1524,9 +1538,7 @@ def backend_gtk3cairo_internal_check(x): class BackendGtk3Cairo(OptionalBackendPackage): name = "gtk3cairo" - def check(self): - super(BackendGtk3Cairo, self).check() - + def check_requirements(self): if 'TRAVIS' in os.environ: raise CheckFailed("Can't build with Travis") @@ -1554,9 +1566,7 @@ def get_package_data(self): class BackendWxAgg(OptionalBackendPackage): name = "wxagg" - def check(self): - super(BackendWxAgg, self).check() - + def check_requirements(self): try: import wxversion except ImportError: @@ -1594,9 +1604,7 @@ def check(self): class BackendMacOSX(OptionalBackendPackage): name = 'macosx' - def check(self): - super(BackendMacOSX, self).check() - + def check_requirements(self): if sys.platform != 'darwin': raise CheckFailed("Mac OS-X only") @@ -1623,9 +1631,7 @@ class Windowing(OptionalBackendPackage): """ name = "windowing" - def check(self): - super(Windowing, self).check() - + def check_requirements(self): if sys.platform != 'win32': raise CheckFailed("Microsoft Windows only") config = self.get_config() @@ -1656,9 +1662,7 @@ def convert_qt_version(self, version): temp.insert(0, str(int(chunk, 16))) return '.'.join(temp) - def check(self): - super(BackendQt4, self).check() - + def check_requirements(self): try: from PyQt4 import pyqtconfig except ImportError: @@ -1676,9 +1680,7 @@ def check(self): class BackendPySide(OptionalBackendPackage): name = "pyside" - def check(self): - super(BackendPySide, self).check() - + def check_requirements(self): try: from PySide import __version__ from PySide import QtCore @@ -1694,9 +1696,7 @@ def check(self): class BackendCairo(OptionalBackendPackage): name = "cairo" - def check(self): - super(BackendCairo, self).check() - + def check_requirements(self): try: import cairo except ImportError: From d3ae52fee77b6a02fb9ca2e3df6781b5c5330441 Mon Sep 17 00:00:00 2001 From: Tobias Megies Date: Tue, 27 Aug 2013 01:50:03 +0200 Subject: [PATCH 6/7] update list of gui backends in config template --- setup.cfg.template | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/setup.cfg.template b/setup.cfg.template index 237a7cd7464a..ba4cde3e9684 100644 --- a/setup.cfg.template +++ b/setup.cfg.template @@ -54,13 +54,18 @@ # otherwise skip silently. This is the default # behavior # +#agg = auto +#cairo = auto #gtk = auto +#gtk3agg = auto +#gtk3cairo = auto #gtkagg = auto -#tkagg = auto #macosx = auto +#pyside = auto +#qt4agg = auto +#tkagg = auto #windowing = auto -#gtk3cairo = auto -#gtk3agg = auto +#wxagg = auto [rc_options] # User-configurable options From 829597beb5a869e86733f348a0472b0f8ef5332f Mon Sep 17 00:00:00 2001 From: Tobias Megies Date: Wed, 4 Sep 2013 00:25:15 +0200 Subject: [PATCH 7/7] refactoring and unifying OptionalPackage and OptionalBackendPackage --- setupext.py | 66 ++++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/setupext.py b/setupext.py index 2669e4d9ad14..8edd6bb83bb3 100644 --- a/setupext.py +++ b/setupext.py @@ -435,62 +435,52 @@ def _check_for_pkg_config(self, package, include_file, min_version=None, class OptionalPackage(SetupPackage): optional = True - - def get_config(self): - install = True - if config is not None: - try: - install = config.getboolean( - 'packages', self.name) - except: - pass - return install - - def check(self): - self.install = self.get_config() - if not self.install: - raise CheckFailed("skipping due to configuration") - return "installing" - - -class OptionalBackendPackage(SetupPackage): - optional = True force = False - install = 'auto' - check = "installing" + config_category = "packages" def get_config(self): + """ + Look at `setup.cfg` and return one of ["auto", True, False] indicating + if the package is at default state ("auto"), forced by the user (True) + or opted-out (False). + """ try: - self.install = config.getboolean('gui_support', self.name) + return config.getboolean(self.config_category, self.name) except: - pass - if self.install is True: - self.optional = False - return self.install + return "auto" def check(self): """ Do not override this method! For custom dependency checks override self.check_requirements(). + Two things are checked: Configuration file and requirements. """ - # check configuration file - if self.get_config() in [True, 'auto']: - self.check = "installing" + # Check configuration file + conf = self.get_config() + # Default "auto" state or install forced by user + if conf in [True, 'auto']: + message = "installing" + # Set non-optional if user sets `True` in config + if conf is True: + self.optional = False + # Configuration opt-out by user else: # Some backend extensions (e.g. Agg) need to be built for certain # other GUI backends (e.g. TkAgg) even when manually disabled if self.force is True: - self.check = "installing forced (config override)" + message = "installing forced (config override)" else: raise CheckFailed("skipping due to configuration") - # check requirements and add extra information (if any) to message - custom_info = self.check_requirements() - if custom_info: - self.check += ", " + self.check_requirements() + # Check requirements and add extra information (if any) to message. + # If requirements are not met a CheckFailed should be raised in there. + additional_info = self.check_requirements() + if additional_info: + message += ", " + additional_info - return self.check + # No CheckFailed raised until now, return install message. + return message def check_requirements(self): """ @@ -503,6 +493,10 @@ def check_requirements(self): return "" +class OptionalBackendPackage(OptionalPackage): + config_category = "gui_support" + + class Platform(SetupPackage): name = "platform"