Skip to content

Commit

Permalink
Fallback to Pure Python if Compilation fails
Browse files Browse the repository at this point in the history
Originally this code attempted to determine if compiling the C ext
would succeed, and if it thought it should, it would then require that
the C extension succeed in order to install. This fails in cases where
the detection code passes, but compiling ultimately fails (one instance
this might happen is if the Python headers are not installed).

Instead of "asking permission", this code will now just attempt to
compile the module, and will fall back to pure Python if that fails,
unless the person has explicitly asked for the C module, in which case
it will still just fail.
  • Loading branch information
dstufft authored and sigmavirus24 committed Sep 12, 2017
1 parent 802c4a6 commit 298e079
Showing 1 changed file with 7 additions and 55 deletions.
62 changes: 7 additions & 55 deletions setup.py
Expand Up @@ -204,63 +204,16 @@ def build_extensions(self):
self.check_extensions_list(self.extensions)
for ext in self.extensions:
with_ext = self.distribution.ext_status(ext)
if with_ext is None:
with_ext = self.check_extension_availability(ext)
if not with_ext:
if with_ext is not None and not with_ext:
continue
if with_cython:
ext.sources = self.cython_sources(ext.sources, ext)
self.build_extension(ext)

def check_extension_availability(self, ext):
cache = os.path.join(self.build_temp, 'check_%s.out' % ext.feature_name)
if not self.force and os.path.isfile(cache):
data = open(cache).read().strip()
if data == '1':
return True
elif data == '0':
return False
mkpath(self.build_temp)
src = os.path.join(self.build_temp, 'check_%s.c' % ext.feature_name)
open(src, 'w').write(ext.feature_check)
log.info("checking if %s is compilable" % ext.feature_name)
try:
[obj] = self.compiler.compile([src],
macros=ext.define_macros+[(undef,) for undef in ext.undef_macros],
include_dirs=ext.include_dirs,
extra_postargs=(ext.extra_compile_args or []),
depends=ext.depends)
except CompileError:
log.warn("")
log.warn("%s is not found or a compiler error: forcing --%s"
% (ext.feature_name, ext.neg_option_name))
log.warn("(if %s is installed correctly, you may need to"
% ext.feature_name)
log.warn(" specify the option --include-dirs or uncomment and")
log.warn(" modify the parameter include_dirs in setup.cfg)")
open(cache, 'w').write('0\n')
return False
prog = 'check_%s' % ext.feature_name
log.info("checking if %s is linkable" % ext.feature_name)
try:
self.compiler.link_executable([obj], prog,
output_dir=self.build_temp,
libraries=ext.libraries,
library_dirs=ext.library_dirs,
runtime_library_dirs=ext.runtime_library_dirs,
extra_postargs=(ext.extra_link_args or []))
except LinkError:
log.warn("")
log.warn("%s is not found or a linker error: forcing --%s"
% (ext.feature_name, ext.neg_option_name))
log.warn("(if %s is installed correctly, you may need to"
% ext.feature_name)
log.warn(" specify the option --library-dirs or uncomment and")
log.warn(" modify the parameter library_dirs in setup.cfg)")
open(cache, 'w').write('0\n')
return False
open(cache, 'w').write('1\n')
return True
try:
self.build_extension(ext)
except (CompileError, LinkError):
if with_ext is not None:
raise
log.warn("Error compiling module, falling back to pure Python")


class bdist_rpm(_bdist_rpm):
Expand Down Expand Up @@ -342,4 +295,3 @@ def run(self):
distclass=Distribution,
cmdclass=cmdclass,
)

0 comments on commit 298e079

Please sign in to comment.