Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make optional backends respect setup.cfg #2331

Merged
merged 7 commits into from Sep 9, 2013
11 changes: 8 additions & 3 deletions setup.cfg.template
Expand Up @@ -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
Expand Down
91 changes: 53 additions & 38 deletions setupext.py
Expand Up @@ -455,18 +455,52 @@ def check(self):

class OptionalBackendPackage(SetupPackage):
optional = True
force = False
install = 'auto'
check = "installing"

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

def check(self):
"""
Do not override this method!

For custom dependency checks override self.check_requirements().
"""
# check configuration file
if self.get_config() in [True, 'auto']:
self.check = "installing"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this message will be ultimately misleading. If setup.cfg is True or auto, but the dependency isn't found, it will read something like installing, gtk not found. I think in that case, the message from check_requirements should just override, but not append to, self.check.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I just looked at it again, and I am kind of arriving at the same logic again (which was there before I made changes, I really only refactored it into two routines):
Looking at setup.py where the package checks are called, any raised CheckFailed Exception drops out of the installation (ignoring any install message assigned in there like "installing") and its Exception message is used exclusively to indicate the reason. Only if check_requirements() properly returns (no raise), this string is appended and the package is assigned for installing in setup.py.

Summary..

  • configuration opt out -> check() raises -> "no [skipping due to configuration]"
  • dependency check fails -> check_requirements() raises -> "no [exception msg as defined in overridden check_requirements()]"
  • normal install -> check_requirements() returns string -> "yes ['installing' + ', ' + custom message by check_requirements()]"
  • install forced -> check_requirements() returns string -> "yes ['installing forced (config override)' + ', ' + custom message by check_requirements()]"

Let me know if I am missing something here..

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)"
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):
Expand Down Expand Up @@ -981,16 +1015,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
# 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 = [
Expand All @@ -1012,10 +1036,7 @@ class BackendTkAgg(OptionalBackendPackage):
def __init__(self):
self.tcl_tk_cache = None

def check(self):
if self.get_config() is False:
raise CheckFailed("skipping due to configuration")

def check_requirements(self):
try:
if sys.version_info[0] < 3:
import Tkinter
Expand Down Expand Up @@ -1301,10 +1322,7 @@ def add_flags(self, ext):
class BackendGtk(OptionalBackendPackage):
name = "gtk"

def check(self):
if self.get_config() is False:
raise CheckFailed("skipping due to configuration")

def check_requirements(self):
try:
import gtk
except ImportError:
Expand Down Expand Up @@ -1457,7 +1475,7 @@ def backend_gtk3agg_internal_check(x):
class BackendGtk3Agg(OptionalBackendPackage):
name = "gtk3agg"

def check(self):
def check_requirements(self):
if 'TRAVIS' in os.environ:
raise CheckFailed("Can't build with Travis")

Expand Down Expand Up @@ -1520,7 +1538,7 @@ def backend_gtk3cairo_internal_check(x):
class BackendGtk3Cairo(OptionalBackendPackage):
name = "gtk3cairo"

def check(self):
def check_requirements(self):
if 'TRAVIS' in os.environ:
raise CheckFailed("Can't build with Travis")

Expand Down Expand Up @@ -1548,7 +1566,7 @@ def get_package_data(self):
class BackendWxAgg(OptionalBackendPackage):
name = "wxagg"

def check(self):
def check_requirements(self):
try:
import wxversion
except ImportError:
Expand Down Expand Up @@ -1586,10 +1604,7 @@ def check(self):
class BackendMacOSX(OptionalBackendPackage):
name = 'macosx'

def check(self):
if self.get_config() is False:
raise CheckFailed("skipping due to configuration")

def check_requirements(self):
if sys.platform != 'darwin':
raise CheckFailed("Mac OS-X only")

Expand All @@ -1616,7 +1631,7 @@ class Windowing(OptionalBackendPackage):
"""
name = "windowing"

def check(self):
def check_requirements(self):
if sys.platform != 'win32':
raise CheckFailed("Microsoft Windows only")
config = self.get_config()
Expand Down Expand Up @@ -1647,7 +1662,7 @@ def convert_qt_version(self, version):
temp.insert(0, str(int(chunk, 16)))
return '.'.join(temp)

def check(self):
def check_requirements(self):
try:
from PyQt4 import pyqtconfig
except ImportError:
Expand All @@ -1665,7 +1680,7 @@ def check(self):
class BackendPySide(OptionalBackendPackage):
name = "pyside"

def check(self):
def check_requirements(self):
try:
from PySide import __version__
from PySide import QtCore
Expand All @@ -1681,7 +1696,7 @@ def check(self):
class BackendCairo(OptionalBackendPackage):
name = "cairo"

def check(self):
def check_requirements(self):
try:
import cairo
except ImportError:
Expand Down