1 # Tests command line execution of scripts
15 verbose
= test
.support
.verbose
17 # XXX ncoghlan: Should we consider moving these to support?
18 from test
.test_cmd_line
import _spawn_python
, _kill_python
20 def _run_python(*args
):
22 p
= _spawn_python(*args
)
24 p
= _spawn_python('-O', *args
)
25 stdout_data
= _kill_python(p
)
26 return p
.wait(), stdout_data
.decode()
28 @contextlib.contextmanager
30 dirname
= tempfile
.mkdtemp()
31 dirname
= os
.path
.realpath(dirname
)
35 shutil
.rmtree(dirname
)
38 # Script may be run with optimisation enabled, so don't rely on assert
39 # statements being executed
40 def assertEqual(lhs, rhs):
42 raise AssertionError('%r != %r' % (lhs, rhs))
43 def assertIdentical(lhs, rhs):
45 raise AssertionError('%r is not %r' % (lhs, rhs))
46 # Check basic code execution
47 result = ['Top level assignment']
49 result.append('Lower level reference')
51 assertEqual(result, ['Top level assignment', 'Lower level reference'])
52 # Check population of magic variables
53 assertEqual(__name__, '__main__')
54 print('__file__==%r' % __file__)
55 print('__package__==%r' % __package__)
56 # Check the sys module
58 assertIdentical(globals(), sys.modules[__name__].__dict__)
59 print('sys.argv[0]==%r' % sys.argv[0])
62 def _make_test_script(script_dir
, script_basename
, source
=test_source
):
63 script_filename
= script_basename
+os
.path
.extsep
+'py'
64 script_name
= os
.path
.join(script_dir
, script_filename
)
65 script_file
= open(script_name
, 'w')
66 script_file
.write(source
)
70 def _compile_test_script(script_name
):
71 py_compile
.compile(script_name
, doraise
=True)
73 compiled_name
= script_name
+ 'c'
75 compiled_name
= script_name
+ 'o'
78 def _make_test_zip(zip_dir
, zip_basename
, script_name
, name_in_zip
=None):
79 zip_filename
= zip_basename
+os
.path
.extsep
+"zip"
80 zip_name
= os
.path
.join(zip_dir
, zip_filename
)
81 zip_file
= zipfile
.ZipFile(zip_name
, 'w')
82 if name_in_zip
is None:
83 name_in_zip
= os
.path
.basename(script_name
)
84 zip_file
.write(script_name
, name_in_zip
)
87 # zip_file = zipfile.ZipFile(zip_name, 'r')
88 # print("Contents of %r:" % zip_name)
91 return zip_name
, os
.path
.join(zip_name
, name_in_zip
)
93 def _make_test_pkg(pkg_dir
):
95 _make_test_script(pkg_dir
, '__init__', '')
97 def _make_test_zip_pkg(zip_dir
, zip_basename
, pkg_name
, script_basename
,
98 source
=test_source
, depth
=1):
99 init_name
= _make_test_script(zip_dir
, '__init__', '')
100 init_basename
= os
.path
.basename(init_name
)
101 script_name
= _make_test_script(zip_dir
, script_basename
, source
)
102 pkg_names
= [os
.sep
.join([pkg_name
]*i
) for i
in range(1, depth
+1)]
103 script_name_in_zip
= os
.path
.join(pkg_names
[-1], os
.path
.basename(script_name
))
104 zip_filename
= zip_basename
+os
.extsep
+'zip'
105 zip_name
= os
.path
.join(zip_dir
, zip_filename
)
106 zip_file
= zipfile
.ZipFile(zip_name
, 'w')
107 for name
in pkg_names
:
108 init_name_in_zip
= os
.path
.join(name
, init_basename
)
109 zip_file
.write(init_name
, init_name_in_zip
)
110 zip_file
.write(script_name
, script_name_in_zip
)
113 os
.unlink(script_name
)
115 # zip_file = zipfile.ZipFile(zip_name, 'r')
116 # print('Contents of %r:' % zip_name)
117 # zip_file.printdir()
119 return zip_name
, os
.path
.join(zip_name
, script_name_in_zip
)
121 # There's no easy way to pass the script directory in to get
122 # -m to work (avoiding that is the whole point of making
123 # directories and zipfiles executable!)
124 # So we fake it for testing purposes with a custom launch script
126 import sys, os.path, runpy
127 sys.path.insert(0, %s)
128 runpy._run_module_as_main(%r)
131 def _make_launch_script(script_dir
, script_basename
, module_name
, path
=None):
133 path
= "os.path.dirname(__file__)"
136 source
= launch_source
% (path
, module_name
)
137 return _make_test_script(script_dir
, script_basename
, source
)
139 class CmdLineTest(unittest
.TestCase
):
140 def _check_script(self
, script_name
, expected_file
,
141 expected_argv0
, expected_package
,
143 run_args
= cmd_line_switches
+ (script_name
,)
144 exit_code
, data
= _run_python(*run_args
)
146 print("Output from test script %r:" % script_name
)
148 self
.assertEqual(exit_code
, 0)
149 printed_file
= '__file__==%r' % expected_file
150 printed_argv0
= 'sys.argv[0]==%r' % expected_argv0
151 printed_package
= '__package__==%r' % expected_package
153 print('Expected output:')
155 print(printed_package
)
157 self
.assert_(printed_file
in data
)
158 self
.assert_(printed_package
in data
)
159 self
.assert_(printed_argv0
in data
)
161 def _check_import_error(self
, script_name
, expected_msg
,
163 run_args
= cmd_line_switches
+ (script_name
,)
164 exit_code
, data
= _run_python(*run_args
)
166 print('Output from test script %r:' % script_name
)
168 print('Expected output: %r' % expected_msg
)
169 self
.assert_(expected_msg
in data
)
171 def test_basic_script(self
):
172 with
temp_dir() as script_dir
:
173 script_name
= _make_test_script(script_dir
, 'script')
174 self
._check
_script
(script_name
, script_name
, script_name
, None)
176 def test_script_compiled(self
):
177 with
temp_dir() as script_dir
:
178 script_name
= _make_test_script(script_dir
, 'script')
179 compiled_name
= _compile_test_script(script_name
)
180 os
.remove(script_name
)
181 self
._check
_script
(compiled_name
, compiled_name
, compiled_name
, None)
183 def test_directory(self
):
184 with
temp_dir() as script_dir
:
185 script_name
= _make_test_script(script_dir
, '__main__')
186 self
._check
_script
(script_dir
, script_name
, script_dir
, '')
188 def test_directory_compiled(self
):
189 with
temp_dir() as script_dir
:
190 script_name
= _make_test_script(script_dir
, '__main__')
191 compiled_name
= _compile_test_script(script_name
)
192 os
.remove(script_name
)
193 self
._check
_script
(script_dir
, compiled_name
, script_dir
, '')
195 def test_directory_error(self
):
196 with
temp_dir() as script_dir
:
197 msg
= "can't find '__main__.py' in %r" % script_dir
198 self
._check
_import
_error
(script_dir
, msg
)
200 def test_zipfile(self
):
201 with
temp_dir() as script_dir
:
202 script_name
= _make_test_script(script_dir
, '__main__')
203 zip_name
, run_name
= _make_test_zip(script_dir
, 'test_zip', script_name
)
204 self
._check
_script
(zip_name
, run_name
, zip_name
, '')
206 def test_zipfile_compiled(self
):
207 with
temp_dir() as script_dir
:
208 script_name
= _make_test_script(script_dir
, '__main__')
209 compiled_name
= _compile_test_script(script_name
)
210 zip_name
, run_name
= _make_test_zip(script_dir
, 'test_zip', compiled_name
)
211 self
._check
_script
(zip_name
, run_name
, zip_name
, '')
213 def test_zipfile_error(self
):
214 with
temp_dir() as script_dir
:
215 script_name
= _make_test_script(script_dir
, 'not_main')
216 zip_name
, run_name
= _make_test_zip(script_dir
, 'test_zip', script_name
)
217 msg
= "can't find '__main__.py' in %r" % zip_name
218 self
._check
_import
_error
(zip_name
, msg
)
220 def test_module_in_package(self
):
221 with
temp_dir() as script_dir
:
222 pkg_dir
= os
.path
.join(script_dir
, 'test_pkg')
223 _make_test_pkg(pkg_dir
)
224 script_name
= _make_test_script(pkg_dir
, 'script')
225 launch_name
= _make_launch_script(script_dir
, 'launch', 'test_pkg.script')
226 self
._check
_script
(launch_name
, script_name
, script_name
, 'test_pkg')
228 def test_module_in_package_in_zipfile(self
):
229 with
temp_dir() as script_dir
:
230 zip_name
, run_name
= _make_test_zip_pkg(script_dir
, 'test_zip', 'test_pkg', 'script')
231 launch_name
= _make_launch_script(script_dir
, 'launch', 'test_pkg.script', zip_name
)
232 self
._check
_script
(launch_name
, run_name
, run_name
, 'test_pkg')
234 def test_module_in_subpackage_in_zipfile(self
):
235 with
temp_dir() as script_dir
:
236 zip_name
, run_name
= _make_test_zip_pkg(script_dir
, 'test_zip', 'test_pkg', 'script', depth
=2)
237 launch_name
= _make_launch_script(script_dir
, 'launch', 'test_pkg.test_pkg.script', zip_name
)
238 self
._check
_script
(launch_name
, run_name
, run_name
, 'test_pkg.test_pkg')
240 def test_package(self
):
241 with
temp_dir() as script_dir
:
242 pkg_dir
= os
.path
.join(script_dir
, 'test_pkg')
243 _make_test_pkg(pkg_dir
)
244 script_name
= _make_test_script(pkg_dir
, '__main__')
245 launch_name
= _make_launch_script(script_dir
, 'launch', 'test_pkg')
246 self
._check
_script
(launch_name
, script_name
,
247 script_name
, 'test_pkg')
249 def test_package_compiled(self
):
250 with
temp_dir() as script_dir
:
251 pkg_dir
= os
.path
.join(script_dir
, 'test_pkg')
252 _make_test_pkg(pkg_dir
)
253 script_name
= _make_test_script(pkg_dir
, '__main__')
254 compiled_name
= _compile_test_script(script_name
)
255 os
.remove(script_name
)
256 launch_name
= _make_launch_script(script_dir
, 'launch', 'test_pkg')
257 self
._check
_script
(launch_name
, compiled_name
,
258 compiled_name
, 'test_pkg')
260 def test_package_error(self
):
261 with
temp_dir() as script_dir
:
262 pkg_dir
= os
.path
.join(script_dir
, 'test_pkg')
263 _make_test_pkg(pkg_dir
)
264 msg
= ("'test_pkg' is a package and cannot "
265 "be directly executed")
266 launch_name
= _make_launch_script(script_dir
, 'launch', 'test_pkg')
267 self
._check
_import
_error
(launch_name
, msg
)
269 def test_package_recursion(self
):
270 with
temp_dir() as script_dir
:
271 pkg_dir
= os
.path
.join(script_dir
, 'test_pkg')
272 _make_test_pkg(pkg_dir
)
273 main_dir
= os
.path
.join(pkg_dir
, '__main__')
274 _make_test_pkg(main_dir
)
275 msg
= ("Cannot use package as __main__ module; "
276 "'test_pkg' is a package and cannot "
277 "be directly executed")
278 launch_name
= _make_launch_script(script_dir
, 'launch', 'test_pkg')
279 self
._check
_import
_error
(launch_name
, msg
)
283 test
.support
.run_unittest(CmdLineTest
)
284 test
.support
.reap_children()
286 if __name__
== '__main__':