core.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. from __future__ import division, absolute_import, print_function
  2. import sys
  3. from distutils.core import *
  4. if 'setuptools' in sys.modules:
  5. have_setuptools = True
  6. from setuptools import setup as old_setup
  7. # easy_install imports math, it may be picked up from cwd
  8. from setuptools.command import easy_install
  9. try:
  10. # very old versions of setuptools don't have this
  11. from setuptools.command import bdist_egg
  12. except ImportError:
  13. have_setuptools = False
  14. else:
  15. from distutils.core import setup as old_setup
  16. have_setuptools = False
  17. import warnings
  18. import distutils.core
  19. import distutils.dist
  20. from numpy.distutils.extension import Extension
  21. from numpy.distutils.numpy_distribution import NumpyDistribution
  22. from numpy.distutils.command import config, config_compiler, \
  23. build, build_py, build_ext, build_clib, build_src, build_scripts, \
  24. sdist, install_data, install_headers, install, bdist_rpm, \
  25. install_clib
  26. from numpy.distutils.misc_util import get_data_files, is_sequence, is_string
  27. numpy_cmdclass = {'build': build.build,
  28. 'build_src': build_src.build_src,
  29. 'build_scripts': build_scripts.build_scripts,
  30. 'config_cc': config_compiler.config_cc,
  31. 'config_fc': config_compiler.config_fc,
  32. 'config': config.config,
  33. 'build_ext': build_ext.build_ext,
  34. 'build_py': build_py.build_py,
  35. 'build_clib': build_clib.build_clib,
  36. 'sdist': sdist.sdist,
  37. 'install_data': install_data.install_data,
  38. 'install_headers': install_headers.install_headers,
  39. 'install_clib': install_clib.install_clib,
  40. 'install': install.install,
  41. 'bdist_rpm': bdist_rpm.bdist_rpm,
  42. }
  43. if have_setuptools:
  44. # Use our own versions of develop and egg_info to ensure that build_src is
  45. # handled appropriately.
  46. from numpy.distutils.command import develop, egg_info
  47. numpy_cmdclass['bdist_egg'] = bdist_egg.bdist_egg
  48. numpy_cmdclass['develop'] = develop.develop
  49. numpy_cmdclass['easy_install'] = easy_install.easy_install
  50. numpy_cmdclass['egg_info'] = egg_info.egg_info
  51. def _dict_append(d, **kws):
  52. for k, v in kws.items():
  53. if k not in d:
  54. d[k] = v
  55. continue
  56. dv = d[k]
  57. if isinstance(dv, tuple):
  58. d[k] = dv + tuple(v)
  59. elif isinstance(dv, list):
  60. d[k] = dv + list(v)
  61. elif isinstance(dv, dict):
  62. _dict_append(dv, **v)
  63. elif is_string(dv):
  64. d[k] = dv + v
  65. else:
  66. raise TypeError(repr(type(dv)))
  67. def _command_line_ok(_cache=None):
  68. """ Return True if command line does not contain any
  69. help or display requests.
  70. """
  71. if _cache:
  72. return _cache[0]
  73. elif _cache is None:
  74. _cache = []
  75. ok = True
  76. display_opts = ['--'+n for n in Distribution.display_option_names]
  77. for o in Distribution.display_options:
  78. if o[1]:
  79. display_opts.append('-'+o[1])
  80. for arg in sys.argv:
  81. if arg.startswith('--help') or arg=='-h' or arg in display_opts:
  82. ok = False
  83. break
  84. _cache.append(ok)
  85. return ok
  86. def get_distribution(always=False):
  87. dist = distutils.core._setup_distribution
  88. # XXX Hack to get numpy installable with easy_install.
  89. # The problem is easy_install runs it's own setup(), which
  90. # sets up distutils.core._setup_distribution. However,
  91. # when our setup() runs, that gets overwritten and lost.
  92. # We can't use isinstance, as the DistributionWithoutHelpCommands
  93. # class is local to a function in setuptools.command.easy_install
  94. if dist is not None and \
  95. 'DistributionWithoutHelpCommands' in repr(dist):
  96. dist = None
  97. if always and dist is None:
  98. dist = NumpyDistribution()
  99. return dist
  100. def setup(**attr):
  101. cmdclass = numpy_cmdclass.copy()
  102. new_attr = attr.copy()
  103. if 'cmdclass' in new_attr:
  104. cmdclass.update(new_attr['cmdclass'])
  105. new_attr['cmdclass'] = cmdclass
  106. if 'configuration' in new_attr:
  107. # To avoid calling configuration if there are any errors
  108. # or help request in command in the line.
  109. configuration = new_attr.pop('configuration')
  110. old_dist = distutils.core._setup_distribution
  111. old_stop = distutils.core._setup_stop_after
  112. distutils.core._setup_distribution = None
  113. distutils.core._setup_stop_after = "commandline"
  114. try:
  115. dist = setup(**new_attr)
  116. finally:
  117. distutils.core._setup_distribution = old_dist
  118. distutils.core._setup_stop_after = old_stop
  119. if dist.help or not _command_line_ok():
  120. # probably displayed help, skip running any commands
  121. return dist
  122. # create setup dictionary and append to new_attr
  123. config = configuration()
  124. if hasattr(config, 'todict'):
  125. config = config.todict()
  126. _dict_append(new_attr, **config)
  127. # Move extension source libraries to libraries
  128. libraries = []
  129. for ext in new_attr.get('ext_modules', []):
  130. new_libraries = []
  131. for item in ext.libraries:
  132. if is_sequence(item):
  133. lib_name, build_info = item
  134. _check_append_ext_library(libraries, lib_name, build_info)
  135. new_libraries.append(lib_name)
  136. elif is_string(item):
  137. new_libraries.append(item)
  138. else:
  139. raise TypeError("invalid description of extension module "
  140. "library %r" % (item,))
  141. ext.libraries = new_libraries
  142. if libraries:
  143. if 'libraries' not in new_attr:
  144. new_attr['libraries'] = []
  145. for item in libraries:
  146. _check_append_library(new_attr['libraries'], item)
  147. # sources in ext_modules or libraries may contain header files
  148. if ('ext_modules' in new_attr or 'libraries' in new_attr) \
  149. and 'headers' not in new_attr:
  150. new_attr['headers'] = []
  151. # Use our custom NumpyDistribution class instead of distutils' one
  152. new_attr['distclass'] = NumpyDistribution
  153. return old_setup(**new_attr)
  154. def _check_append_library(libraries, item):
  155. for libitem in libraries:
  156. if is_sequence(libitem):
  157. if is_sequence(item):
  158. if item[0]==libitem[0]:
  159. if item[1] is libitem[1]:
  160. return
  161. warnings.warn("[0] libraries list contains %r with"
  162. " different build_info" % (item[0],),
  163. stacklevel=2)
  164. break
  165. else:
  166. if item==libitem[0]:
  167. warnings.warn("[1] libraries list contains %r with"
  168. " no build_info" % (item[0],),
  169. stacklevel=2)
  170. break
  171. else:
  172. if is_sequence(item):
  173. if item[0]==libitem:
  174. warnings.warn("[2] libraries list contains %r with"
  175. " no build_info" % (item[0],),
  176. stacklevel=2)
  177. break
  178. else:
  179. if item==libitem:
  180. return
  181. libraries.append(item)
  182. def _check_append_ext_library(libraries, lib_name, build_info):
  183. for item in libraries:
  184. if is_sequence(item):
  185. if item[0]==lib_name:
  186. if item[1] is build_info:
  187. return
  188. warnings.warn("[3] libraries list contains %r with"
  189. " different build_info" % (lib_name,),
  190. stacklevel=2)
  191. break
  192. elif item==lib_name:
  193. warnings.warn("[4] libraries list contains %r with"
  194. " no build_info" % (lib_name,),
  195. stacklevel=2)
  196. break
  197. libraries.append((lib_name, build_info))