test_install.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. """Tests for distutils.command.install."""
  2. import os
  3. import sys
  4. import unittest
  5. import site
  6. from test.support import captured_stdout, run_unittest
  7. from distutils import sysconfig
  8. from distutils.command.install import install
  9. from distutils.command import install as install_module
  10. from distutils.command.build_ext import build_ext
  11. from distutils.command.install import INSTALL_SCHEMES
  12. from distutils.core import Distribution
  13. from distutils.errors import DistutilsOptionError
  14. from distutils.extension import Extension
  15. from distutils.tests import support
  16. def _make_ext_name(modname):
  17. return modname + sysconfig.get_config_var('EXT_SUFFIX')
  18. class InstallTestCase(support.TempdirManager,
  19. support.EnvironGuard,
  20. support.LoggingSilencer,
  21. unittest.TestCase):
  22. def test_home_installation_scheme(self):
  23. # This ensure two things:
  24. # - that --home generates the desired set of directory names
  25. # - test --home is supported on all platforms
  26. builddir = self.mkdtemp()
  27. destination = os.path.join(builddir, "installation")
  28. dist = Distribution({"name": "foopkg"})
  29. # script_name need not exist, it just need to be initialized
  30. dist.script_name = os.path.join(builddir, "setup.py")
  31. dist.command_obj["build"] = support.DummyCommand(
  32. build_base=builddir,
  33. build_lib=os.path.join(builddir, "lib"),
  34. )
  35. cmd = install(dist)
  36. cmd.home = destination
  37. cmd.ensure_finalized()
  38. self.assertEqual(cmd.install_base, destination)
  39. self.assertEqual(cmd.install_platbase, destination)
  40. def check_path(got, expected):
  41. got = os.path.normpath(got)
  42. expected = os.path.normpath(expected)
  43. self.assertEqual(got, expected)
  44. libdir = os.path.join(destination, "lib", "python")
  45. check_path(cmd.install_lib, libdir)
  46. check_path(cmd.install_platlib, libdir)
  47. check_path(cmd.install_purelib, libdir)
  48. check_path(cmd.install_headers,
  49. os.path.join(destination, "include", "python", "foopkg"))
  50. check_path(cmd.install_scripts, os.path.join(destination, "bin"))
  51. check_path(cmd.install_data, destination)
  52. def test_user_site(self):
  53. # test install with --user
  54. # preparing the environment for the test
  55. self.old_user_base = site.USER_BASE
  56. self.old_user_site = site.USER_SITE
  57. self.tmpdir = self.mkdtemp()
  58. self.user_base = os.path.join(self.tmpdir, 'B')
  59. self.user_site = os.path.join(self.tmpdir, 'S')
  60. site.USER_BASE = self.user_base
  61. site.USER_SITE = self.user_site
  62. install_module.USER_BASE = self.user_base
  63. install_module.USER_SITE = self.user_site
  64. def _expanduser(path):
  65. return self.tmpdir
  66. self.old_expand = os.path.expanduser
  67. os.path.expanduser = _expanduser
  68. def cleanup():
  69. site.USER_BASE = self.old_user_base
  70. site.USER_SITE = self.old_user_site
  71. install_module.USER_BASE = self.old_user_base
  72. install_module.USER_SITE = self.old_user_site
  73. os.path.expanduser = self.old_expand
  74. self.addCleanup(cleanup)
  75. for key in ('nt_user', 'unix_user'):
  76. self.assertIn(key, INSTALL_SCHEMES)
  77. dist = Distribution({'name': 'xx'})
  78. cmd = install(dist)
  79. # making sure the user option is there
  80. options = [name for name, short, lable in
  81. cmd.user_options]
  82. self.assertIn('user', options)
  83. # setting a value
  84. cmd.user = 1
  85. # user base and site shouldn't be created yet
  86. self.assertFalse(os.path.exists(self.user_base))
  87. self.assertFalse(os.path.exists(self.user_site))
  88. # let's run finalize
  89. cmd.ensure_finalized()
  90. # now they should
  91. self.assertTrue(os.path.exists(self.user_base))
  92. self.assertTrue(os.path.exists(self.user_site))
  93. self.assertIn('userbase', cmd.config_vars)
  94. self.assertIn('usersite', cmd.config_vars)
  95. def test_handle_extra_path(self):
  96. dist = Distribution({'name': 'xx', 'extra_path': 'path,dirs'})
  97. cmd = install(dist)
  98. # two elements
  99. cmd.handle_extra_path()
  100. self.assertEqual(cmd.extra_path, ['path', 'dirs'])
  101. self.assertEqual(cmd.extra_dirs, 'dirs')
  102. self.assertEqual(cmd.path_file, 'path')
  103. # one element
  104. cmd.extra_path = ['path']
  105. cmd.handle_extra_path()
  106. self.assertEqual(cmd.extra_path, ['path'])
  107. self.assertEqual(cmd.extra_dirs, 'path')
  108. self.assertEqual(cmd.path_file, 'path')
  109. # none
  110. dist.extra_path = cmd.extra_path = None
  111. cmd.handle_extra_path()
  112. self.assertEqual(cmd.extra_path, None)
  113. self.assertEqual(cmd.extra_dirs, '')
  114. self.assertEqual(cmd.path_file, None)
  115. # three elements (no way !)
  116. cmd.extra_path = 'path,dirs,again'
  117. self.assertRaises(DistutilsOptionError, cmd.handle_extra_path)
  118. def test_finalize_options(self):
  119. dist = Distribution({'name': 'xx'})
  120. cmd = install(dist)
  121. # must supply either prefix/exec-prefix/home or
  122. # install-base/install-platbase -- not both
  123. cmd.prefix = 'prefix'
  124. cmd.install_base = 'base'
  125. self.assertRaises(DistutilsOptionError, cmd.finalize_options)
  126. # must supply either home or prefix/exec-prefix -- not both
  127. cmd.install_base = None
  128. cmd.home = 'home'
  129. self.assertRaises(DistutilsOptionError, cmd.finalize_options)
  130. # can't combine user with prefix/exec_prefix/home or
  131. # install_(plat)base
  132. cmd.prefix = None
  133. cmd.user = 'user'
  134. self.assertRaises(DistutilsOptionError, cmd.finalize_options)
  135. def test_record(self):
  136. install_dir = self.mkdtemp()
  137. project_dir, dist = self.create_dist(py_modules=['hello'],
  138. scripts=['sayhi'])
  139. os.chdir(project_dir)
  140. self.write_file('hello.py', "def main(): print('o hai')")
  141. self.write_file('sayhi', 'from hello import main; main()')
  142. cmd = install(dist)
  143. dist.command_obj['install'] = cmd
  144. cmd.root = install_dir
  145. cmd.record = os.path.join(project_dir, 'filelist')
  146. cmd.ensure_finalized()
  147. cmd.run()
  148. f = open(cmd.record)
  149. try:
  150. content = f.read()
  151. finally:
  152. f.close()
  153. found = [os.path.basename(line) for line in content.splitlines()]
  154. expected = ['hello.py', 'hello.%s.pyc' % sys.implementation.cache_tag,
  155. 'sayhi',
  156. 'UNKNOWN-0.0.0-py%s.%s.egg-info' % sys.version_info[:2]]
  157. self.assertEqual(found, expected)
  158. def test_record_extensions(self):
  159. install_dir = self.mkdtemp()
  160. project_dir, dist = self.create_dist(ext_modules=[
  161. Extension('xx', ['xxmodule.c'])])
  162. os.chdir(project_dir)
  163. support.copy_xxmodule_c(project_dir)
  164. buildextcmd = build_ext(dist)
  165. support.fixup_build_ext(buildextcmd)
  166. buildextcmd.ensure_finalized()
  167. cmd = install(dist)
  168. dist.command_obj['install'] = cmd
  169. dist.command_obj['build_ext'] = buildextcmd
  170. cmd.root = install_dir
  171. cmd.record = os.path.join(project_dir, 'filelist')
  172. cmd.ensure_finalized()
  173. cmd.run()
  174. f = open(cmd.record)
  175. try:
  176. content = f.read()
  177. finally:
  178. f.close()
  179. found = [os.path.basename(line) for line in content.splitlines()]
  180. expected = [_make_ext_name('xx'),
  181. 'UNKNOWN-0.0.0-py%s.%s.egg-info' % sys.version_info[:2]]
  182. self.assertEqual(found, expected)
  183. def test_debug_mode(self):
  184. # this covers the code called when DEBUG is set
  185. old_logs_len = len(self.logs)
  186. install_module.DEBUG = True
  187. try:
  188. with captured_stdout():
  189. self.test_record()
  190. finally:
  191. install_module.DEBUG = False
  192. self.assertGreater(len(self.logs), old_logs_len)
  193. def test_suite():
  194. return unittest.makeSuite(InstallTestCase)
  195. if __name__ == "__main__":
  196. run_unittest(test_suite())