]> granicus.if.org Git - python/commitdiff
Merged revisions 70910 via svnmerge from
authorTarek Ziadé <ziade.tarek@gmail.com>
Tue, 31 Mar 2009 22:37:55 +0000 (22:37 +0000)
committerTarek Ziadé <ziade.tarek@gmail.com>
Tue, 31 Mar 2009 22:37:55 +0000 (22:37 +0000)
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r70910 | tarek.ziade | 2009-03-31 17:27:23 -0500 (Tue, 31 Mar 2009) | 1 line

  #5583 Added optional Extensions in Distutils
........

Doc/distutils/setupscript.rst
Lib/distutils/command/build_ext.py
Lib/distutils/extension.py
Lib/distutils/tests/test_build_ext.py
Misc/NEWS

index 2e5d8c17a73edc375168e5e0973550eba688a93f..85089d092ddb39fa6e904c5f5169f3f0ca962c1e 100644 (file)
@@ -334,6 +334,10 @@ Other options
 
 There are still some other options which can be used to handle special cases.
 
+The :option:`optional` option is a boolean; if it is true, that specifies that
+a build failure in the extension should not abort the build process, but simply
+not install the failing extension.
+
 The :option:`extra_objects` option is a list of object files to be passed to the
 linker. These files must not have extensions, as the default extension for the
 compiler is used.
index 1ed69f33c0421430d6d39319323a70daf7950352..229590664c986941be3ccfc834f12fa43cf198ad 100644 (file)
@@ -455,7 +455,13 @@ class build_ext(Command):
         self.check_extensions_list(self.extensions)
 
         for ext in self.extensions:
-            self.build_extension(ext)
+            try:
+                self.build_extension(ext)
+            except (CCompilerError, DistutilsError) as e:
+                if not ext.optional:
+                    raise
+                self.warn('building extension "%s" failed: %s' %
+                          (ext.name, e))
 
     def build_extension(self, ext):
         sources = ext.sources
index b271816844de28f62ecfabf8f5984be107ce4af2..f7e7b4edc9195814e69b2186be56fd6fe96f4010 100644 (file)
@@ -82,6 +82,9 @@ class Extension:
       language : string
         extension language (i.e. "c", "c++", "objc"). Will be detected
         from the source extensions if not provided.
+      optional : boolean
+        specifies that a build failure in the extension should not abort the
+        build process, but simply not install the failing extension.
     """
 
     # When adding arguments to this constructor, be sure to update
@@ -100,6 +103,7 @@ class Extension:
                   swig_opts = None,
                   depends=None,
                   language=None,
+                  optional=None,
                   **kw                      # To catch unknown keywords
                  ):
         assert isinstance(name, str), "'name' must be a string"
@@ -122,6 +126,7 @@ class Extension:
         self.swig_opts = swig_opts or []
         self.depends = depends or []
         self.language = language
+        self.optional = optional
 
         # If there are unknown keyword options, warn about them
         if len(kw):
index 2e47953ee31ff3ab17f8cef7e4a913ba4457a816..094f4b6644c869add6ec5df0a3b090b431a03c70 100644 (file)
@@ -8,6 +8,9 @@ from distutils.core import Extension, Distribution
 from distutils.command.build_ext import build_ext
 from distutils import sysconfig
 from distutils.tests.support import TempdirManager
+from distutils.tests.support import LoggingSilencer
+from distutils.extension import Extension
+from distutils.errors import UnknownFileError
 
 import unittest
 from test import support
@@ -20,7 +23,9 @@ def _get_source_filename():
     srcdir = sysconfig.get_config_var('srcdir')
     return os.path.join(srcdir, 'Modules', 'xxmodule.c')
 
-class BuildExtTestCase(TempdirManager, unittest.TestCase):
+class BuildExtTestCase(TempdirManager,
+                       LoggingSilencer,
+                       unittest.TestCase):
     def setUp(self):
         # Create a simple test environment
         # Note that we're making changes to sys.path
@@ -141,6 +146,22 @@ class BuildExtTestCase(TempdirManager, unittest.TestCase):
         self.assert_(lib in cmd.library_dirs)
         self.assert_(incl in cmd.include_dirs)
 
+    def test_optional_extension(self):
+
+        # this extension will fail, but let's ignore this failure
+        # with the optional argument.
+        modules = [Extension('foo', ['xxx'], optional=False)]
+        dist = Distribution({'name': 'xx', 'ext_modules': modules})
+        cmd = build_ext(dist)
+        cmd.ensure_finalized()
+        self.assertRaises(UnknownFileError, cmd.run)  # should raise an error
+
+        modules = [Extension('foo', ['xxx'], optional=True)]
+        dist = Distribution({'name': 'xx', 'ext_modules': modules})
+        cmd = build_ext(dist)
+        cmd.ensure_finalized()
+        cmd.run()  # should pass
+
 def test_suite():
     src = _get_source_filename()
     if not os.path.exists(src):
index 916a2c9926c2ea9a5b39b22cb74127fa6c4062e5..78adb643225ee2b2d76902045c9dd1b55b673c33 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -282,6 +282,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #5583: Added optional Extensions in Distutils. Initial patch by Georg
+  Brandl.
+
 - Issue #1222: locale.format() bug when the thousands separator is a space
   character.