From: Gregory P. Smith Date: Wed, 4 Feb 2015 09:04:31 +0000 (-0800) Subject: Skip some tests that require a subinterpreter launched with -E or -I when the X-Git-Tag: v3.5.0a1~29 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8f2fae1e7d7142a280a23bb9428d0aaddbb518c5;p=python Skip some tests that require a subinterpreter launched with -E or -I when the interpreter under test is being run in an environment that requires the use of environment variables such as PYTHONHOME in order to function at all. Adds a test.script_helper.interpreter_requires_environment() function to be used with @unittest.skipIf on stdlib test methods requiring this. --- 8f2fae1e7d7142a280a23bb9428d0aaddbb518c5 diff --cc Lib/test/script_helper.py index 87a781e31a,6a8bea6884..619752ea89 --- a/Lib/test/script_helper.py +++ b/Lib/test/script_helper.py @@@ -15,6 -15,41 +15,41 @@@ import zipfil from importlib.util import source_from_cache from test.support import make_legacy_pyc, strip_python_stderr, temp_dir + + # Cached result of the expensive test performed in the function below. + __cached_interp_requires_environment = None + -def _interpreter_requires_environment(): ++def interpreter_requires_environment(): + """ + Returns True if our sys.executable interpreter requires environment + variables in order to be able to run at all. + + This is designed to be used with @unittest.skipIf() to annotate tests + that need to use an assert_python*() function to launch an isolated + mode (-I) or no environment mode (-E) sub-interpreter process. + + A normal build & test does not run into this situation but it can happen + when trying to run the standard library test suite from an interpreter that + doesn't have an obvious home with Python's current home finding logic. + + Setting PYTHONHOME is one way to get most of the testsuite to run in that + situation. PYTHONPATH or PYTHONUSERSITE are other common envirnonment + variables that might impact whether or not the interpreter can start. + """ + global __cached_interp_requires_environment + if __cached_interp_requires_environment is None: + # Try running an interpreter with -E to see if it works or not. + try: + subprocess.check_call([sys.executable, '-E', + '-c', 'import sys; sys.exit(0)']) + except subprocess.CalledProcessError: + __cached_interp_requires_environment = True + else: + __cached_interp_requires_environment = False + + return __cached_interp_requires_environment + + # Executing the interpreter in a subprocess def _assert_python(expected_success, *args, **env_vars): if '__isolated' in env_vars: diff --cc Lib/test/test_cmd_line.py index 327c1455fc,3683a48b7a..ebe557e73c --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@@ -439,7 -440,8 +440,8 @@@ class CmdLineTest(unittest.TestCase) self.assertEqual(err.splitlines().count(b'Unknown option: -a'), 1) self.assertEqual(b'', out) - - @unittest.skipIf(script_helper._interpreter_requires_environment(), ++ @unittest.skipIf(script_helper.interpreter_requires_environment(), + 'Cannot run -I tests when PYTHON env vars are required.') def test_isolatedmode(self): self.verify_valid_flag('-I') self.verify_valid_flag('-IEs') diff --cc Lib/test/test_script_helper.py index ea73fd86e5,da61265fd2..a10e80122c --- a/Lib/test/test_script_helper.py +++ b/Lib/test/test_script_helper.py @@@ -31,5 -34,43 +34,43 @@@ class TestScriptHelper(unittest.TestCas msg='unexpected command line.') + class TestScriptHelperEnvironment(unittest.TestCase): - """Code coverage for _interpreter_requires_environment().""" ++ """Code coverage for interpreter_requires_environment().""" + + def setUp(self): + self.assertTrue( + hasattr(script_helper, '__cached_interp_requires_environment')) + # Reset the private cached state. + script_helper.__dict__['__cached_interp_requires_environment'] = None + + def tearDown(self): + # Reset the private cached state. + script_helper.__dict__['__cached_interp_requires_environment'] = None + + @mock.patch('subprocess.check_call') + def test_interpreter_requires_environment_true(self, mock_check_call): + mock_check_call.side_effect = subprocess.CalledProcessError('', '') - self.assertTrue(script_helper._interpreter_requires_environment()) - self.assertTrue(script_helper._interpreter_requires_environment()) ++ self.assertTrue(script_helper.interpreter_requires_environment()) ++ self.assertTrue(script_helper.interpreter_requires_environment()) + self.assertEqual(1, mock_check_call.call_count) + + @mock.patch('subprocess.check_call') + def test_interpreter_requires_environment_false(self, mock_check_call): + # The mocked subprocess.check_call fakes a no-error process. - script_helper._interpreter_requires_environment() - self.assertFalse(script_helper._interpreter_requires_environment()) ++ script_helper.interpreter_requires_environment() ++ self.assertFalse(script_helper.interpreter_requires_environment()) + self.assertEqual(1, mock_check_call.call_count) + + @mock.patch('subprocess.check_call') + def test_interpreter_requires_environment_details(self, mock_check_call): - script_helper._interpreter_requires_environment() - self.assertFalse(script_helper._interpreter_requires_environment()) - self.assertFalse(script_helper._interpreter_requires_environment()) ++ script_helper.interpreter_requires_environment() ++ self.assertFalse(script_helper.interpreter_requires_environment()) ++ self.assertFalse(script_helper.interpreter_requires_environment()) + self.assertEqual(1, mock_check_call.call_count) + check_call_command = mock_check_call.call_args[0][0] + self.assertEqual(sys.executable, check_call_command[0]) + self.assertIn('-E', check_call_command) + + if __name__ == '__main__': unittest.main() diff --cc Lib/test/test_tracemalloc.py index bc22450f0f,48ccab28b8..19d3fd8dda --- a/Lib/test/test_tracemalloc.py +++ b/Lib/test/test_tracemalloc.py @@@ -755,6 -755,8 +755,8 @@@ class TestCommandLine(unittest.TestCase stdout = stdout.rstrip() self.assertEqual(stdout, b'False') - @unittest.skipIf(script_helper._interpreter_requires_environment(), ++ @unittest.skipIf(script_helper.interpreter_requires_environment(), + 'Cannot run -E tests when PYTHON env vars are required.') def test_env_var_ignored_with_E(self): """PYTHON* environment variables must be ignored when -E is present.""" code = 'import tracemalloc; print(tracemalloc.is_tracing())'