def test_assert_python_failure_raises(self): with self.assertRaises(AssertionError) as error_context: script_helper.assert_python_failure('-c', 'import sys; sys.exit(0)') error_msg = str(error_context.exception) self.assertIn('Process return code is 0,', error_msg) self.assertIn('import sys; sys.exit(0)', error_msg, msg='unexpected command line.')
def test_exit(self): # call with two arguments self.assertRaises(TypeError, sys.exit, 42, 42) # call without argument with self.assertRaises(SystemExit) as cm: sys.exit() self.assertIsNone(cm.exception.code) rc, out, err = assert_python_ok("-c", "import sys; sys.exit()") self.assertEqual(rc, 0) self.assertEqual(out, b"") self.assertEqual(err, b"") # call with integer argument with self.assertRaises(SystemExit) as cm: sys.exit(42) self.assertEqual(cm.exception.code, 42) # call with tuple argument with one entry # entry will be unpacked with self.assertRaises(SystemExit) as cm: sys.exit((42,)) self.assertEqual(cm.exception.code, 42) # call with string argument with self.assertRaises(SystemExit) as cm: sys.exit("exit") self.assertEqual(cm.exception.code, "exit") # call with tuple argument with two entries with self.assertRaises(SystemExit) as cm: sys.exit((17, 23)) self.assertEqual(cm.exception.code, (17, 23)) # test that the exit machinery handles SystemExits properly # both unnormalized... rc, out, err = assert_python_failure("-c", "raise SystemExit, 46") self.assertEqual(rc, 46) self.assertEqual(out, b"") self.assertEqual(err, b"") # ... and normalized rc, out, err = assert_python_failure("-c", "raise SystemExit(47)") self.assertEqual(rc, 47) self.assertEqual(out, b"") self.assertEqual(err, b"") def check_exit_message(code, expected, **env_vars): rc, out, err = assert_python_failure("-c", code, **env_vars) self.assertEqual(rc, 1) self.assertEqual(out, b"") self.assertTrue(err.startswith(expected), "%s doesn't start with %s" % (repr(err), repr(expected))) # test that stderr buffer is flushed before the exit message is written # into stderr check_exit_message(r'import sys; sys.stderr.write("unflushed,"); sys.exit("message")', b"unflushed,message") # test that the unicode message is encoded to the stderr encoding check_exit_message(r'import sys; sys.exit(u"h\xe9")', b"h\xe9", PYTHONIOENCODING="latin-1")
def test_run_code(self): # Test expected operation of the '-c' switch # Switch needs an argument assert_python_failure('-c') # Check we get an error for an uncaught exception assert_python_failure('-c', 'raise Exception') # All good if execution is successful assert_python_ok('-c', 'pass')
def test_crashers_crash(self): for fname in glob.glob(CRASHER_FILES): if os.path.basename(fname) in infinite_loops: continue # Some "crashers" only trigger an exception rather than a # segfault. Consider that an acceptable outcome. if test.support.verbose: print("Checking crasher:", fname) assert_python_failure(fname)
def test_return_result_with_error(self): # Issue #23571: A function must not return a result with an error set if Py_DEBUG: code = textwrap.dedent(""" import _testcapi from test import support with support.SuppressCrashReport(): _testcapi.return_result_with_error() """) rc, out, err = assert_python_failure('-c', code) self.assertRegex(err.replace(b'\r', b''), br'Fatal Python error: a function returned a ' br'result with an error set\n' br'ValueError\n' br'\n' br'During handling of the above exception, ' br'another exception occurred:\n' br'\n' br'SystemError: <built-in ' br'function return_result_with_error> ' br'returned a result with an error set\n' br'\n' br'Current thread.*:\n' br' File .*, line 6 in <module>') else: with self.assertRaises(SystemError) as cm: _testcapi.return_result_with_error() self.assertRegex(str(cm.exception), 'return_result_with_error.* ' 'returned a result with an error set')
def test_finalize_runnning_thread(self): # Issue 1402: the PyGILState_Ensure / _Release functions may be called # very late on python exit: on deallocation of a running thread for # example. import_module("ctypes") rc, out, err = assert_python_failure( "-c", """if 1: import ctypes, sys, time, _thread # This lock is used as a simple event variable. ready = _thread.allocate_lock() ready.acquire() # Module globals are cleared before __del__ is run # So we save the functions in class dict class C: ensure = ctypes.pythonapi.PyGILState_Ensure release = ctypes.pythonapi.PyGILState_Release def __del__(self): state = self.ensure() self.release(state) def waitingThread(): x = C() ready.release() time.sleep(100) _thread.start_new_thread(waitingThread, ()) ready.acquire() # Be sure the other thread is waiting. sys.exit(42) """, ) self.assertEqual(rc, 42)
def test_trigger_memory_error(self): e = self._nested_expression(100) rc, out, err = assert_python_failure('-c', e) # parsing the expression will result in an error message # followed by a MemoryError (see #11963) self.assertIn(b's_push: parser stack overflow', err) self.assertIn(b'MemoryError', err)
def test_return_result_with_error(self): # Issue #23571: A function must not return a result with an error set if Py_DEBUG: code = textwrap.dedent(""" import _testcapi from test import support with support.SuppressCrashReport(): _testcapi.return_result_with_error() """) rc, out, err = assert_python_failure('-c', code) self.assertRegex( err.replace(b'\r', b''), br'Fatal Python error: a function returned a ' br'result with an error set\n' br'ValueError\n' br'\n' br'During handling of the above exception, ' br'another exception occurred:\n' br'\n' br'SystemError: <built-in ' br'function return_result_with_error> ' br'returned a result with an error set\n' br'\n' br'Current thread.*:\n' br' File .*, line 6 in <module>') else: with self.assertRaises(SystemError) as cm: _testcapi.return_result_with_error() self.assertRegex( str(cm.exception), 'return_result_with_error.* ' 'returned a result with an error set')
def test_finalize_runnning_thread(self): # Issue 1402: the PyGILState_Ensure / _Release functions may be called # very late on python exit: on deallocation of a running thread for # example. import_module("ctypes") rc, out, err = assert_python_failure( "-c", """if 1: import ctypes, sys, time, _thread # This lock is used as a simple event variable. ready = _thread.allocate_lock() ready.acquire() # Module globals are cleared before __del__ is run # So we save the functions in class dict class C: ensure = ctypes.pythonapi.PyGILState_Ensure release = ctypes.pythonapi.PyGILState_Release def __del__(self): state = self.ensure() self.release(state) def waitingThread(): x = C() ready.release() time.sleep(100) _thread.start_new_thread(waitingThread, ()) ready.acquire() # Be sure the other thread is waiting. sys.exit(42) """) self.assertEqual(rc, 42)
def test_return_null_without_error(self): # Issue #23571: A function must not return NULL without setting an # error if Py_DEBUG: code = textwrap.dedent(""" import _testcapi from test import support with support.SuppressCrashReport(): _testcapi.return_null_without_error() """) rc, out, err = assert_python_failure('-c', code) self.assertRegex(err.replace(b'\r', b''), br'Fatal Python error: a function returned NULL ' br'without setting an error\n' br'SystemError: <built-in function ' br'return_null_without_error> returned NULL ' br'without setting an error\n' br'\n' br'Current thread.*:\n' br' File .*", line 6 in <module>') else: with self.assertRaises(SystemError) as cm: _testcapi.return_null_without_error() self.assertRegex(str(cm.exception), 'return_null_without_error.* ' 'returned NULL without setting an error')
def test_return_null_without_error(self): # Issue #23571: A function must not return NULL without setting an # error if Py_DEBUG: code = textwrap.dedent(""" import _testcapi from test import support with support.SuppressCrashReport(): _testcapi.return_null_without_error() """) rc, out, err = assert_python_failure('-c', code) self.assertRegex( err.replace(b'\r', b''), br'Fatal Python error: a function returned NULL ' br'without setting an error\n' br'SystemError: <built-in function ' br'return_null_without_error> returned NULL ' br'without setting an error\n' br'\n' br'Current thread.*:\n' br' File .*", line 6 in <module>') else: with self.assertRaises(SystemError) as cm: _testcapi.return_null_without_error() self.assertRegex( str(cm.exception), 'return_null_without_error.* ' 'returned NULL without setting an error')
def test_sys_xoptions_invalid(self): for nframe in (-1, 0, 2 ** 30): with self.subTest(nframe=nframe): with support.SuppressCrashReport(): args = ("-X", "tracemalloc=%s" % nframe, "-c", "pass") ok, stdout, stderr = assert_python_failure(*args) self.assertIn(b"-X tracemalloc=NFRAME: invalid " b"number of frames", stderr)
def check_exit_message(code, expected, **env_vars): rc, out, err = assert_python_failure('-c', code, **env_vars) self.assertEqual(rc, 1) self.assertEqual(out, b'') self.assertTrue( err.startswith(expected), "%s doesn't start with %s" % (repr(err), repr(expected)))
def test_unknown_options(self): rc, out, err = assert_python_failure('-E', '-z') self.assertIn(b'Unknown option: -z', err) self.assertEqual(err.splitlines().count(b'Unknown option: -z'), 1) self.assertEqual(b'', out) # Add "without='-E'" to prevent _assert_python to append -E # to env_vars and change the output of stderr rc, out, err = assert_python_failure('-z', without='-E') self.assertIn(b'Unknown option: -z', err) self.assertEqual(err.splitlines().count(b'Unknown option: -z'), 1) self.assertEqual(b'', out) rc, out, err = assert_python_failure('-a', '-z', without='-E') self.assertIn(b'Unknown option: -a', err) # only the first unknown option is reported self.assertNotIn(b'Unknown option: -z', err) self.assertEqual(err.splitlines().count(b'Unknown option: -a'), 1) self.assertEqual(b'', out)
def _check_import_error(self, script_name, expected_msg, *cmd_line_switches): run_args = cmd_line_switches + (script_name,) rc, out, err = assert_python_failure(*run_args) if verbose > 1: print("Output from test script %r:" % script_name) print(err) print("Expected output: %r" % expected_msg) self.assertIn(expected_msg.encode("utf-8"), err)
def test_sys_xoptions_invalid(self): for nframe in (-1, 0, 2**30): with self.subTest(nframe=nframe): with support.SuppressCrashReport(): args = ('-X', 'tracemalloc=%s' % nframe, '-c', 'pass') ok, stdout, stderr = assert_python_failure(*args) self.assertIn(b'-X tracemalloc=NFRAME: invalid ' b'number of frames', stderr)
def test_sys_xoptions_invalid(self): for nframe in (-1, 0, 5000): with self.subTest(nframe=nframe): with support.SuppressCrashReport(): args = ('-X', 'tracemalloc=%s' % nframe, '-c', 'pass') ok, stdout, stderr = assert_python_failure(*args) self.assertIn(b'-X tracemalloc=NFRAME: number of frame must ' b'be an integer in range [1; 100]', stderr)
def test_d_runtime_error(self): bazfn = script_helper.make_script(self.pkgdir, "baz", "raise Exception") self.assertRunOK("-q", "-d", "dinsdale", self.pkgdir) fn = script_helper.make_script(self.pkgdir, "bing", "import baz") pyc = importlib.util.cache_from_source(bazfn) os.rename(pyc, os.path.join(self.pkgdir, "baz.pyc")) os.remove(bazfn) rc, out, err = script_helper.assert_python_failure(fn, __isolated=False) self.assertRegex(err, b'File "dinsdale')
def test_d_runtime_error(self): bazfn = script_helper.make_script(self.pkgdir, 'baz', 'raise Exception') self.assertRunOK('-q', '-d', 'dinsdale', self.pkgdir) fn = script_helper.make_script(self.pkgdir, 'bing', 'import baz') pyc = importlib.util.cache_from_source(bazfn) os.rename(pyc, os.path.join(self.pkgdir, 'baz.pyc')) os.remove(bazfn) rc, out, err = script_helper.assert_python_failure(fn, __isolated=False) self.assertRegex(err, b'File "dinsdale')
def test_env_var_invalid(self): for nframe in (-1, 0, 2**30): with self.subTest(nframe=nframe): with support.SuppressCrashReport(): ok, stdout, stderr = assert_python_failure( '-c', 'pass', PYTHONTRACEMALLOC=str(nframe)) self.assertIn( b'PYTHONTRACEMALLOC: invalid ' b'number of frames', stderr)
def _check_import_error(self, script_name, expected_msg, *cmd_line_switches): run_args = cmd_line_switches + (script_name,) rc, out, err = assert_python_failure(*run_args) if verbose > 1: print('Output from test script %r:' % script_name) print(err) print('Expected output: %r' % expected_msg) self.assertIn(expected_msg.encode('utf-8'), err)
def test_env_var_invalid(self): for nframe in (-1, 0, 5000): with self.subTest(nframe=nframe): with support.SuppressCrashReport(): ok, stdout, stderr = assert_python_failure( '-c', 'pass', PYTHONTRACEMALLOC=str(nframe)) self.assertIn(b'PYTHONTRACEMALLOC must be an integer ' b'in range [1; 100]', stderr)
def test_env_var_invalid(self): for nframe in (-1, 0, 2**30): with self.subTest(nframe=nframe): with support.SuppressCrashReport(): ok, stdout, stderr = assert_python_failure( '-c', 'pass', PYTHONTRACEMALLOC=str(nframe)) self.assertIn(b'PYTHONTRACEMALLOC: invalid ' b'number of frames', stderr)
def test_syshook_no_logdir_text_format(self): # Issue 12890: we were emitting the <p> tag in text mode. with temp_dir() as tracedir: rc, out, err = assert_python_failure( '-c', ('import cgitb; cgitb.enable(format="text", logdir=%s); ' 'raise ValueError("Hello World")') % repr(tracedir)) out = out.decode(sys.getfilesystemencoding()) self.assertIn("ValueError", out) self.assertIn("Hello World", out) self.assertNotIn('<p>', out) self.assertNotIn('</p>', out)
def test_syshook_no_logdir_default_format(self): with temp_dir() as tracedir: rc, out, err = assert_python_failure( '-c', ('import cgitb; cgitb.enable(logdir=%s); ' 'raise ValueError("Hello World")') % repr(tracedir)) out = out.decode(sys.getfilesystemencoding()) self.assertIn("ValueError", out) self.assertIn("Hello World", out) # By default we emit HTML markup. self.assertIn('<p>', out) self.assertIn('</p>', out)
def test_conflicting_envvar_and_command_line(self): rc, stdout, stderr = assert_python_failure("-Werror::DeprecationWarning", "-c", "import sys, warnings; sys.stdout.write(str(sys.warnoptions)); " "warnings.warn('Message', DeprecationWarning)", PYTHONWARNINGS="default::DeprecationWarning") self.assertEqual(stdout, b"['default::DeprecationWarning', 'error::DeprecationWarning']") self.assertEqual(stderr.splitlines(), [b"Traceback (most recent call last):", b" File \"<string>\", line 1, in <module>", b"DeprecationWarning: Message"])
def test_yet_more_evil_still_undecodable(self): # Issue #25388 src = b"#\x00\n#\xfd\n" tmpd = tempfile.mkdtemp() try: fn = os.path.join(tmpd, "bad.py") with open(fn, "wb") as fp: fp.write(src) rc, out, err = script_helper.assert_python_failure(fn) finally: test_support.rmtree(tmpd) self.assertIn(b"Non-ASCII", err)
def test_dash_m_error_code_is_one(self): # If a module is invoked with the -m command line flag # and results in an error that the return code to the # shell is '1' with temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') make_pkg(pkg_dir) script_name = _make_test_script(pkg_dir, 'other', "if __name__ == '__main__': raise ValueError") rc, out, err = assert_python_failure('-m', 'test_pkg.other', *example_args) if verbose > 1: print(out) self.assertEqual(rc, 1)
def test_dash_m_errors(self): # Exercise error reporting for various invalid package executions tests = ( ('__builtin__', br'No code object available'), ('__builtin__.x', br'No module named'), ('__builtin__.x.y', br'No module named'), ('os.path', br'Loader.*cannot handle'), ('importlib', br'No module named.*' br'is a package and cannot be directly executed'), ('importlib.nonexistant', br'No module named'), ) for name, regex in tests: rc, _, err = assert_python_failure('-m', name) self.assertEqual(rc, 1) self.assertRegexpMatches(err, regex) self.assertNotIn(b'Traceback', err)
def test_run_module(self): # Test expected operation of the '-m' switch # Switch needs an argument assert_python_failure('-m') # Check we get an error for a nonexistent module assert_python_failure('-m', 'fnord43520xyz') # Check the runpy module also gives an error for # a nonexistent module assert_python_failure('-m', 'runpy', 'fnord43520xyz') # All good if module is located and run successfully assert_python_ok('-m', 'timeit', '-n', '1')
def test_run_module(self): # Test expected operation of the '-m' switch # Switch needs an argument assert_python_failure('-m') # Check we get an error for a nonexistent module assert_python_failure('-m', 'fnord43520xyz') # Check the runpy module also gives an error for # a nonexistent module assert_python_failure('-m', 'runpy', 'fnord43520xyz'), # All good if module is located and run successfully assert_python_ok('-m', 'timeit', '-n', '1'),
def test_issue20500_exit_with_exception_value(self): script = textwrap.dedent("""\ import sys error = None try: raise ValueError('some text') except ValueError as err: error = err if error: sys.exit(error) """) with temp_dir() as script_dir: script_name = _make_test_script(script_dir, 'script', script) exitcode, stdout, stderr = assert_python_failure(script_name) text = stderr.decode('ascii') self.assertEqual(text, "some text")
def test_pep_409_verbiage(self): # Make sure PEP 409 syntax properly suppresses # the context of an exception script = textwrap.dedent("""\ try: raise ValueError except: raise NameError from None """) with temp_dir() as script_dir: script_name = _make_test_script(script_dir, 'script', script) exitcode, stdout, stderr = assert_python_failure(script_name) text = stderr.decode('ascii').split('\n') self.assertEqual(len(text), 4) self.assertTrue(text[0].startswith('Traceback')) self.assertTrue(text[1].startswith(' File ')) self.assertTrue(text[3].startswith('NameError'))
def test_yet_more_evil_still_undecodable(self): # Issue #25388 src = b"#\x00\n#\xfd\n" tmpd = tempfile.mkdtemp() try: fn = os.path.join(tmpd, "bad.py") with open(fn, "wb") as fp: fp.write(src) try: rc, out, err = script_helper.assert_python_failure(fn) except AssertionError: if check_impl_detail(pypy=True): # as long as we don't crash return raise finally: test_support.rmtree(tmpd) self.assertIn(b"Non-ASCII", err)
def test_daemon_threads_fatal_error(self): subinterp_code = r"""if 1: import os import threading import time def f(): # Make sure the daemon thread is still running when # Py_EndInterpreter is called. time.sleep(10) threading.Thread(target=f, daemon=True).start() """ script = r"""if 1: import _testcapi _testcapi.run_in_subinterp(%r) """ % (subinterp_code,) rc, out, err = assert_python_failure("-c", script) self.assertIn("Fatal Python error: Py_EndInterpreter: " "not the last thread", err.decode())
def test_daemon_threads_fatal_error(self): subinterp_code = r"""if 1: import os import threading import time def f(): # Make sure the daemon thread is still running when # Py_EndInterpreter is called. time.sleep(10) threading.Thread(target=f, daemon=True).start() """ script = r"""if 1: import _testcapi _testcapi.run_in_subinterp(%r) """ % (subinterp_code, ) rc, out, err = assert_python_failure("-c", script) self.assertIn( "Fatal Python error: Py_EndInterpreter: " "not the last thread", err.decode())
def test_exit(self): # call with two arguments self.assertRaises(TypeError, sys.exit, 42, 42) # call without argument with self.assertRaises(SystemExit) as cm: sys.exit() self.assertIsNone(cm.exception.code) rc, out, err = assert_python_ok('-c', 'import sys; sys.exit()') self.assertEqual(rc, 0) self.assertEqual(out, b'') self.assertEqual(err, b'') # call with integer argument with self.assertRaises(SystemExit) as cm: sys.exit(42) self.assertEqual(cm.exception.code, 42) # call with tuple argument with one entry # entry will be unpacked with self.assertRaises(SystemExit) as cm: sys.exit((42,)) self.assertEqual(cm.exception.code, 42) # call with string argument with self.assertRaises(SystemExit) as cm: sys.exit("exit") self.assertEqual(cm.exception.code, "exit") # call with tuple argument with two entries with self.assertRaises(SystemExit) as cm: sys.exit((17, 23)) self.assertEqual(cm.exception.code, (17, 23)) # test that the exit machinery handles SystemExits properly # both unnormalized... rc, out, err = assert_python_failure('-c', 'raise SystemExit, 46') self.assertEqual(rc, 46) self.assertEqual(out, b'') self.assertEqual(err, b'') # ... and normalized rc, out, err = assert_python_failure('-c', 'raise SystemExit(47)') self.assertEqual(rc, 47) self.assertEqual(out, b'') self.assertEqual(err, b'') def check_exit_message(code, expected, **env_vars): rc, out, err = assert_python_failure('-c', code, **env_vars) self.assertEqual(rc, 1) self.assertEqual(out, b'') self.assertTrue(err.startswith(expected), "%s doesn't start with %s" % (repr(err), repr(expected))) # test that stderr buffer is flushed before the exit message is written # into stderr check_exit_message( r'import sys; sys.stderr.write("unflushed,"); sys.exit("message")', b"unflushed,message") # test that the unicode message is encoded to the stderr encoding check_exit_message( r'import sys; sys.exit(u"h\xe9")', b"h\xe9", PYTHONIOENCODING='latin-1')
def assertFailure(self, *args): rc, stdout, stderr = assert_python_failure('-m', 'calendar', *args) self.assertIn(b'Usage:', stderr) self.assertEqual(rc, 2)
def test_unmached_quote(self): # Issue #10206: python program starting with unmatched quote # spewed spaces to stdout rc, out, err = assert_python_failure('-c', "'") self.assertRegex(err.decode('ascii', 'ignore'), 'SyntaxError') self.assertEqual(b'', out)
def test_directories(self): assert_python_failure('.') assert_python_failure('< .')
def assertRunNotOK(self, *args, **env_vars): rc, out, err = script_helper.assert_python_failure( '-S', '-m', 'compileall', *args, **env_vars) return rc, out, err
def test_usage(self): rc, out, err = assert_python_failure(self.script, '-h') self.assertEqual(rc, 2) self.assertEqual(out, b'') self.assertGreater(err, b'')