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