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_user'):
|
---|
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())
|
---|