From a7ad49fcc4540f9f4f0751664e296ed157b69aeb Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Thu, 29 Jun 2017 11:59:36 +0300 Subject: [PATCH] setup.py: use pure-Python implementation as fallback --- setup.py | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 75 insertions(+), 9 deletions(-) diff --git a/setup.py b/setup.py index 9e38b24..947d427 100644 --- a/setup.py +++ b/setup.py @@ -18,11 +18,48 @@ This works with Python 2 and 3, and PyPy. The license is Apache 2.0. """ +import sys try: - from setuptools import setup + from setuptools import setup, Extension except ImportError: from distutils.core import setup + from distutils.extension import Extension + +from distutils.command.build_ext import build_ext +from distutils.errors import CCompilerError, DistutilsExecError, \ + DistutilsPlatformError + + +class BuildFailed(Exception): + pass + +class ve_build_ext(build_ext): + """This class allows C extension building to fail.""" + ext_errors = (CCompilerError, DistutilsExecError, DistutilsPlatformError) + if sys.platform == 'win32' and sys.version_info < (2, 7): + # 2.6's distutils.msvc9compiler can raise an IOError when failing to + # find the compiler + # It can also raise ValueError http://bugs.python.org/issue7511 + ext_errors += (IOError, ValueError) + + def run(self): + try: + build_ext.run(self) + except DistutilsPlatformError: + raise BuildFailed() + + def build_extension(self, ext): + try: + build_ext.build_extension(self, ext) + except self.ext_errors: + raise BuildFailed() + except ValueError: + # this can happen on Windows 64 bit, see Python issue 7511 + if "'path'" in str(sys.exc_info()[1]): # works with Python 2 and 3 + raise BuildFailed() + raise + common = dict( name = 'streql', @@ -49,12 +86,41 @@ ], ) -try: - import __pypy__ - setup(py_modules=['streql'], package_dir={'':'pypy'}, **common) -except ImportError: +def setup_c_extension(): + setup(ext_modules=[Extension("streql", ["streql.c"])], + cmdclass={'build_ext': ve_build_ext}, + **common) + +def setup_pure_python(): + setup(py_modules=['streql'], package_dir={'': 'pypy'}, **common) + + +is_pypy = hasattr(sys, 'pypy_version_info') + +if is_pypy: + setup_pure_python() +else: try: - from setuptools import Extension - except ImportError: - from distutils.extension import Extension - setup(ext_modules = [Extension("streql", ["streql.c"])], **common) + setup_c_extension() + except BuildFailed: + # install the pure-Python version, + # while printing useful output so the user knows what happened + def echo(msg=''): + sys.stdout.write(msg + '\n') + + line = '=' * 74 + build_ext_warning = 'WARNING: The C extensions could not be ' \ + 'compiled; speedups are not enabled.' + + echo(line) + echo(build_ext_warning) + echo('Failure information, if any, is above.') + echo('Retrying the build without the C extension now.') + echo() + + setup_pure_python() + + echo(line) + echo(build_ext_warning) + echo('Plain-Python installation succeeded.') + echo(line)