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