1 # Tests command line execution of scripts 2 3 import unittest 4 import os 5 import os.path 6 import test.test_support 7 from test.script_helper import (run_python, 8 temp_dir, make_script, compile_script, 9 assert_python_failure, make_pkg, 10 make_zip_script, make_zip_pkg) 11 12 verbose = test.test_support.verbose 13 14 15 example_args = ['test1', 'test2', 'test3'] 16 17 test_source = """\ 18 # Script may be run with optimisation enabled, so don't rely on assert 19 # statements being executed 20 def assertEqual(lhs, rhs): 21 if lhs != rhs: 22 raise AssertionError('%r != %r' % (lhs, rhs)) 23 def assertIdentical(lhs, rhs): 24 if lhs is not rhs: 25 raise AssertionError('%r is not %r' % (lhs, rhs)) 26 # Check basic code execution 27 result = ['Top level assignment'] 28 def f(): 29 result.append('Lower level reference') 30 f() 31 assertEqual(result, ['Top level assignment', 'Lower level reference']) 32 # Check population of magic variables 33 assertEqual(__name__, '__main__') 34 print '__file__==%r' % __file__ 35 print '__package__==%r' % __package__ 36 # Check the sys module 37 import sys 38 assertIdentical(globals(), sys.modules[__name__].__dict__) 39 print 'sys.argv[0]==%r' % sys.argv[0] 40 """ 41 42 def _make_test_script(script_dir, script_basename, source=test_source): 43 return make_script(script_dir, script_basename, source) 44 45 def _make_test_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, 46 source=test_source, depth=1): 47 return make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, 48 source, depth) 49 50 # There's no easy way to pass the script directory in to get 51 # -m to work (avoiding that is the whole point of making 52 # directories and zipfiles executable!) 53 # So we fake it for testing purposes with a custom launch script 54 launch_source = """\ 55 import sys, os.path, runpy 56 sys.path.insert(0, %s) 57 runpy._run_module_as_main(%r) 58 """ 59 60 def _make_launch_script(script_dir, script_basename, module_name, path=None): 61 if path is None: 62 path = "os.path.dirname(__file__)" 63 else: 64 path = repr(path) 65 source = launch_source % (path, module_name) 66 return make_script(script_dir, script_basename, source) 67 68 class CmdLineTest(unittest.TestCase): 69 def _check_script(self, script_name, expected_file, 70 expected_argv0, expected_package, 71 *cmd_line_switches): 72 run_args = cmd_line_switches + (script_name,) 73 exit_code, data = run_python(*run_args) 74 if verbose: 75 print 'Output from test script %r:' % script_name 76 print data 77 self.assertEqual(exit_code, 0) 78 printed_file = '__file__==%r' % expected_file 79 printed_argv0 = 'sys.argv[0]==%r' % expected_argv0 80 printed_package = '__package__==%r' % expected_package 81 if verbose: 82 print 'Expected output:' 83 print printed_file 84 print printed_package 85 print printed_argv0 86 self.assertIn(printed_file, data) 87 self.assertIn(printed_package, data) 88 self.assertIn(printed_argv0, data) 89 90 def _check_import_error(self, script_name, expected_msg, 91 *cmd_line_switches): 92 run_args = cmd_line_switches + (script_name,) 93 exit_code, data = run_python(*run_args) 94 if verbose: 95 print 'Output from test script %r:' % script_name 96 print data 97 print 'Expected output: %r' % expected_msg 98 self.assertIn(expected_msg, data) 99 100 def test_basic_script(self): 101 with temp_dir() as script_dir: 102 script_name = _make_test_script(script_dir, 'script') 103 self._check_script(script_name, script_name, script_name, None) 104 105 def test_script_compiled(self): 106 with temp_dir() as script_dir: 107 script_name = _make_test_script(script_dir, 'script') 108 compiled_name = compile_script(script_name) 109 os.remove(script_name) 110 self._check_script(compiled_name, compiled_name, compiled_name, None) 111 112 def test_directory(self): 113 with temp_dir() as script_dir: 114 script_name = _make_test_script(script_dir, '__main__') 115 self._check_script(script_dir, script_name, script_dir, '') 116 117 def test_directory_compiled(self): 118 with temp_dir() as script_dir: 119 script_name = _make_test_script(script_dir, '__main__') 120 compiled_name = compile_script(script_name) 121 os.remove(script_name) 122 self._check_script(script_dir, compiled_name, script_dir, '') 123 124 def test_directory_error(self): 125 with temp_dir() as script_dir: 126 msg = "can't find '__main__' module in %r" % script_dir 127 self._check_import_error(script_dir, msg) 128 129 def test_zipfile(self): 130 with temp_dir() as script_dir: 131 script_name = _make_test_script(script_dir, '__main__') 132 zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name) 133 self._check_script(zip_name, run_name, zip_name, '') 134 135 def test_zipfile_compiled(self): 136 with temp_dir() as script_dir: 137 script_name = _make_test_script(script_dir, '__main__') 138 compiled_name = compile_script(script_name) 139 zip_name, run_name = make_zip_script(script_dir, 'test_zip', compiled_name) 140 self._check_script(zip_name, run_name, zip_name, '') 141 142 def test_zipfile_error(self): 143 with temp_dir() as script_dir: 144 script_name = _make_test_script(script_dir, 'not_main') 145 zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name) 146 msg = "can't find '__main__' module in %r" % zip_name 147 self._check_import_error(zip_name, msg) 148 149 def test_module_in_package(self): 150 with temp_dir() as script_dir: 151 pkg_dir = os.path.join(script_dir, 'test_pkg') 152 make_pkg(pkg_dir) 153 script_name = _make_test_script(pkg_dir, 'script') 154 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.script') 155 self._check_script(launch_name, script_name, script_name, 'test_pkg') 156 157 def test_module_in_package_in_zipfile(self): 158 with temp_dir() as script_dir: 159 zip_name, run_name = _make_test_zip_pkg(script_dir, 'test_zip', 'test_pkg', 'script') 160 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.script', zip_name) 161 self._check_script(launch_name, run_name, run_name, 'test_pkg') 162 163 def test_module_in_subpackage_in_zipfile(self): 164 with temp_dir() as script_dir: 165 zip_name, run_name = _make_test_zip_pkg(script_dir, 'test_zip', 'test_pkg', 'script', depth=2) 166 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.test_pkg.script', zip_name) 167 self._check_script(launch_name, run_name, run_name, 'test_pkg.test_pkg') 168 169 def test_package(self): 170 with temp_dir() as script_dir: 171 pkg_dir = os.path.join(script_dir, 'test_pkg') 172 make_pkg(pkg_dir) 173 script_name = _make_test_script(pkg_dir, '__main__') 174 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') 175 self._check_script(launch_name, script_name, 176 script_name, 'test_pkg') 177 178 def test_package_compiled(self): 179 with temp_dir() as script_dir: 180 pkg_dir = os.path.join(script_dir, 'test_pkg') 181 make_pkg(pkg_dir) 182 script_name = _make_test_script(pkg_dir, '__main__') 183 compiled_name = compile_script(script_name) 184 os.remove(script_name) 185 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') 186 self._check_script(launch_name, compiled_name, 187 compiled_name, 'test_pkg') 188 189 def test_package_error(self): 190 with temp_dir() as script_dir: 191 pkg_dir = os.path.join(script_dir, 'test_pkg') 192 make_pkg(pkg_dir) 193 msg = ("'test_pkg' is a package and cannot " 194 "be directly executed") 195 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') 196 self._check_import_error(launch_name, msg) 197 198 def test_package_recursion(self): 199 with temp_dir() as script_dir: 200 pkg_dir = os.path.join(script_dir, 'test_pkg') 201 make_pkg(pkg_dir) 202 main_dir = os.path.join(pkg_dir, '__main__') 203 make_pkg(main_dir) 204 msg = ("Cannot use package as __main__ module; " 205 "'test_pkg' is a package and cannot " 206 "be directly executed") 207 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') 208 self._check_import_error(launch_name, msg) 209 210 def test_dash_m_error_code_is_one(self): 211 # If a module is invoked with the -m command line flag 212 # and results in an error that the return code to the 213 # shell is '1' 214 with temp_dir() as script_dir: 215 pkg_dir = os.path.join(script_dir, 'test_pkg') 216 make_pkg(pkg_dir) 217 script_name = _make_test_script(pkg_dir, 'other', "if __name__ == '__main__': raise ValueError") 218 rc, out, err = assert_python_failure('-m', 'test_pkg.other', *example_args) 219 if verbose > 1: 220 print(out) 221 self.assertEqual(rc, 1) 222 223 224 def test_main(): 225 test.test_support.run_unittest(CmdLineTest) 226 test.test_support.reap_children() 227 228 if __name__ == '__main__': 229 test_main() 230