import sys from distutils.core import Distribution if 'setuptools' in sys.modules: have_setuptools = True from setuptools import setup as old_setup # easy_install imports math, it may be picked up from cwd from setuptools.command import easy_install try: # very old versions of setuptools don't have this from setuptools.command import bdist_egg except ImportError: have_setuptools = False else: from distutils.core import setup as old_setup have_setuptools = False import warnings import distutils.core import distutils.dist from numpy.distutils.extension import Extension from numpy.distutils.numpy_distribution import NumpyDistribution from numpy.distutils.command import config, config_compiler, \ build, build_py, build_ext, build_clib, build_src, build_scripts, \ sdist, install_data, install_headers, install, bdist_rpm, \ install_clib from numpy.distutils.misc_util import is_sequence, is_string numpy_cmdclass = {'build': build.build, 'build_src': build_src.build_src, 'build_scripts': build_scripts.build_scripts, 'config_cc': config_compiler.config_cc, 'config_fc': config_compiler.config_fc, 'config': config.config, 'build_ext': build_ext.build_ext, 'build_py': build_py.build_py, 'build_clib': build_clib.build_clib, 'sdist': sdist.sdist, 'install_data': install_data.install_data, 'install_headers': install_headers.install_headers, 'install_clib': install_clib.install_clib, 'install': install.install, 'bdist_rpm': bdist_rpm.bdist_rpm, } if have_setuptools: # Use our own versions of develop and egg_info to ensure that build_src is # handled appropriately. from numpy.distutils.command import develop, egg_info numpy_cmdclass['bdist_egg'] = bdist_egg.bdist_egg numpy_cmdclass['develop'] = develop.develop numpy_cmdclass['easy_install'] = easy_install.easy_install numpy_cmdclass['egg_info'] = egg_info.egg_info def _dict_append(d, **kws): for k, v in kws.items(): if k not in d: d[k] = v continue dv = d[k] if isinstance(dv, tuple): d[k] = dv + tuple(v) elif isinstance(dv, list): d[k] = dv + list(v) elif isinstance(dv, dict): _dict_append(dv, **v) elif is_string(dv): d[k] = dv + v else: raise TypeError(repr(type(dv))) def _command_line_ok(_cache=None): """ Return True if command line does not contain any help or display requests. """ if _cache: return _cache[0] elif _cache is None: _cache = [] ok = True display_opts = ['--'+n for n in Distribution.display_option_names] for o in Distribution.display_options: if o[1]: display_opts.append('-'+o[1]) for arg in sys.argv: if arg.startswith('--help') or arg=='-h' or arg in display_opts: ok = False break _cache.append(ok) return ok def get_distribution(always=False): dist = distutils.core._setup_distribution # XXX Hack to get numpy installable with easy_install. # The problem is easy_install runs it's own setup(), which # sets up distutils.core._setup_distribution. However, # when our setup() runs, that gets overwritten and lost. # We can't use isinstance, as the DistributionWithoutHelpCommands # class is local to a function in setuptools.command.easy_install if dist is not None and \ 'DistributionWithoutHelpCommands' in repr(dist): dist = None if always and dist is None: dist = NumpyDistribution() return dist def setup(**attr): cmdclass = numpy_cmdclass.copy() new_attr = attr.copy() if 'cmdclass' in new_attr: cmdclass.update(new_attr['cmdclass']) new_attr['cmdclass'] = cmdclass if 'configuration' in new_attr: # To avoid calling configuration if there are any errors # or help request in command in the line. configuration = new_attr.pop('configuration') old_dist = distutils.core._setup_distribution old_stop = distutils.core._setup_stop_after distutils.core._setup_distribution = None distutils.core._setup_stop_after = "commandline" try: dist = setup(**new_attr) finally: distutils.core._setup_distribution = old_dist distutils.core._setup_stop_after = old_stop if dist.help or not _command_line_ok(): # probably displayed help, skip running any commands return dist # create setup dictionary and append to new_attr config = configuration() if hasattr(config, 'todict'): config = config.todict() _dict_append(new_attr, **config) # Move extension source libraries to libraries libraries = [] for ext in new_attr.get('ext_modules', []): new_libraries = [] for item in ext.libraries: if is_sequence(item): lib_name, build_info = item _check_append_ext_library(libraries, lib_name, build_info) new_libraries.append(lib_name) elif is_string(item): new_libraries.append(item) else: raise TypeError("invalid description of extension module " "library %r" % (item,)) ext.libraries = new_libraries if libraries: if 'libraries' not in new_attr: new_attr['libraries'] = [] for item in libraries: _check_append_library(new_attr['libraries'], item) # sources in ext_modules or libraries may contain header files if ('ext_modules' in new_attr or 'libraries' in new_attr) \ and 'headers' not in new_attr: new_attr['headers'] = [] # Use our custom NumpyDistribution class instead of distutils' one new_attr['distclass'] = NumpyDistribution return old_setup(**new_attr) def _check_append_library(libraries, item): for libitem in libraries: if is_sequence(libitem): if is_sequence(item): if item[0]==libitem[0]: if item[1] is libitem[1]: return warnings.warn("[0] libraries list contains %r with" " different build_info" % (item[0],), stacklevel=2) break else: if item==libitem[0]: warnings.warn("[1] libraries list contains %r with" " no build_info" % (item[0],), stacklevel=2) break else: if is_sequence(item): if item[0]==libitem: warnings.warn("[2] libraries list contains %r with" " no build_info" % (item[0],), stacklevel=2) break else: if item==libitem: return libraries.append(item) def _check_append_ext_library(libraries, lib_name, build_info): for item in libraries: if is_sequence(item): if item[0]==lib_name: if item[1] is build_info: return warnings.warn("[3] libraries list contains %r with" " different build_info" % (lib_name,), stacklevel=2) break elif item==lib_name: warnings.warn("[4] libraries list contains %r with" " no build_info" % (lib_name,), stacklevel=2) break libraries.append((lib_name, build_info))