@@ -438,38 +438,66 @@ def _check_for_pkg_config(self, package, include_file, min_version=None,
438438
439439class OptionalPackage (SetupPackage ):
440440 optional = True
441+ force = False
442+ config_category = "packages"
441443
442444 def get_config (self ):
443- install = True
444- if config is not None :
445- try :
446- install = config .getboolean (
447- 'packages' , self .name )
448- except :
449- pass
450- return install
445+ """
446+ Look at `setup.cfg` and return one of ["auto", True, False] indicating
447+ if the package is at default state ("auto"), forced by the user (True)
448+ or opted-out (False).
449+ """
450+ try :
451+ return config .getboolean (self .config_category , self .name )
452+ except :
453+ return "auto"
451454
452455 def check (self ):
453- self .install = self .get_config ()
454- if not self .install :
455- raise CheckFailed ("skipping due to configuration" )
456- return "installing"
456+ """
457+ Do not override this method!
457458
459+ For custom dependency checks override self.check_requirements().
460+ Two things are checked: Configuration file and requirements.
461+ """
462+ # Check configuration file
463+ conf = self .get_config ()
464+ # Default "auto" state or install forced by user
465+ if conf in [True , 'auto' ]:
466+ message = "installing"
467+ # Set non-optional if user sets `True` in config
468+ if conf is True :
469+ self .optional = False
470+ # Configuration opt-out by user
471+ else :
472+ # Some backend extensions (e.g. Agg) need to be built for certain
473+ # other GUI backends (e.g. TkAgg) even when manually disabled
474+ if self .force is True :
475+ message = "installing forced (config override)"
476+ else :
477+ raise CheckFailed ("skipping due to configuration" )
458478
459- class OptionalBackendPackage (SetupPackage ):
460- optional = True
479+ # Check requirements and add extra information (if any) to message.
480+ # If requirements are not met a CheckFailed should be raised in there.
481+ additional_info = self .check_requirements ()
482+ if additional_info :
483+ message += ", " + additional_info
484+
485+ # No CheckFailed raised until now, return install message.
486+ return message
487+
488+ def check_requirements (self ):
489+ """
490+ Override this method to do custom dependency checks.
491+
492+ - Raise CheckFailed() if requirements are not met.
493+ - Return message with additional information, or an empty string
494+ (or None) for no additional information.
495+ """
496+ return ""
461497
462- def get_config (self ):
463- install = 'auto'
464- if config is not None :
465- try :
466- install = config .getboolean (
467- 'gui_support' , self .name )
468- except :
469- install = 'auto'
470- if install is True :
471- self .optional = False
472- return install
498+
499+ class OptionalBackendPackage (OptionalPackage ):
500+ config_category = "gui_support"
473501
474502
475503class Platform (SetupPackage ):
@@ -1025,16 +1053,6 @@ def get_install_requires(self):
10251053
10261054class BackendAgg (OptionalBackendPackage ):
10271055 name = "agg"
1028- force = False
1029-
1030- def check (self ):
1031- # The Agg backend extension needs to be built even
1032- # for certain GUI backends, such as TkAgg
1033- config = self .get_config ()
1034- if config is False and self .force is False :
1035- raise CheckFailed ("skipping due to configuration" )
1036- else :
1037- return "installing"
10381056
10391057 def get_extension (self ):
10401058 sources = [
@@ -1056,10 +1074,7 @@ class BackendTkAgg(OptionalBackendPackage):
10561074 def __init__ (self ):
10571075 self .tcl_tk_cache = None
10581076
1059- def check (self ):
1060- if self .get_config () is False :
1061- raise CheckFailed ("skipping due to configuration" )
1062-
1077+ def check_requirements (self ):
10631078 try :
10641079 if PY3 :
10651080 import tkinter as Tkinter
@@ -1345,10 +1360,7 @@ def add_flags(self, ext):
13451360class BackendGtk (OptionalBackendPackage ):
13461361 name = "gtk"
13471362
1348- def check (self ):
1349- if self .get_config () is False :
1350- raise CheckFailed ("skipping due to configuration" )
1351-
1363+ def check_requirements (self ):
13521364 try :
13531365 import gtk
13541366 except ImportError :
@@ -1503,7 +1515,7 @@ def backend_gtk3agg_internal_check(x):
15031515class BackendGtk3Agg (OptionalBackendPackage ):
15041516 name = "gtk3agg"
15051517
1506- def check (self ):
1518+ def check_requirements (self ):
15071519 if 'TRAVIS' in os .environ :
15081520 raise CheckFailed ("Can't build with Travis" )
15091521
@@ -1568,7 +1580,7 @@ def backend_gtk3cairo_internal_check(x):
15681580class BackendGtk3Cairo (OptionalBackendPackage ):
15691581 name = "gtk3cairo"
15701582
1571- def check (self ):
1583+ def check_requirements (self ):
15721584 if 'TRAVIS' in os .environ :
15731585 raise CheckFailed ("Can't build with Travis" )
15741586
@@ -1596,7 +1608,7 @@ def get_package_data(self):
15961608class BackendWxAgg (OptionalBackendPackage ):
15971609 name = "wxagg"
15981610
1599- def check (self ):
1611+ def check_requirements (self ):
16001612 try :
16011613 import wxversion
16021614 except ImportError :
@@ -1634,10 +1646,7 @@ def check(self):
16341646class BackendMacOSX (OptionalBackendPackage ):
16351647 name = 'macosx'
16361648
1637- def check (self ):
1638- if self .get_config () is False :
1639- raise CheckFailed ("skipping due to configuration" )
1640-
1649+ def check_requirements (self ):
16411650 if sys .platform != 'darwin' :
16421651 raise CheckFailed ("Mac OS-X only" )
16431652
@@ -1664,7 +1673,7 @@ class Windowing(OptionalBackendPackage):
16641673 """
16651674 name = "windowing"
16661675
1667- def check (self ):
1676+ def check_requirements (self ):
16681677 if sys .platform != 'win32' :
16691678 raise CheckFailed ("Microsoft Windows only" )
16701679 config = self .get_config ()
@@ -1695,7 +1704,7 @@ def convert_qt_version(self, version):
16951704 temp .insert (0 , str (int (chunk , 16 )))
16961705 return '.' .join (temp )
16971706
1698- def check (self ):
1707+ def check_requirements (self ):
16991708 try :
17001709 from PyQt4 import pyqtconfig
17011710 except ImportError :
@@ -1715,7 +1724,7 @@ def check(self):
17151724class BackendPySide (OptionalBackendPackage ):
17161725 name = "pyside"
17171726
1718- def check (self ):
1727+ def check_requirements (self ):
17191728 try :
17201729 from PySide import __version__
17211730 from PySide import QtCore
@@ -1731,7 +1740,7 @@ def check(self):
17311740class BackendCairo (OptionalBackendPackage ):
17321741 name = "cairo"
17331742
1734- def check (self ):
1743+ def check_requirements (self ):
17351744 try :
17361745 import cairo
17371746 except ImportError :
0 commit comments