Thrift-386: Make it possible to build the Python library without the extension
Client: py
Patch: Jake Farrell

patch for py lib which will attempt to build the C extension and if it fails falls back to just building the library without any extensions.



git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1206398 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/py/setup.py b/lib/py/setup.py
index 8664b03..5870cd0 100644
--- a/lib/py/setup.py
+++ b/lib/py/setup.py
@@ -19,43 +19,86 @@
 # under the License.
 #
 
+import sys
 try:
     from setuptools import setup, Extension
 except:
-    from distutils.core import setup, Extension
-import sys
+    from distutils.core import setup, Extension, Command
+
+from distutils.command.build_ext import build_ext
+from distutils.errors import CCompilerError, DistutilsExecError, DistutilsPlatformError
 
 include_dirs = []
 if sys.platform == 'win32':
     include_dirs.append('compat/win32')
-fastbinarymod = Extension('thrift.protocol.fastbinary',
-                    sources = ['src/protocol/fastbinary.c'],
+    ext_errors = (CCompilerError, DistutilsExecError, DistutilsPlatformError, IOError)
+else:
+    ext_errors = (CCompilerError, DistutilsExecError, DistutilsPlatformError)
+
+class BuildFailed(Exception):
+    pass
+
+class ve_build_ext(build_ext):
+    def run(self):
+        try:
+            build_ext.run(self)
+        except DistutilsPlatformError, x:
+            raise BuildFailed()
+
+    def build_extension(self, ext):
+        try:
+            build_ext.build_extension(self, ext)
+        except ext_errors, x:
+            raise BuildFailed()
+
+def run_setup(with_binary):
+    if with_binary:
+        extensions = dict(
+            ext_modules = [
+                 Extension('thrift.protocol.fastbinary',
+                       sources = ['src/protocol/fastbinary.c'],
                     include_dirs = include_dirs,
                 )
+            ],
+            cmdclass=dict(build_ext=ve_build_ext)
+        )
+    else:
+        extensions = dict()
+        
+    setup(name = 'thrift',
+        version = '0.8.0-dev',
+        description = 'Python bindings for the Apache Thrift RPC system',
+        author = ['Thrift Developers'],
+        author_email = ['dev@thrift.apache.org'],
+        url = 'http://thrift.apache.org',
+        license = 'Apache License 2.0',
+        packages = [
+            'thrift',
+            'thrift.protocol',
+            'thrift.transport',
+            'thrift.server',
+        ],
+        package_dir = {'thrift' : 'src'},
+        classifiers = [
+            'Development Status :: 5 - Production/Stable',
+            'Environment :: Console',
+            'Intended Audience :: Developers',
+            'Programming Language :: Python',
+            'Programming Language :: Python :: 2',
+            'Topic :: Software Development :: Libraries',
+            'Topic :: System :: Networking'
+        ],
+        **extensions
+    )
 
-setup(name = 'thrift',
-    version = '0.8.0-dev',
-    description = 'Python bindings for the Apache Thrift RPC system',
-    author = ['Thrift Developers'],
-    author_email = ['dev@thrift.apache.org'],
-    url = 'http://thrift.apache.org',
-    license = 'Apache License 2.0',
-    packages = [
-        'thrift',
-        'thrift.protocol',
-        'thrift.transport',
-        'thrift.server',
-    ],
-    package_dir = {'thrift' : 'src'},
-    ext_modules = [fastbinarymod],
-    classifiers=[
-        'Development Status :: 5 - Production/Stable',
-        'Environment :: Console',
-        'Intended Audience :: Developers',
-        'Programming Language :: Python',
-        'Programming Language :: Python :: 2',
-        'Topic :: Software Development :: Libraries',
-        'Topic :: System :: Networking'
-    ]
-)
+try:
+    run_setup(True)
+except BuildFailed:
+    print
+    print '*' * 80
+    print "An error occured while trying to compile with the C extension enabled" 
+    print "Attempting to build without the extension now"
+    print '*' * 80
+    print
 
+    run_setup(False)