blob: 852a7aa7a02bfffb88bf33f46cde309321977eb3 [file] [log] [blame]
Christian Heimes9cd17752007-11-18 19:35:23 +00001# Tests invocation of the interpreter with various command line arguments
2# All tests are executed with environment variables ignored
3# See test_cmd_line_script.py for testing of script execution
Neal Norwitz11bd1192005-10-03 00:54:56 +00004
Philip Jenveyab7481a2009-05-22 05:46:35 +00005import os
Benjamin Petersonee8712c2008-05-20 21:35:26 +00006import test.support, unittest
Antoine Pitrou87695762008-08-14 22:44:29 +00007import os
Neal Norwitz11bd1192005-10-03 00:54:56 +00008import sys
Nick Coghlan260bd3e2009-11-16 06:49:25 +00009from test.script_helper import spawn_python, kill_python, python_exit_code
Neal Norwitz11bd1192005-10-03 00:54:56 +000010
Nick Coghlan260bd3e2009-11-16 06:49:25 +000011# XXX (ncoghlan): there are assorted gratuitous inconsistencies between the
12# support code in the Py3k version and the 2.x version that unnecessarily
13# complicate test suite merges. See issue 7331
14
15# spawn_python normally enforces use of -E to avoid environmental effects
16# but one test checks PYTHONPATH behaviour explicitly
17# XXX (ncoghlan): Give script_helper.spawn_python an option to switch
18# off the -E flag that is normally inserted automatically
19import subprocess
20def _spawn_python_with_env(*args):
Antoine Pitrou87695762008-08-14 22:44:29 +000021 cmd_line = [sys.executable]
Thomas Woutersed03b412007-08-28 21:37:11 +000022 cmd_line.extend(args)
23 return subprocess.Popen(cmd_line, stdin=subprocess.PIPE,
24 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
25
Trent Nelson39e307e2008-03-19 06:45:48 +000026
Nick Coghlan260bd3e2009-11-16 06:49:25 +000027# XXX (ncoghlan): Move to script_helper and make consistent with run_python
Trent Nelson39e307e2008-03-19 06:45:48 +000028def _kill_python_and_exit_code(p):
Nick Coghlan260bd3e2009-11-16 06:49:25 +000029 data = kill_python(p)
Trent Nelson39e307e2008-03-19 06:45:48 +000030 returncode = p.wait()
31 return data, returncode
Thomas Woutersed03b412007-08-28 21:37:11 +000032
Neal Norwitz11bd1192005-10-03 00:54:56 +000033class CmdLineTest(unittest.TestCase):
Thomas Woutersed03b412007-08-28 21:37:11 +000034 def start_python(self, *args):
Nick Coghlan260bd3e2009-11-16 06:49:25 +000035 p = spawn_python(*args)
36 return kill_python(p)
Trent Nelson39e307e2008-03-19 06:45:48 +000037
38 def start_python_and_exit_code(self, *args):
Nick Coghlan260bd3e2009-11-16 06:49:25 +000039 p = spawn_python(*args)
Trent Nelson39e307e2008-03-19 06:45:48 +000040 return _kill_python_and_exit_code(p)
Neal Norwitz11bd1192005-10-03 00:54:56 +000041
Thomas Wouters477c8d52006-05-27 19:21:47 +000042 def exit_code(self, *args):
Nick Coghlan260bd3e2009-11-16 06:49:25 +000043 return python_exit_code(*args)
Walter Dörwald9356fb92005-11-25 15:22:10 +000044
Neal Norwitz11bd1192005-10-03 00:54:56 +000045 def test_directories(self):
Neal Norwitz72c2c062006-03-09 05:58:11 +000046 self.assertNotEqual(self.exit_code('.'), 0)
47 self.assertNotEqual(self.exit_code('< .'), 0)
Neal Norwitz11bd1192005-10-03 00:54:56 +000048
49 def verify_valid_flag(self, cmd_line):
50 data = self.start_python(cmd_line)
Guido van Rossuma1c42a92007-08-29 03:47:36 +000051 self.assertTrue(data == b'' or data.endswith(b'\n'))
Guido van Rossumf074b642007-07-11 06:56:16 +000052 self.assertTrue(b'Traceback' not in data)
Neal Norwitz11bd1192005-10-03 00:54:56 +000053
Neal Norwitz11bd1192005-10-03 00:54:56 +000054 def test_optimize(self):
55 self.verify_valid_flag('-O')
56 self.verify_valid_flag('-OO')
57
58 def test_q(self):
59 self.verify_valid_flag('-Qold')
60 self.verify_valid_flag('-Qnew')
61 self.verify_valid_flag('-Qwarn')
62 self.verify_valid_flag('-Qwarnall')
63
64 def test_site_flag(self):
65 self.verify_valid_flag('-S')
66
67 def test_usage(self):
Guido van Rossumf074b642007-07-11 06:56:16 +000068 self.assertTrue(b'usage' in self.start_python('-h'))
Neal Norwitz11bd1192005-10-03 00:54:56 +000069
70 def test_version(self):
Guido van Rossuma1c42a92007-08-29 03:47:36 +000071 version = ('Python %d.%d' % sys.version_info[:2]).encode("ascii")
Neal Norwitz11bd1192005-10-03 00:54:56 +000072 self.assertTrue(self.start_python('-V').startswith(version))
73
Trent Nelson39e307e2008-03-19 06:45:48 +000074 def test_verbose(self):
75 # -v causes imports to write to stderr. If the write to
76 # stderr itself causes an import to happen (for the output
77 # codec), a recursion loop can occur.
78 data, rc = self.start_python_and_exit_code('-v')
79 self.assertEqual(rc, 0)
80 self.assertTrue(b'stack overflow' not in data)
81 data, rc = self.start_python_and_exit_code('-vv')
82 self.assertEqual(rc, 0)
83 self.assertTrue(b'stack overflow' not in data)
84
Thomas Wouters477c8d52006-05-27 19:21:47 +000085 def test_run_module(self):
86 # Test expected operation of the '-m' switch
87 # Switch needs an argument
88 self.assertNotEqual(self.exit_code('-m'), 0)
89 # Check we get an error for a nonexistent module
90 self.assertNotEqual(
91 self.exit_code('-m', 'fnord43520xyz'),
92 0)
93 # Check the runpy module also gives an error for
94 # a nonexistent module
95 self.assertNotEqual(
96 self.exit_code('-m', 'runpy', 'fnord43520xyz'),
97 0)
98 # All good if module is located and run successfully
99 self.assertEqual(
100 self.exit_code('-m', 'timeit', '-n', '1'),
101 0)
102
Thomas Woutersed03b412007-08-28 21:37:11 +0000103 def test_run_module_bug1764407(self):
104 # -m and -i need to play well together
105 # Runs the timeit module and checks the __main__
106 # namespace has been populated appropriately
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000107 p = spawn_python('-i', '-m', 'timeit', '-n', '1')
Guido van Rossuma1c42a92007-08-29 03:47:36 +0000108 p.stdin.write(b'Timer\n')
109 p.stdin.write(b'exit()\n')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000110 data = kill_python(p)
Thomas Woutersed03b412007-08-28 21:37:11 +0000111 self.assertTrue(data.find(b'1 loop') != -1)
112 self.assertTrue(data.find(b'__main__.Timer') != -1)
113
Thomas Wouters477c8d52006-05-27 19:21:47 +0000114 def test_run_code(self):
115 # Test expected operation of the '-c' switch
116 # Switch needs an argument
117 self.assertNotEqual(self.exit_code('-c'), 0)
118 # Check we get an error for an uncaught exception
119 self.assertNotEqual(
120 self.exit_code('-c', 'raise Exception'),
121 0)
122 # All good if execution is successful
123 self.assertEqual(
124 self.exit_code('-c', 'pass'),
125 0)
126
Amaury Forgeot d'Arc9a5499b2008-11-11 23:04:59 +0000127 # Test handling of non-ascii data
Amaury Forgeot d'Arce2557642008-11-12 00:59:11 +0000128 if sys.getfilesystemencoding() != 'ascii':
129 command = "assert(ord('\xe9') == 0xe9)"
130 self.assertEqual(
131 self.exit_code('-c', command),
132 0)
Amaury Forgeot d'Arc9a5499b2008-11-11 23:04:59 +0000133
Antoine Pitrou05608432009-01-09 18:53:14 +0000134 def test_unbuffered_output(self):
135 # Test expected operation of the '-u' switch
136 for stream in ('stdout', 'stderr'):
137 # Binary is unbuffered
138 code = ("import os, sys; sys.%s.buffer.write(b'x'); os._exit(0)"
139 % stream)
140 data, rc = self.start_python_and_exit_code('-u', '-c', code)
141 self.assertEqual(rc, 0)
142 self.assertEqual(data, b'x', "binary %s not unbuffered" % stream)
143 # Text is line-buffered
144 code = ("import os, sys; sys.%s.write('x\\n'); os._exit(0)"
145 % stream)
146 data, rc = self.start_python_and_exit_code('-u', '-c', code)
147 self.assertEqual(rc, 0)
148 self.assertEqual(data.strip(), b'x',
149 "text %s not line-buffered" % stream)
150
Antoine Pitrou27fe9fc2009-01-26 21:48:00 +0000151 def test_unbuffered_input(self):
152 # sys.stdin still works with '-u'
153 code = ("import sys; sys.stdout.write(sys.stdin.read(1))")
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000154 p = spawn_python('-u', '-c', code)
Antoine Pitrou27fe9fc2009-01-26 21:48:00 +0000155 p.stdin.write(b'x')
156 p.stdin.flush()
157 data, rc = _kill_python_and_exit_code(p)
158 self.assertEqual(rc, 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000159 self.assertTrue(data.startswith(b'x'), data)
Antoine Pitrou27fe9fc2009-01-26 21:48:00 +0000160
Amaury Forgeot d'Arc66f8c432009-06-09 21:30:01 +0000161 def test_large_PYTHONPATH(self):
162 with test.support.EnvironmentVarGuard() as env:
163 path1 = "ABCDE" * 100
164 path2 = "FGHIJ" * 100
165 env['PYTHONPATH'] = path1 + os.pathsep + path2
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000166 p = _spawn_python_with_env('-S', '-c',
167 'import sys; print(sys.path)')
Amaury Forgeot d'Arc66f8c432009-06-09 21:30:01 +0000168 stdout, _ = p.communicate()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000169 self.assertTrue(path1.encode('ascii') in stdout)
170 self.assertTrue(path2.encode('ascii') in stdout)
Amaury Forgeot d'Arc66f8c432009-06-09 21:30:01 +0000171
Thomas Wouters477c8d52006-05-27 19:21:47 +0000172
Neal Norwitz11bd1192005-10-03 00:54:56 +0000173def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000174 test.support.run_unittest(CmdLineTest)
175 test.support.reap_children()
Neal Norwitz11bd1192005-10-03 00:54:56 +0000176
177if __name__ == "__main__":
178 test_main()