blob: 155aafc7eb94501b654553eecd1809e0ba7560c7 [file] [log] [blame]
Barry Warsaw28a691b2010-04-17 00:19:56 +00001# tests command line execution of scripts
Christian Heimes9cd17752007-11-18 19:35:23 +00002
Brett Cannone0d88a12012-04-25 20:54:04 -04003import importlib
Christian Heimes9cd17752007-11-18 19:35:23 +00004import unittest
Georg Brandlf5247e32010-10-14 08:08:56 +00005import sys
Christian Heimes9cd17752007-11-18 19:35:23 +00006import os
7import os.path
Barry Warsaw28a691b2010-04-17 00:19:56 +00008import py_compile
9
Nick Coghland26c18a2010-08-17 13:06:11 +000010from test import support
Barry Warsaw28a691b2010-04-17 00:19:56 +000011from test.script_helper import (
Antoine Pitrouf51d8d32010-10-08 18:05:42 +000012 make_pkg, make_script, make_zip_pkg, make_zip_script,
13 assert_python_ok, assert_python_failure, temp_dir)
Christian Heimes9cd17752007-11-18 19:35:23 +000014
Nick Coghland26c18a2010-08-17 13:06:11 +000015verbose = support.verbose
Christian Heimes9cd17752007-11-18 19:35:23 +000016
Nick Coghlan37fc4012012-04-22 17:11:33 +100017example_args = ['test1', 'test2', 'test3']
18
Christian Heimescbf3b5c2007-12-03 21:02:03 +000019test_source = """\
Christian Heimes9cd17752007-11-18 19:35:23 +000020# Script may be run with optimisation enabled, so don't rely on assert
21# statements being executed
22def assertEqual(lhs, rhs):
23 if lhs != rhs:
Christian Heimescbf3b5c2007-12-03 21:02:03 +000024 raise AssertionError('%r != %r' % (lhs, rhs))
Christian Heimes9cd17752007-11-18 19:35:23 +000025def assertIdentical(lhs, rhs):
26 if lhs is not rhs:
Christian Heimescbf3b5c2007-12-03 21:02:03 +000027 raise AssertionError('%r is not %r' % (lhs, rhs))
Christian Heimes9cd17752007-11-18 19:35:23 +000028# Check basic code execution
29result = ['Top level assignment']
30def f():
31 result.append('Lower level reference')
32f()
33assertEqual(result, ['Top level assignment', 'Lower level reference'])
34# Check population of magic variables
35assertEqual(__name__, '__main__')
Victor Stinnere3874ed2010-10-17 01:41:09 +000036print('__file__==%a' % __file__)
Barry Warsaw28a691b2010-04-17 00:19:56 +000037assertEqual(__cached__, None)
Christian Heimescbf3b5c2007-12-03 21:02:03 +000038print('__package__==%r' % __package__)
Christian Heimes9cd17752007-11-18 19:35:23 +000039# Check the sys module
40import sys
41assertIdentical(globals(), sys.modules[__name__].__dict__)
Nick Coghlan37fc4012012-04-22 17:11:33 +100042from test import test_cmd_line_script
43example_args_list = test_cmd_line_script.example_args
44assertEqual(sys.argv[1:], example_args_list)
Victor Stinnere3874ed2010-10-17 01:41:09 +000045print('sys.argv[0]==%a' % sys.argv[0])
46print('sys.path[0]==%a' % sys.path[0])
Nick Coghland26c18a2010-08-17 13:06:11 +000047# Check the working directory
48import os
Victor Stinnere3874ed2010-10-17 01:41:09 +000049print('cwd==%a' % os.getcwd())
Christian Heimescbf3b5c2007-12-03 21:02:03 +000050"""
Christian Heimes9cd17752007-11-18 19:35:23 +000051
Christian Heimescbf3b5c2007-12-03 21:02:03 +000052def _make_test_script(script_dir, script_basename, source=test_source):
Brett Cannone0d88a12012-04-25 20:54:04 -040053 to_return = make_script(script_dir, script_basename, source)
54 importlib.invalidate_caches()
55 return to_return
Christian Heimescbf3b5c2007-12-03 21:02:03 +000056
Nick Coghlanf088e5e2008-12-14 11:50:48 +000057def _make_test_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename,
58 source=test_source, depth=1):
Brett Cannone0d88a12012-04-25 20:54:04 -040059 to_return = make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename,
60 source, depth)
61 importlib.invalidate_caches()
62 return to_return
Nick Coghlanf088e5e2008-12-14 11:50:48 +000063
Christian Heimescbf3b5c2007-12-03 21:02:03 +000064# There's no easy way to pass the script directory in to get
65# -m to work (avoiding that is the whole point of making
66# directories and zipfiles executable!)
67# So we fake it for testing purposes with a custom launch script
68launch_source = """\
69import sys, os.path, runpy
Nick Coghlanf088e5e2008-12-14 11:50:48 +000070sys.path.insert(0, %s)
Christian Heimescbf3b5c2007-12-03 21:02:03 +000071runpy._run_module_as_main(%r)
72"""
73
Nick Coghlanf088e5e2008-12-14 11:50:48 +000074def _make_launch_script(script_dir, script_basename, module_name, path=None):
75 if path is None:
76 path = "os.path.dirname(__file__)"
77 else:
78 path = repr(path)
79 source = launch_source % (path, module_name)
Brett Cannone0d88a12012-04-25 20:54:04 -040080 to_return = make_script(script_dir, script_basename, source)
81 importlib.invalidate_caches()
82 return to_return
Christian Heimescbf3b5c2007-12-03 21:02:03 +000083
Christian Heimes9cd17752007-11-18 19:35:23 +000084class CmdLineTest(unittest.TestCase):
Nick Coghland26c18a2010-08-17 13:06:11 +000085 def _check_output(self, script_name, exit_code, data,
86 expected_file, expected_argv0,
87 expected_path0, expected_package):
88 if verbose > 1:
Guido van Rossum87c0f1d2007-11-19 18:03:44 +000089 print("Output from test script %r:" % script_name)
90 print(data)
Christian Heimescbf3b5c2007-12-03 21:02:03 +000091 self.assertEqual(exit_code, 0)
Victor Stinnere3874ed2010-10-17 01:41:09 +000092 printed_file = '__file__==%a' % expected_file
Christian Heimescbf3b5c2007-12-03 21:02:03 +000093 printed_package = '__package__==%r' % expected_package
Victor Stinnere3874ed2010-10-17 01:41:09 +000094 printed_argv0 = 'sys.argv[0]==%a' % expected_argv0
95 printed_path0 = 'sys.path[0]==%a' % expected_path0
96 printed_cwd = 'cwd==%a' % os.getcwd()
Nick Coghland26c18a2010-08-17 13:06:11 +000097 if verbose > 1:
Christian Heimescbf3b5c2007-12-03 21:02:03 +000098 print('Expected output:')
99 print(printed_file)
100 print(printed_package)
101 print(printed_argv0)
Nick Coghland26c18a2010-08-17 13:06:11 +0000102 print(printed_cwd)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000103 self.assertIn(printed_file.encode('utf-8'), data)
104 self.assertIn(printed_package.encode('utf-8'), data)
105 self.assertIn(printed_argv0.encode('utf-8'), data)
Nick Coghland26c18a2010-08-17 13:06:11 +0000106 self.assertIn(printed_path0.encode('utf-8'), data)
107 self.assertIn(printed_cwd.encode('utf-8'), data)
108
109 def _check_script(self, script_name, expected_file,
110 expected_argv0, expected_path0,
111 expected_package,
112 *cmd_line_switches):
Georg Brandlf5247e32010-10-14 08:08:56 +0000113 if not __debug__:
114 cmd_line_switches += ('-' + 'O' * sys.flags.optimize,)
Nick Coghlan37fc4012012-04-22 17:11:33 +1000115 run_args = cmd_line_switches + (script_name,) + tuple(example_args)
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000116 rc, out, err = assert_python_ok(*run_args)
117 self._check_output(script_name, rc, out + err, expected_file,
Nick Coghland26c18a2010-08-17 13:06:11 +0000118 expected_argv0, expected_path0, expected_package)
Christian Heimes9cd17752007-11-18 19:35:23 +0000119
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000120 def _check_import_error(self, script_name, expected_msg,
121 *cmd_line_switches):
122 run_args = cmd_line_switches + (script_name,)
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000123 rc, out, err = assert_python_failure(*run_args)
Nick Coghland26c18a2010-08-17 13:06:11 +0000124 if verbose > 1:
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000125 print('Output from test script %r:' % script_name)
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000126 print(err)
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000127 print('Expected output: %r' % expected_msg)
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000128 self.assertIn(expected_msg.encode('utf-8'), err)
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000129
Christian Heimes9cd17752007-11-18 19:35:23 +0000130 def test_basic_script(self):
131 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000132 script_name = _make_test_script(script_dir, 'script')
Nick Coghland26c18a2010-08-17 13:06:11 +0000133 self._check_script(script_name, script_name, script_name,
134 script_dir, None)
Christian Heimes9cd17752007-11-18 19:35:23 +0000135
136 def test_script_compiled(self):
137 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000138 script_name = _make_test_script(script_dir, 'script')
Nick Coghland26c18a2010-08-17 13:06:11 +0000139 py_compile.compile(script_name, doraise=True)
Christian Heimes9cd17752007-11-18 19:35:23 +0000140 os.remove(script_name)
Nick Coghland26c18a2010-08-17 13:06:11 +0000141 pyc_file = support.make_legacy_pyc(script_name)
142 self._check_script(pyc_file, pyc_file,
143 pyc_file, script_dir, None)
Christian Heimes9cd17752007-11-18 19:35:23 +0000144
145 def test_directory(self):
146 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000147 script_name = _make_test_script(script_dir, '__main__')
Nick Coghland26c18a2010-08-17 13:06:11 +0000148 self._check_script(script_dir, script_name, script_dir,
149 script_dir, '')
Christian Heimes9cd17752007-11-18 19:35:23 +0000150
151 def test_directory_compiled(self):
152 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000153 script_name = _make_test_script(script_dir, '__main__')
Nick Coghland26c18a2010-08-17 13:06:11 +0000154 py_compile.compile(script_name, doraise=True)
Christian Heimes9cd17752007-11-18 19:35:23 +0000155 os.remove(script_name)
Nick Coghland26c18a2010-08-17 13:06:11 +0000156 pyc_file = support.make_legacy_pyc(script_name)
157 self._check_script(script_dir, pyc_file, script_dir,
158 script_dir, '')
Christian Heimes9cd17752007-11-18 19:35:23 +0000159
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000160 def test_directory_error(self):
161 with temp_dir() as script_dir:
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000162 msg = "can't find '__main__' module in %r" % script_dir
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000163 self._check_import_error(script_dir, msg)
164
Christian Heimes9cd17752007-11-18 19:35:23 +0000165 def test_zipfile(self):
166 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000167 script_name = _make_test_script(script_dir, '__main__')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000168 zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name)
Nick Coghland26c18a2010-08-17 13:06:11 +0000169 self._check_script(zip_name, run_name, zip_name, zip_name, '')
Christian Heimes9cd17752007-11-18 19:35:23 +0000170
171 def test_zipfile_compiled(self):
172 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000173 script_name = _make_test_script(script_dir, '__main__')
Barry Warsaw28a691b2010-04-17 00:19:56 +0000174 compiled_name = py_compile.compile(script_name, doraise=True)
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000175 zip_name, run_name = make_zip_script(script_dir, 'test_zip', compiled_name)
Nick Coghland26c18a2010-08-17 13:06:11 +0000176 self._check_script(zip_name, run_name, zip_name, zip_name, '')
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000177
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000178 def test_zipfile_error(self):
179 with temp_dir() as script_dir:
180 script_name = _make_test_script(script_dir, 'not_main')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000181 zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name)
182 msg = "can't find '__main__' module in %r" % zip_name
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000183 self._check_import_error(zip_name, msg)
184
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000185 def test_module_in_package(self):
186 with temp_dir() as script_dir:
187 pkg_dir = os.path.join(script_dir, 'test_pkg')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000188 make_pkg(pkg_dir)
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000189 script_name = _make_test_script(pkg_dir, 'script')
190 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.script')
Nick Coghland26c18a2010-08-17 13:06:11 +0000191 self._check_script(launch_name, script_name, script_name, script_dir, 'test_pkg')
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000192
193 def test_module_in_package_in_zipfile(self):
194 with temp_dir() as script_dir:
195 zip_name, run_name = _make_test_zip_pkg(script_dir, 'test_zip', 'test_pkg', 'script')
196 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.script', zip_name)
Nick Coghland26c18a2010-08-17 13:06:11 +0000197 self._check_script(launch_name, run_name, run_name, zip_name, 'test_pkg')
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000198
199 def test_module_in_subpackage_in_zipfile(self):
200 with temp_dir() as script_dir:
201 zip_name, run_name = _make_test_zip_pkg(script_dir, 'test_zip', 'test_pkg', 'script', depth=2)
202 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.test_pkg.script', zip_name)
Nick Coghland26c18a2010-08-17 13:06:11 +0000203 self._check_script(launch_name, run_name, run_name, zip_name, 'test_pkg.test_pkg')
Christian Heimes9cd17752007-11-18 19:35:23 +0000204
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000205 def test_package(self):
206 with temp_dir() as script_dir:
207 pkg_dir = os.path.join(script_dir, 'test_pkg')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000208 make_pkg(pkg_dir)
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000209 script_name = _make_test_script(pkg_dir, '__main__')
210 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg')
211 self._check_script(launch_name, script_name,
Nick Coghland26c18a2010-08-17 13:06:11 +0000212 script_name, script_dir, 'test_pkg')
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000213
214 def test_package_compiled(self):
215 with temp_dir() as script_dir:
216 pkg_dir = os.path.join(script_dir, 'test_pkg')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000217 make_pkg(pkg_dir)
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000218 script_name = _make_test_script(pkg_dir, '__main__')
Barry Warsaw28a691b2010-04-17 00:19:56 +0000219 compiled_name = py_compile.compile(script_name, doraise=True)
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000220 os.remove(script_name)
Nick Coghland26c18a2010-08-17 13:06:11 +0000221 pyc_file = support.make_legacy_pyc(script_name)
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000222 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg')
Barry Warsaw28a691b2010-04-17 00:19:56 +0000223 self._check_script(launch_name, pyc_file,
Nick Coghland26c18a2010-08-17 13:06:11 +0000224 pyc_file, script_dir, 'test_pkg')
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000225
226 def test_package_error(self):
227 with temp_dir() as script_dir:
228 pkg_dir = os.path.join(script_dir, 'test_pkg')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000229 make_pkg(pkg_dir)
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000230 msg = ("'test_pkg' is a package and cannot "
231 "be directly executed")
232 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg')
233 self._check_import_error(launch_name, msg)
234
235 def test_package_recursion(self):
236 with temp_dir() as script_dir:
237 pkg_dir = os.path.join(script_dir, 'test_pkg')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000238 make_pkg(pkg_dir)
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000239 main_dir = os.path.join(pkg_dir, '__main__')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000240 make_pkg(main_dir)
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000241 msg = ("Cannot use package as __main__ module; "
242 "'test_pkg' is a package and cannot "
243 "be directly executed")
244 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg')
245 self._check_import_error(launch_name, msg)
246
Nick Coghland26c18a2010-08-17 13:06:11 +0000247 def test_issue8202(self):
248 # Make sure package __init__ modules see "-m" in sys.argv0 while
249 # searching for the module to execute
250 with temp_dir() as script_dir:
251 with support.temp_cwd(path=script_dir):
252 pkg_dir = os.path.join(script_dir, 'test_pkg')
253 make_pkg(pkg_dir, "import sys; print('init_argv0==%r' % sys.argv[0])")
254 script_name = _make_test_script(pkg_dir, 'script')
Nick Coghlan37fc4012012-04-22 17:11:33 +1000255 rc, out, err = assert_python_ok('-m', 'test_pkg.script', *example_args)
Nick Coghland26c18a2010-08-17 13:06:11 +0000256 if verbose > 1:
Nick Coghlan10ac77d2012-04-19 22:19:36 +1000257 print(out)
Nick Coghland26c18a2010-08-17 13:06:11 +0000258 expected = "init_argv0==%r" % '-m'
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000259 self.assertIn(expected.encode('utf-8'), out)
260 self._check_output(script_name, rc, out,
Nick Coghland26c18a2010-08-17 13:06:11 +0000261 script_name, script_name, '', 'test_pkg')
262
263 def test_issue8202_dash_c_file_ignored(self):
264 # Make sure a "-c" file in the current directory
265 # does not alter the value of sys.path[0]
266 with temp_dir() as script_dir:
267 with support.temp_cwd(path=script_dir):
268 with open("-c", "w") as f:
269 f.write("data")
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000270 rc, out, err = assert_python_ok('-c',
Nick Coghland26c18a2010-08-17 13:06:11 +0000271 'import sys; print("sys.path[0]==%r" % sys.path[0])')
272 if verbose > 1:
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000273 print(out)
Nick Coghland26c18a2010-08-17 13:06:11 +0000274 expected = "sys.path[0]==%r" % ''
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000275 self.assertIn(expected.encode('utf-8'), out)
Nick Coghland26c18a2010-08-17 13:06:11 +0000276
277 def test_issue8202_dash_m_file_ignored(self):
278 # Make sure a "-m" file in the current directory
279 # does not alter the value of sys.path[0]
280 with temp_dir() as script_dir:
281 script_name = _make_test_script(script_dir, 'other')
282 with support.temp_cwd(path=script_dir):
283 with open("-m", "w") as f:
284 f.write("data")
Nick Coghlan37fc4012012-04-22 17:11:33 +1000285 rc, out, err = assert_python_ok('-m', 'other', *example_args)
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000286 self._check_output(script_name, rc, out,
Nick Coghland26c18a2010-08-17 13:06:11 +0000287 script_name, script_name, '', '')
Christian Heimes9cd17752007-11-18 19:35:23 +0000288
289def test_main():
Nick Coghland26c18a2010-08-17 13:06:11 +0000290 support.run_unittest(CmdLineTest)
291 support.reap_children()
Christian Heimes9cd17752007-11-18 19:35:23 +0000292
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000293if __name__ == '__main__':
Christian Heimes9cd17752007-11-18 19:35:23 +0000294 test_main()