blob: 921c5f3df41960538c946a7c267e84ee35a8f49b [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
3import unittest
Georg Brandlf5247e32010-10-14 08:08:56 +00004import sys
Christian Heimes9cd17752007-11-18 19:35:23 +00005import os
6import os.path
Barry Warsaw28a691b2010-04-17 00:19:56 +00007import py_compile
8
Nick Coghland26c18a2010-08-17 13:06:11 +00009from test import support
Barry Warsaw28a691b2010-04-17 00:19:56 +000010from test.script_helper import (
Antoine Pitrouf51d8d32010-10-08 18:05:42 +000011 make_pkg, make_script, make_zip_pkg, make_zip_script,
12 assert_python_ok, assert_python_failure, temp_dir)
Christian Heimes9cd17752007-11-18 19:35:23 +000013
Nick Coghland26c18a2010-08-17 13:06:11 +000014verbose = support.verbose
Christian Heimes9cd17752007-11-18 19:35:23 +000015
Christian Heimescbf3b5c2007-12-03 21:02:03 +000016test_source = """\
Christian Heimes9cd17752007-11-18 19:35:23 +000017# Script may be run with optimisation enabled, so don't rely on assert
18# statements being executed
19def assertEqual(lhs, rhs):
20 if lhs != rhs:
Christian Heimescbf3b5c2007-12-03 21:02:03 +000021 raise AssertionError('%r != %r' % (lhs, rhs))
Christian Heimes9cd17752007-11-18 19:35:23 +000022def assertIdentical(lhs, rhs):
23 if lhs is not rhs:
Christian Heimescbf3b5c2007-12-03 21:02:03 +000024 raise AssertionError('%r is not %r' % (lhs, rhs))
Christian Heimes9cd17752007-11-18 19:35:23 +000025# Check basic code execution
26result = ['Top level assignment']
27def f():
28 result.append('Lower level reference')
29f()
30assertEqual(result, ['Top level assignment', 'Lower level reference'])
31# Check population of magic variables
32assertEqual(__name__, '__main__')
Victor Stinnere3874ed2010-10-17 01:41:09 +000033print('__file__==%a' % __file__)
Barry Warsaw28a691b2010-04-17 00:19:56 +000034assertEqual(__cached__, None)
Christian Heimescbf3b5c2007-12-03 21:02:03 +000035print('__package__==%r' % __package__)
Christian Heimes9cd17752007-11-18 19:35:23 +000036# Check the sys module
37import sys
38assertIdentical(globals(), sys.modules[__name__].__dict__)
Victor Stinnere3874ed2010-10-17 01:41:09 +000039print('sys.argv[0]==%a' % sys.argv[0])
40print('sys.path[0]==%a' % sys.path[0])
Nick Coghland26c18a2010-08-17 13:06:11 +000041# Check the working directory
42import os
Victor Stinnere3874ed2010-10-17 01:41:09 +000043print('cwd==%a' % os.getcwd())
Christian Heimescbf3b5c2007-12-03 21:02:03 +000044"""
Christian Heimes9cd17752007-11-18 19:35:23 +000045
Christian Heimescbf3b5c2007-12-03 21:02:03 +000046def _make_test_script(script_dir, script_basename, source=test_source):
Nick Coghlan260bd3e2009-11-16 06:49:25 +000047 return make_script(script_dir, script_basename, source)
Christian Heimescbf3b5c2007-12-03 21:02:03 +000048
Nick Coghlanf088e5e2008-12-14 11:50:48 +000049def _make_test_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename,
50 source=test_source, depth=1):
Nick Coghlan260bd3e2009-11-16 06:49:25 +000051 return make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename,
52 source, depth)
Nick Coghlanf088e5e2008-12-14 11:50:48 +000053
Christian Heimescbf3b5c2007-12-03 21:02:03 +000054# There's no easy way to pass the script directory in to get
55# -m to work (avoiding that is the whole point of making
56# directories and zipfiles executable!)
57# So we fake it for testing purposes with a custom launch script
58launch_source = """\
59import sys, os.path, runpy
Nick Coghlanf088e5e2008-12-14 11:50:48 +000060sys.path.insert(0, %s)
Christian Heimescbf3b5c2007-12-03 21:02:03 +000061runpy._run_module_as_main(%r)
62"""
63
Nick Coghlanf088e5e2008-12-14 11:50:48 +000064def _make_launch_script(script_dir, script_basename, module_name, path=None):
65 if path is None:
66 path = "os.path.dirname(__file__)"
67 else:
68 path = repr(path)
69 source = launch_source % (path, module_name)
Nick Coghlan260bd3e2009-11-16 06:49:25 +000070 return make_script(script_dir, script_basename, source)
Christian Heimescbf3b5c2007-12-03 21:02:03 +000071
Christian Heimes9cd17752007-11-18 19:35:23 +000072class CmdLineTest(unittest.TestCase):
Nick Coghland26c18a2010-08-17 13:06:11 +000073 def _check_output(self, script_name, exit_code, data,
74 expected_file, expected_argv0,
75 expected_path0, expected_package):
76 if verbose > 1:
Guido van Rossum87c0f1d2007-11-19 18:03:44 +000077 print("Output from test script %r:" % script_name)
78 print(data)
Christian Heimescbf3b5c2007-12-03 21:02:03 +000079 self.assertEqual(exit_code, 0)
Victor Stinnere3874ed2010-10-17 01:41:09 +000080 printed_file = '__file__==%a' % expected_file
Christian Heimescbf3b5c2007-12-03 21:02:03 +000081 printed_package = '__package__==%r' % expected_package
Victor Stinnere3874ed2010-10-17 01:41:09 +000082 printed_argv0 = 'sys.argv[0]==%a' % expected_argv0
83 printed_path0 = 'sys.path[0]==%a' % expected_path0
84 printed_cwd = 'cwd==%a' % os.getcwd()
Nick Coghland26c18a2010-08-17 13:06:11 +000085 if verbose > 1:
Christian Heimescbf3b5c2007-12-03 21:02:03 +000086 print('Expected output:')
87 print(printed_file)
88 print(printed_package)
89 print(printed_argv0)
Nick Coghland26c18a2010-08-17 13:06:11 +000090 print(printed_cwd)
Benjamin Peterson577473f2010-01-19 00:09:57 +000091 self.assertIn(printed_file.encode('utf-8'), data)
92 self.assertIn(printed_package.encode('utf-8'), data)
93 self.assertIn(printed_argv0.encode('utf-8'), data)
Nick Coghland26c18a2010-08-17 13:06:11 +000094 self.assertIn(printed_path0.encode('utf-8'), data)
95 self.assertIn(printed_cwd.encode('utf-8'), data)
96
97 def _check_script(self, script_name, expected_file,
98 expected_argv0, expected_path0,
99 expected_package,
100 *cmd_line_switches):
Georg Brandlf5247e32010-10-14 08:08:56 +0000101 if not __debug__:
102 cmd_line_switches += ('-' + 'O' * sys.flags.optimize,)
Nick Coghland26c18a2010-08-17 13:06:11 +0000103 run_args = cmd_line_switches + (script_name,)
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000104 rc, out, err = assert_python_ok(*run_args)
105 self._check_output(script_name, rc, out + err, expected_file,
Nick Coghland26c18a2010-08-17 13:06:11 +0000106 expected_argv0, expected_path0, expected_package)
Christian Heimes9cd17752007-11-18 19:35:23 +0000107
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000108 def _check_import_error(self, script_name, expected_msg,
109 *cmd_line_switches):
110 run_args = cmd_line_switches + (script_name,)
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000111 rc, out, err = assert_python_failure(*run_args)
Nick Coghland26c18a2010-08-17 13:06:11 +0000112 if verbose > 1:
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000113 print('Output from test script %r:' % script_name)
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000114 print(err)
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000115 print('Expected output: %r' % expected_msg)
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000116 self.assertIn(expected_msg.encode('utf-8'), err)
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000117
Christian Heimes9cd17752007-11-18 19:35:23 +0000118 def test_basic_script(self):
119 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000120 script_name = _make_test_script(script_dir, 'script')
Nick Coghland26c18a2010-08-17 13:06:11 +0000121 self._check_script(script_name, script_name, script_name,
122 script_dir, None)
Christian Heimes9cd17752007-11-18 19:35:23 +0000123
124 def test_script_compiled(self):
125 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000126 script_name = _make_test_script(script_dir, 'script')
Nick Coghland26c18a2010-08-17 13:06:11 +0000127 py_compile.compile(script_name, doraise=True)
Christian Heimes9cd17752007-11-18 19:35:23 +0000128 os.remove(script_name)
Nick Coghland26c18a2010-08-17 13:06:11 +0000129 pyc_file = support.make_legacy_pyc(script_name)
130 self._check_script(pyc_file, pyc_file,
131 pyc_file, script_dir, None)
Christian Heimes9cd17752007-11-18 19:35:23 +0000132
133 def test_directory(self):
134 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000135 script_name = _make_test_script(script_dir, '__main__')
Nick Coghland26c18a2010-08-17 13:06:11 +0000136 self._check_script(script_dir, script_name, script_dir,
137 script_dir, '')
Christian Heimes9cd17752007-11-18 19:35:23 +0000138
139 def test_directory_compiled(self):
140 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000141 script_name = _make_test_script(script_dir, '__main__')
Nick Coghland26c18a2010-08-17 13:06:11 +0000142 py_compile.compile(script_name, doraise=True)
Christian Heimes9cd17752007-11-18 19:35:23 +0000143 os.remove(script_name)
Nick Coghland26c18a2010-08-17 13:06:11 +0000144 pyc_file = support.make_legacy_pyc(script_name)
145 self._check_script(script_dir, pyc_file, script_dir,
146 script_dir, '')
Christian Heimes9cd17752007-11-18 19:35:23 +0000147
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000148 def test_directory_error(self):
149 with temp_dir() as script_dir:
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000150 msg = "can't find '__main__' module in %r" % script_dir
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000151 self._check_import_error(script_dir, msg)
152
Christian Heimes9cd17752007-11-18 19:35:23 +0000153 def test_zipfile(self):
154 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000155 script_name = _make_test_script(script_dir, '__main__')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000156 zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name)
Nick Coghland26c18a2010-08-17 13:06:11 +0000157 self._check_script(zip_name, run_name, zip_name, zip_name, '')
Christian Heimes9cd17752007-11-18 19:35:23 +0000158
159 def test_zipfile_compiled(self):
160 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000161 script_name = _make_test_script(script_dir, '__main__')
Barry Warsaw28a691b2010-04-17 00:19:56 +0000162 compiled_name = py_compile.compile(script_name, doraise=True)
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000163 zip_name, run_name = make_zip_script(script_dir, 'test_zip', compiled_name)
Nick Coghland26c18a2010-08-17 13:06:11 +0000164 self._check_script(zip_name, run_name, zip_name, zip_name, '')
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000165
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000166 def test_zipfile_error(self):
167 with temp_dir() as script_dir:
168 script_name = _make_test_script(script_dir, 'not_main')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000169 zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name)
170 msg = "can't find '__main__' module in %r" % zip_name
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000171 self._check_import_error(zip_name, msg)
172
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000173 def test_module_in_package(self):
174 with temp_dir() as script_dir:
175 pkg_dir = os.path.join(script_dir, 'test_pkg')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000176 make_pkg(pkg_dir)
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000177 script_name = _make_test_script(pkg_dir, 'script')
178 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.script')
Nick Coghland26c18a2010-08-17 13:06:11 +0000179 self._check_script(launch_name, script_name, script_name, script_dir, 'test_pkg')
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000180
181 def test_module_in_package_in_zipfile(self):
182 with temp_dir() as script_dir:
183 zip_name, run_name = _make_test_zip_pkg(script_dir, 'test_zip', 'test_pkg', 'script')
184 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.script', zip_name)
Nick Coghland26c18a2010-08-17 13:06:11 +0000185 self._check_script(launch_name, run_name, run_name, zip_name, 'test_pkg')
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000186
187 def test_module_in_subpackage_in_zipfile(self):
188 with temp_dir() as script_dir:
189 zip_name, run_name = _make_test_zip_pkg(script_dir, 'test_zip', 'test_pkg', 'script', depth=2)
190 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.test_pkg.script', zip_name)
Nick Coghland26c18a2010-08-17 13:06:11 +0000191 self._check_script(launch_name, run_name, run_name, zip_name, 'test_pkg.test_pkg')
Christian Heimes9cd17752007-11-18 19:35:23 +0000192
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000193 def test_package(self):
194 with temp_dir() as script_dir:
195 pkg_dir = os.path.join(script_dir, 'test_pkg')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000196 make_pkg(pkg_dir)
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000197 script_name = _make_test_script(pkg_dir, '__main__')
198 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg')
199 self._check_script(launch_name, script_name,
Nick Coghland26c18a2010-08-17 13:06:11 +0000200 script_name, script_dir, 'test_pkg')
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000201
202 def test_package_compiled(self):
203 with temp_dir() as script_dir:
204 pkg_dir = os.path.join(script_dir, 'test_pkg')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000205 make_pkg(pkg_dir)
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000206 script_name = _make_test_script(pkg_dir, '__main__')
Barry Warsaw28a691b2010-04-17 00:19:56 +0000207 compiled_name = py_compile.compile(script_name, doraise=True)
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000208 os.remove(script_name)
Nick Coghland26c18a2010-08-17 13:06:11 +0000209 pyc_file = support.make_legacy_pyc(script_name)
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000210 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg')
Barry Warsaw28a691b2010-04-17 00:19:56 +0000211 self._check_script(launch_name, pyc_file,
Nick Coghland26c18a2010-08-17 13:06:11 +0000212 pyc_file, script_dir, 'test_pkg')
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000213
214 def test_package_error(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 msg = ("'test_pkg' is a package and cannot "
219 "be directly executed")
220 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg')
221 self._check_import_error(launch_name, msg)
222
223 def test_package_recursion(self):
224 with temp_dir() as script_dir:
225 pkg_dir = os.path.join(script_dir, 'test_pkg')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000226 make_pkg(pkg_dir)
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000227 main_dir = os.path.join(pkg_dir, '__main__')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000228 make_pkg(main_dir)
Nick Coghlan3f48ae32009-02-08 01:58:26 +0000229 msg = ("Cannot use package as __main__ module; "
230 "'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
Nick Coghland26c18a2010-08-17 13:06:11 +0000235 def test_issue8202(self):
236 # Make sure package __init__ modules see "-m" in sys.argv0 while
237 # searching for the module to execute
238 with temp_dir() as script_dir:
239 with support.temp_cwd(path=script_dir):
240 pkg_dir = os.path.join(script_dir, 'test_pkg')
241 make_pkg(pkg_dir, "import sys; print('init_argv0==%r' % sys.argv[0])")
242 script_name = _make_test_script(pkg_dir, 'script')
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000243 rc, out, err = assert_python_ok('-m', 'test_pkg.script')
Nick Coghland26c18a2010-08-17 13:06:11 +0000244 if verbose > 1:
245 print(data)
Nick Coghland26c18a2010-08-17 13:06:11 +0000246 expected = "init_argv0==%r" % '-m'
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000247 self.assertIn(expected.encode('utf-8'), out)
248 self._check_output(script_name, rc, out,
Nick Coghland26c18a2010-08-17 13:06:11 +0000249 script_name, script_name, '', 'test_pkg')
250
251 def test_issue8202_dash_c_file_ignored(self):
252 # Make sure a "-c" file in the current directory
253 # does not alter the value of sys.path[0]
254 with temp_dir() as script_dir:
255 with support.temp_cwd(path=script_dir):
256 with open("-c", "w") as f:
257 f.write("data")
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000258 rc, out, err = assert_python_ok('-c',
Nick Coghland26c18a2010-08-17 13:06:11 +0000259 'import sys; print("sys.path[0]==%r" % sys.path[0])')
260 if verbose > 1:
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000261 print(out)
Nick Coghland26c18a2010-08-17 13:06:11 +0000262 expected = "sys.path[0]==%r" % ''
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000263 self.assertIn(expected.encode('utf-8'), out)
Nick Coghland26c18a2010-08-17 13:06:11 +0000264
265 def test_issue8202_dash_m_file_ignored(self):
266 # Make sure a "-m" file in the current directory
267 # does not alter the value of sys.path[0]
268 with temp_dir() as script_dir:
269 script_name = _make_test_script(script_dir, 'other')
270 with support.temp_cwd(path=script_dir):
271 with open("-m", "w") as f:
272 f.write("data")
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000273 rc, out, err = assert_python_ok('-m', 'other')
274 self._check_output(script_name, rc, out,
Nick Coghland26c18a2010-08-17 13:06:11 +0000275 script_name, script_name, '', '')
Christian Heimes9cd17752007-11-18 19:35:23 +0000276
277def test_main():
Nick Coghland26c18a2010-08-17 13:06:11 +0000278 support.run_unittest(CmdLineTest)
279 support.reap_children()
Christian Heimes9cd17752007-11-18 19:35:23 +0000280
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000281if __name__ == '__main__':
Christian Heimes9cd17752007-11-18 19:35:23 +0000282 test_main()