blob: 8faa8e1986d01af1e1d300d489a31d39de119746 [file] [log] [blame]
Christian Heimes9cd17752007-11-18 19:35:23 +00001# Tests invocation of the interpreter with various command line arguments
Nick Coghland26c18a2010-08-17 13:06:11 +00002# Most tests are executed with environment variables ignored
Christian Heimes9cd17752007-11-18 19:35:23 +00003# See test_cmd_line_script.py for testing of script execution
Neal Norwitz11bd1192005-10-03 00:54:56 +00004
Benjamin Petersonee8712c2008-05-20 21:35:26 +00005import test.support, unittest
Antoine Pitrou87695762008-08-14 22:44:29 +00006import os
Christian Heimesad73a9c2013-08-10 16:36:18 +02007import shutil
Neal Norwitz11bd1192005-10-03 00:54:56 +00008import sys
Nick Coghlan260bd3e2009-11-16 06:49:25 +00009import subprocess
Victor Stinnerc0f1a1a2011-02-23 12:07:37 +000010import tempfile
Berker Peksagce643912015-05-06 06:33:17 +030011from test.support import script_helper
12from test.support.script_helper import (spawn_python, kill_python, assert_python_ok,
Ezio Melotti7c663192012-11-18 13:55:52 +020013 assert_python_failure)
Thomas Woutersed03b412007-08-28 21:37:11 +000014
Trent Nelson39e307e2008-03-19 06:45:48 +000015
Nick Coghlan260bd3e2009-11-16 06:49:25 +000016# XXX (ncoghlan): Move to script_helper and make consistent with run_python
Trent Nelson39e307e2008-03-19 06:45:48 +000017def _kill_python_and_exit_code(p):
Nick Coghlan260bd3e2009-11-16 06:49:25 +000018 data = kill_python(p)
Trent Nelson39e307e2008-03-19 06:45:48 +000019 returncode = p.wait()
20 return data, returncode
Thomas Woutersed03b412007-08-28 21:37:11 +000021
Neal Norwitz11bd1192005-10-03 00:54:56 +000022class CmdLineTest(unittest.TestCase):
Neal Norwitz11bd1192005-10-03 00:54:56 +000023 def test_directories(self):
Antoine Pitrouf51d8d32010-10-08 18:05:42 +000024 assert_python_failure('.')
25 assert_python_failure('< .')
Neal Norwitz11bd1192005-10-03 00:54:56 +000026
27 def verify_valid_flag(self, cmd_line):
Antoine Pitrouf51d8d32010-10-08 18:05:42 +000028 rc, out, err = assert_python_ok(*cmd_line)
29 self.assertTrue(out == b'' or out.endswith(b'\n'))
30 self.assertNotIn(b'Traceback', out)
31 self.assertNotIn(b'Traceback', err)
Neal Norwitz11bd1192005-10-03 00:54:56 +000032
Neal Norwitz11bd1192005-10-03 00:54:56 +000033 def test_optimize(self):
34 self.verify_valid_flag('-O')
35 self.verify_valid_flag('-OO')
36
Neal Norwitz11bd1192005-10-03 00:54:56 +000037 def test_site_flag(self):
38 self.verify_valid_flag('-S')
39
40 def test_usage(self):
Antoine Pitrouf51d8d32010-10-08 18:05:42 +000041 rc, out, err = assert_python_ok('-h')
42 self.assertIn(b'usage', out)
Neal Norwitz11bd1192005-10-03 00:54:56 +000043
44 def test_version(self):
Guido van Rossuma1c42a92007-08-29 03:47:36 +000045 version = ('Python %d.%d' % sys.version_info[:2]).encode("ascii")
Serhiy Storchakae3ed4ed2013-07-11 20:01:17 +030046 for switch in '-V', '--version':
47 rc, out, err = assert_python_ok(switch)
48 self.assertFalse(err.startswith(version))
49 self.assertTrue(out.startswith(version))
Neal Norwitz11bd1192005-10-03 00:54:56 +000050
Trent Nelson39e307e2008-03-19 06:45:48 +000051 def test_verbose(self):
52 # -v causes imports to write to stderr. If the write to
53 # stderr itself causes an import to happen (for the output
54 # codec), a recursion loop can occur.
Antoine Pitrouf51d8d32010-10-08 18:05:42 +000055 rc, out, err = assert_python_ok('-v')
56 self.assertNotIn(b'stack overflow', err)
57 rc, out, err = assert_python_ok('-vv')
58 self.assertNotIn(b'stack overflow', err)
Trent Nelson39e307e2008-03-19 06:45:48 +000059
Antoine Pitrou9583cac2010-10-21 13:42:28 +000060 def test_xoptions(self):
Victor Stinneref8115e2013-06-25 21:54:17 +020061 def get_xoptions(*args):
Berker Peksagce643912015-05-06 06:33:17 +030062 # use subprocess module directly because test.support.script_helper adds
Victor Stinneref8115e2013-06-25 21:54:17 +020063 # "-X faulthandler" to the command line
64 args = (sys.executable, '-E') + args
65 args += ('-c', 'import sys; print(sys._xoptions)')
66 out = subprocess.check_output(args)
67 opts = eval(out.splitlines()[0])
68 return opts
69
70 opts = get_xoptions()
Antoine Pitrou9583cac2010-10-21 13:42:28 +000071 self.assertEqual(opts, {})
Victor Stinneref8115e2013-06-25 21:54:17 +020072
73 opts = get_xoptions('-Xa', '-Xb=c,d=e')
Antoine Pitrou9583cac2010-10-21 13:42:28 +000074 self.assertEqual(opts, {'a': True, 'b': 'c,d=e'})
75
Ezio Melotti1f8898a2013-03-26 01:59:56 +020076 def test_showrefcount(self):
77 def run_python(*args):
78 # this is similar to assert_python_ok but doesn't strip
79 # the refcount from stderr. It can be replaced once
80 # assert_python_ok stops doing that.
81 cmd = [sys.executable]
82 cmd.extend(args)
83 PIPE = subprocess.PIPE
84 p = subprocess.Popen(cmd, stdout=PIPE, stderr=PIPE)
85 out, err = p.communicate()
86 p.stdout.close()
87 p.stderr.close()
88 rc = p.returncode
89 self.assertEqual(rc, 0)
90 return rc, out, err
91 code = 'import sys; print(sys._xoptions)'
92 # normally the refcount is hidden
93 rc, out, err = run_python('-c', code)
94 self.assertEqual(out.rstrip(), b'{}')
95 self.assertEqual(err, b'')
96 # "-X showrefcount" shows the refcount, but only in debug builds
97 rc, out, err = run_python('-X', 'showrefcount', '-c', code)
98 self.assertEqual(out.rstrip(), b"{'showrefcount': True}")
99 if hasattr(sys, 'gettotalrefcount'): # debug build
100 self.assertRegex(err, br'^\[\d+ refs, \d+ blocks\]')
101 else:
102 self.assertEqual(err, b'')
103
Thomas Wouters477c8d52006-05-27 19:21:47 +0000104 def test_run_module(self):
105 # Test expected operation of the '-m' switch
106 # Switch needs an argument
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000107 assert_python_failure('-m')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000108 # Check we get an error for a nonexistent module
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000109 assert_python_failure('-m', 'fnord43520xyz')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000110 # Check the runpy module also gives an error for
111 # a nonexistent module
Victor Stinner3fa1aae2013-03-26 01:14:08 +0100112 assert_python_failure('-m', 'runpy', 'fnord43520xyz')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000113 # All good if module is located and run successfully
Victor Stinner3fa1aae2013-03-26 01:14:08 +0100114 assert_python_ok('-m', 'timeit', '-n', '1')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000115
Thomas Woutersed03b412007-08-28 21:37:11 +0000116 def test_run_module_bug1764407(self):
117 # -m and -i need to play well together
118 # Runs the timeit module and checks the __main__
119 # namespace has been populated appropriately
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000120 p = spawn_python('-i', '-m', 'timeit', '-n', '1')
Guido van Rossuma1c42a92007-08-29 03:47:36 +0000121 p.stdin.write(b'Timer\n')
122 p.stdin.write(b'exit()\n')
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000123 data = kill_python(p)
Thomas Woutersed03b412007-08-28 21:37:11 +0000124 self.assertTrue(data.find(b'1 loop') != -1)
125 self.assertTrue(data.find(b'__main__.Timer') != -1)
126
Thomas Wouters477c8d52006-05-27 19:21:47 +0000127 def test_run_code(self):
128 # Test expected operation of the '-c' switch
129 # Switch needs an argument
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000130 assert_python_failure('-c')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000131 # Check we get an error for an uncaught exception
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000132 assert_python_failure('-c', 'raise Exception')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000133 # All good if execution is successful
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000134 assert_python_ok('-c', 'pass')
Thomas Wouters477c8d52006-05-27 19:21:47 +0000135
Victor Stinner8b219b22012-11-06 23:23:43 +0100136 @unittest.skipUnless(test.support.FS_NONASCII, 'need support.FS_NONASCII')
Victor Stinner073f7592010-10-20 21:56:55 +0000137 def test_non_ascii(self):
Amaury Forgeot d'Arc9a5499b2008-11-11 23:04:59 +0000138 # Test handling of non-ascii data
Victor Stinner8b219b22012-11-06 23:23:43 +0100139 command = ("assert(ord(%r) == %s)"
140 % (test.support.FS_NONASCII, ord(test.support.FS_NONASCII)))
Victor Stinner073f7592010-10-20 21:56:55 +0000141 assert_python_ok('-c', command)
Amaury Forgeot d'Arc9a5499b2008-11-11 23:04:59 +0000142
Victor Stinnerf6211ed2010-10-20 21:52:33 +0000143 # On Windows, pass bytes to subprocess doesn't test how Python decodes the
144 # command line, but how subprocess does decode bytes to unicode. Python
145 # doesn't decode the command line because Windows provides directly the
146 # arguments as unicode (using wmain() instead of main()).
147 @unittest.skipIf(sys.platform == 'win32',
148 'Windows has a native unicode API')
149 def test_undecodable_code(self):
150 undecodable = b"\xff"
151 env = os.environ.copy()
152 # Use C locale to get ascii for the locale encoding
153 env['LC_ALL'] = 'C'
154 code = (
155 b'import locale; '
156 b'print(ascii("' + undecodable + b'"), '
157 b'locale.getpreferredencoding())')
158 p = subprocess.Popen(
159 [sys.executable, "-c", code],
160 stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
161 env=env)
162 stdout, stderr = p.communicate()
163 if p.returncode == 1:
164 # _Py_char2wchar() decoded b'\xff' as '\udcff' (b'\xff' is not
165 # decodable from ASCII) and run_command() failed on
166 # PyUnicode_AsUTF8String(). This is the expected behaviour on
167 # Linux.
168 pattern = b"Unable to decode the command from the command line:"
169 elif p.returncode == 0:
170 # _Py_char2wchar() decoded b'\xff' as '\xff' even if the locale is
171 # C and the locale encoding is ASCII. It occurs on FreeBSD, Solaris
172 # and Mac OS X.
173 pattern = b"'\\xff' "
174 # The output is followed by the encoding name, an alias to ASCII.
175 # Examples: "US-ASCII" or "646" (ISO 646, on Solaris).
176 else:
177 raise AssertionError("Unknown exit code: %s, output=%a" % (p.returncode, stdout))
178 if not stdout.startswith(pattern):
179 raise AssertionError("%a doesn't start with %a" % (stdout, pattern))
180
Victor Stinnerf933e1a2010-10-20 22:58:25 +0000181 @unittest.skipUnless(sys.platform == 'darwin', 'test specific to Mac OS X')
182 def test_osx_utf8(self):
183 def check_output(text):
Marc-André Lemburg8f36af72011-02-25 15:42:01 +0000184 decoded = text.decode('utf-8', 'surrogateescape')
Victor Stinnerf933e1a2010-10-20 22:58:25 +0000185 expected = ascii(decoded).encode('ascii') + b'\n'
186
187 env = os.environ.copy()
188 # C locale gives ASCII locale encoding, but Python uses UTF-8
189 # to parse the command line arguments on Mac OS X
190 env['LC_ALL'] = 'C'
191
192 p = subprocess.Popen(
193 (sys.executable, "-c", "import sys; print(ascii(sys.argv[1]))", text),
194 stdout=subprocess.PIPE,
195 env=env)
196 stdout, stderr = p.communicate()
197 self.assertEqual(stdout, expected)
198 self.assertEqual(p.returncode, 0)
199
200 # test valid utf-8
201 text = 'e:\xe9, euro:\u20ac, non-bmp:\U0010ffff'.encode('utf-8')
202 check_output(text)
203
204 # test invalid utf-8
205 text = (
206 b'\xff' # invalid byte
207 b'\xc3\xa9' # valid utf-8 character
208 b'\xc3\xff' # invalid byte sequence
209 b'\xed\xa0\x80' # lone surrogate character (invalid)
210 )
211 check_output(text)
212
Antoine Pitrou05608432009-01-09 18:53:14 +0000213 def test_unbuffered_output(self):
214 # Test expected operation of the '-u' switch
215 for stream in ('stdout', 'stderr'):
216 # Binary is unbuffered
217 code = ("import os, sys; sys.%s.buffer.write(b'x'); os._exit(0)"
218 % stream)
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000219 rc, out, err = assert_python_ok('-u', '-c', code)
220 data = err if stream == 'stderr' else out
Antoine Pitrou05608432009-01-09 18:53:14 +0000221 self.assertEqual(data, b'x', "binary %s not unbuffered" % stream)
222 # Text is line-buffered
223 code = ("import os, sys; sys.%s.write('x\\n'); os._exit(0)"
224 % stream)
Antoine Pitrouf51d8d32010-10-08 18:05:42 +0000225 rc, out, err = assert_python_ok('-u', '-c', code)
226 data = err if stream == 'stderr' else out
Antoine Pitrou05608432009-01-09 18:53:14 +0000227 self.assertEqual(data.strip(), b'x',
228 "text %s not line-buffered" % stream)
229
Antoine Pitrou27fe9fc2009-01-26 21:48:00 +0000230 def test_unbuffered_input(self):
231 # sys.stdin still works with '-u'
232 code = ("import sys; sys.stdout.write(sys.stdin.read(1))")
Nick Coghlan260bd3e2009-11-16 06:49:25 +0000233 p = spawn_python('-u', '-c', code)
Antoine Pitrou27fe9fc2009-01-26 21:48:00 +0000234 p.stdin.write(b'x')
235 p.stdin.flush()
236 data, rc = _kill_python_and_exit_code(p)
237 self.assertEqual(rc, 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000238 self.assertTrue(data.startswith(b'x'), data)
Antoine Pitrou27fe9fc2009-01-26 21:48:00 +0000239
Amaury Forgeot d'Arc66f8c432009-06-09 21:30:01 +0000240 def test_large_PYTHONPATH(self):
Antoine Pitrou9bc35682010-11-09 21:33:55 +0000241 path1 = "ABCDE" * 100
242 path2 = "FGHIJ" * 100
243 path = path1 + os.pathsep + path2
Victor Stinner76cf6872010-04-16 15:10:27 +0000244
Antoine Pitrou9bc35682010-11-09 21:33:55 +0000245 code = """if 1:
246 import sys
247 path = ":".join(sys.path)
248 path = path.encode("ascii", "backslashreplace")
249 sys.stdout.buffer.write(path)"""
250 rc, out, err = assert_python_ok('-S', '-c', code,
251 PYTHONPATH=path)
252 self.assertIn(path1.encode('ascii'), out)
253 self.assertIn(path2.encode('ascii'), out)
Amaury Forgeot d'Arc66f8c432009-06-09 21:30:01 +0000254
Andrew Svetlov69032c82012-11-03 13:52:58 +0200255 def test_empty_PYTHONPATH_issue16309(self):
Ezio Melotti32f4e6e2012-11-23 01:51:20 +0200256 # On Posix, it is documented that setting PATH to the
257 # empty string is equivalent to not setting PATH at all,
258 # which is an exception to the rule that in a string like
259 # "/bin::/usr/bin" the empty string in the middle gets
260 # interpreted as '.'
Andrew Svetlov69032c82012-11-03 13:52:58 +0200261 code = """if 1:
262 import sys
263 path = ":".join(sys.path)
264 path = path.encode("ascii", "backslashreplace")
265 sys.stdout.buffer.write(path)"""
266 rc1, out1, err1 = assert_python_ok('-c', code, PYTHONPATH="")
Victor Stinnere8785ff2013-10-12 14:44:01 +0200267 rc2, out2, err2 = assert_python_ok('-c', code, __isolated=False)
Andrew Svetlov69032c82012-11-03 13:52:58 +0200268 # regarding to Posix specification, outputs should be equal
269 # for empty and unset PYTHONPATH
Ezio Melotti32f4e6e2012-11-23 01:51:20 +0200270 self.assertEqual(out1, out2)
Andrew Svetlov69032c82012-11-03 13:52:58 +0200271
Victor Stinner13d49ee2010-12-04 17:24:33 +0000272 def test_displayhook_unencodable(self):
Marc-André Lemburg8f36af72011-02-25 15:42:01 +0000273 for encoding in ('ascii', 'latin-1', 'utf-8'):
R David Murrayf4bbc532015-04-14 17:57:41 -0400274 # We are testing a PYTHON environment variable here, so we can't
275 # use -E, -I, or script_helper (which uses them). So instead we do
276 # poor-man's isolation by deleting the PYTHON vars from env.
277 env = {key:value for (key,value) in os.environ.copy().items()
278 if not key.startswith('PYTHON')}
Victor Stinner13d49ee2010-12-04 17:24:33 +0000279 env['PYTHONIOENCODING'] = encoding
280 p = subprocess.Popen(
281 [sys.executable, '-i'],
282 stdin=subprocess.PIPE,
283 stdout=subprocess.PIPE,
284 stderr=subprocess.STDOUT,
285 env=env)
286 # non-ascii, surrogate, non-BMP printable, non-BMP unprintable
287 text = "a=\xe9 b=\uDC80 c=\U00010000 d=\U0010FFFF"
288 p.stdin.write(ascii(text).encode('ascii') + b"\n")
289 p.stdin.write(b'exit()\n')
290 data = kill_python(p)
291 escaped = repr(text).encode(encoding, 'backslashreplace')
292 self.assertIn(escaped, data)
293
Victor Stinnerc0f1a1a2011-02-23 12:07:37 +0000294 def check_input(self, code, expected):
295 with tempfile.NamedTemporaryFile("wb+") as stdin:
296 sep = os.linesep.encode('ASCII')
297 stdin.write(sep.join((b'abc', b'def')))
298 stdin.flush()
299 stdin.seek(0)
300 with subprocess.Popen(
301 (sys.executable, "-c", code),
302 stdin=stdin, stdout=subprocess.PIPE) as proc:
303 stdout, stderr = proc.communicate()
304 self.assertEqual(stdout.rstrip(), expected)
305
306 def test_stdin_readline(self):
307 # Issue #11272: check that sys.stdin.readline() replaces '\r\n' by '\n'
308 # on Windows (sys.stdin is opened in binary mode)
309 self.check_input(
310 "import sys; print(repr(sys.stdin.readline()))",
311 b"'abc\\n'")
312
313 def test_builtin_input(self):
314 # Issue #11272: check that input() strips newlines ('\n' or '\r\n')
315 self.check_input(
316 "print(repr(input()))",
317 b"'abc'")
318
Victor Stinner7b3f0fa2012-08-04 01:28:00 +0200319 def test_output_newline(self):
320 # Issue 13119 Newline for print() should be \r\n on Windows.
321 code = """if 1:
322 import sys
323 print(1)
324 print(2)
325 print(3, file=sys.stderr)
326 print(4, file=sys.stderr)"""
327 rc, out, err = assert_python_ok('-c', code)
328
329 if sys.platform == 'win32':
330 self.assertEqual(b'1\r\n2\r\n', out)
331 self.assertEqual(b'3\r\n4', err)
332 else:
333 self.assertEqual(b'1\n2\n', out)
334 self.assertEqual(b'3\n4', err)
335
R David Murraye697e372011-06-24 13:26:31 -0400336 def test_unmached_quote(self):
337 # Issue #10206: python program starting with unmatched quote
338 # spewed spaces to stdout
339 rc, out, err = assert_python_failure('-c', "'")
340 self.assertRegex(err.decode('ascii', 'ignore'), 'SyntaxError')
341 self.assertEqual(b'', out)
342
Antoine Pitroud7c8fbf2011-11-26 21:59:36 +0100343 def test_stdout_flush_at_shutdown(self):
344 # Issue #5319: if stdout.flush() fails at shutdown, an error should
345 # be printed out.
346 code = """if 1:
Steve Dower79938f22015-03-07 20:32:16 -0800347 import os, sys, test.support
348 test.support.SuppressCrashReport().__enter__()
Antoine Pitroud7c8fbf2011-11-26 21:59:36 +0100349 sys.stdout.write('x')
350 os.close(sys.stdout.fileno())"""
Martin Panterb4ce1fc2015-11-30 03:18:29 +0000351 rc, out, err = assert_python_failure('-c', code)
Antoine Pitroud7c8fbf2011-11-26 21:59:36 +0100352 self.assertEqual(b'', out)
Martin Panterb4ce1fc2015-11-30 03:18:29 +0000353 self.assertEqual(120, rc)
Antoine Pitroud7c8fbf2011-11-26 21:59:36 +0100354 self.assertRegex(err.decode('ascii', 'ignore'),
Andrew Svetlov76bcff22012-11-03 15:56:05 +0200355 'Exception ignored in.*\nOSError: .*')
Antoine Pitroud7c8fbf2011-11-26 21:59:36 +0100356
357 def test_closed_stdout(self):
358 # Issue #13444: if stdout has been explicitly closed, we should
359 # not attempt to flush it at shutdown.
360 code = "import sys; sys.stdout.close()"
361 rc, out, err = assert_python_ok('-c', code)
362 self.assertEqual(b'', err)
363
Antoine Pitrou11942a52011-11-28 19:08:36 +0100364 # Issue #7111: Python should work without standard streams
365
366 @unittest.skipIf(os.name != 'posix', "test needs POSIX semantics")
367 def _test_no_stdio(self, streams):
368 code = """if 1:
369 import os, sys
370 for i, s in enumerate({streams}):
371 if getattr(sys, s) is not None:
372 os._exit(i + 1)
373 os._exit(42)""".format(streams=streams)
374 def preexec():
375 if 'stdin' in streams:
376 os.close(0)
377 if 'stdout' in streams:
378 os.close(1)
379 if 'stderr' in streams:
380 os.close(2)
381 p = subprocess.Popen(
382 [sys.executable, "-E", "-c", code],
383 stdin=subprocess.PIPE,
384 stdout=subprocess.PIPE,
385 stderr=subprocess.PIPE,
386 preexec_fn=preexec)
387 out, err = p.communicate()
388 self.assertEqual(test.support.strip_python_stderr(err), b'')
389 self.assertEqual(p.returncode, 42)
390
391 def test_no_stdin(self):
392 self._test_no_stdio(['stdin'])
393
394 def test_no_stdout(self):
395 self._test_no_stdio(['stdout'])
396
397 def test_no_stderr(self):
398 self._test_no_stdio(['stderr'])
399
400 def test_no_std_streams(self):
401 self._test_no_stdio(['stdin', 'stdout', 'stderr'])
402
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100403 def test_hash_randomization(self):
404 # Verify that -R enables hash randomization:
405 self.verify_valid_flag('-R')
406 hashes = []
Gregory P. Smith220ba722015-12-13 20:01:44 -0800407 if os.environ.get('PYTHONHASHSEED', 'random') != 'random':
408 env = dict(os.environ) # copy
409 # We need to test that it is enabled by default without
410 # the environment variable enabling it for us.
411 del env['PYTHONHASHSEED']
412 env['__cleanenv'] = '1' # consumed by assert_python_ok()
413 else:
414 env = {}
415 for i in range(3):
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100416 code = 'print(hash("spam"))'
Gregory P. Smith220ba722015-12-13 20:01:44 -0800417 rc, out, err = assert_python_ok('-c', code, **env)
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100418 self.assertEqual(rc, 0)
Georg Brandl09a7c722012-02-20 21:31:46 +0100419 hashes.append(out)
Gregory P. Smith220ba722015-12-13 20:01:44 -0800420 hashes = sorted(set(hashes)) # uniq
421 # Rare chance of failure due to 3 random seeds honestly being equal.
422 self.assertGreater(len(hashes), 1,
423 msg='3 runs produced an identical random hash '
424 ' for "spam": {}'.format(hashes))
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100425
426 # Verify that sys.flags contains hash_randomization
427 code = 'import sys; print("random is", sys.flags.hash_randomization)'
Benjamin Petersonc9f54cf2012-02-21 16:08:05 -0500428 rc, out, err = assert_python_ok('-c', code)
Georg Brandl2daf6ae2012-02-20 19:54:16 +0100429 self.assertEqual(rc, 0)
Georg Brandl09a7c722012-02-20 21:31:46 +0100430 self.assertIn(b'random is 1', out)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000431
Hynek Schlawack5c6b3e22012-11-07 09:02:24 +0100432 def test_del___main__(self):
433 # Issue #15001: PyRun_SimpleFileExFlags() did crash because it kept a
434 # borrowed reference to the dict of __main__ module and later modify
435 # the dict whereas the module was destroyed
436 filename = test.support.TESTFN
437 self.addCleanup(test.support.unlink, filename)
438 with open(filename, "w") as script:
439 print("import sys", file=script)
440 print("del sys.modules['__main__']", file=script)
441 assert_python_ok(filename)
442
Ezio Melotti7c663192012-11-18 13:55:52 +0200443 def test_unknown_options(self):
Ezio Melottia0dd22e2012-11-23 18:48:32 +0200444 rc, out, err = assert_python_failure('-E', '-z')
445 self.assertIn(b'Unknown option: -z', err)
Ezio Melotti7c663192012-11-18 13:55:52 +0200446 self.assertEqual(err.splitlines().count(b'Unknown option: -z'), 1)
447 self.assertEqual(b'', out)
Gregory P. Smith48e81002015-01-22 22:55:00 -0800448 # Add "without='-E'" to prevent _assert_python to append -E
449 # to env_vars and change the output of stderr
450 rc, out, err = assert_python_failure('-z', without='-E')
Ezio Melottia0dd22e2012-11-23 18:48:32 +0200451 self.assertIn(b'Unknown option: -z', err)
452 self.assertEqual(err.splitlines().count(b'Unknown option: -z'), 1)
453 self.assertEqual(b'', out)
Gregory P. Smith48e81002015-01-22 22:55:00 -0800454 rc, out, err = assert_python_failure('-a', '-z', without='-E')
Ezio Melottia0dd22e2012-11-23 18:48:32 +0200455 self.assertIn(b'Unknown option: -a', err)
456 # only the first unknown option is reported
457 self.assertNotIn(b'Unknown option: -z', err)
458 self.assertEqual(err.splitlines().count(b'Unknown option: -a'), 1)
459 self.assertEqual(b'', out)
460
Gregory P. Smith8f2fae12015-02-04 01:04:31 -0800461 @unittest.skipIf(script_helper.interpreter_requires_environment(),
Gregory P. Smithb9a3dd92015-02-04 00:59:40 -0800462 'Cannot run -I tests when PYTHON env vars are required.')
Christian Heimesad73a9c2013-08-10 16:36:18 +0200463 def test_isolatedmode(self):
464 self.verify_valid_flag('-I')
465 self.verify_valid_flag('-IEs')
466 rc, out, err = assert_python_ok('-I', '-c',
467 'from sys import flags as f; '
468 'print(f.no_user_site, f.ignore_environment, f.isolated)',
469 # dummyvar to prevent extranous -E
470 dummyvar="")
471 self.assertEqual(out.strip(), b'1 1 1')
472 with test.support.temp_cwd() as tmpdir:
473 fake = os.path.join(tmpdir, "uuid.py")
474 main = os.path.join(tmpdir, "main.py")
475 with open(fake, "w") as f:
476 f.write("raise RuntimeError('isolated mode test')\n")
477 with open(main, "w") as f:
478 f.write("import uuid\n")
479 f.write("print('ok')\n")
480 self.assertRaises(subprocess.CalledProcessError,
481 subprocess.check_output,
482 [sys.executable, main], cwd=tmpdir,
483 stderr=subprocess.DEVNULL)
484 out = subprocess.check_output([sys.executable, "-I", main],
485 cwd=tmpdir)
486 self.assertEqual(out.strip(), b"ok")
487
Neal Norwitz11bd1192005-10-03 00:54:56 +0000488def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000489 test.support.run_unittest(CmdLineTest)
490 test.support.reap_children()
Neal Norwitz11bd1192005-10-03 00:54:56 +0000491
492if __name__ == "__main__":
493 test_main()