[Python-checkins] cpython (3.4): Skip some tests that require a subinterpreter launched with -E or -I when the

gregory.p.smith python-checkins at python.org
Wed Feb 4 10:04:50 CET 2015


https://hg.python.org/cpython/rev/ef1d338bec8f
changeset:   94496:ef1d338bec8f
branch:      3.4
parent:      94488:fd445d2dd107
user:        Gregory P. Smith <greg at krypto.org>
date:        Wed Feb 04 00:59:40 2015 -0800
summary:
  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 private test.script_helper._interpreter_requires_environment() function
to be used with @unittest.skipIf on stdlib test methods requiring this.

files:
  Lib/test/script_helper.py      |  35 ++++++++++++++++++
  Lib/test/test_cmd_line.py      |   4 +-
  Lib/test/test_script_helper.py |  41 ++++++++++++++++++++++
  Lib/test/test_tracemalloc.py   |   4 +-
  4 files changed, 82 insertions(+), 2 deletions(-)


diff --git a/Lib/test/script_helper.py b/Lib/test/script_helper.py
--- a/Lib/test/script_helper.py
+++ b/Lib/test/script_helper.py
@@ -15,6 +15,41 @@
 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():
+    """
+    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 --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py
--- a/Lib/test/test_cmd_line.py
+++ b/Lib/test/test_cmd_line.py
@@ -8,6 +8,7 @@
 import sys
 import subprocess
 import tempfile
+from test import script_helper
 from test.script_helper import (spawn_python, kill_python, assert_python_ok,
     assert_python_failure)
 
@@ -439,7 +440,8 @@
         self.assertEqual(err.splitlines().count(b'Unknown option: -a'), 1)
         self.assertEqual(b'', out)
 
-
+    @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 --git a/Lib/test/test_script_helper.py b/Lib/test/test_script_helper.py
--- a/Lib/test/test_script_helper.py
+++ b/Lib/test/test_script_helper.py
@@ -1,7 +1,10 @@
 """Unittests for test.script_helper.  Who tests the test helper?"""
 
+import subprocess
+import sys
 from test import script_helper
 import unittest
+from unittest import mock
 
 
 class TestScriptHelper(unittest.TestCase):
@@ -31,5 +34,43 @@
                       msg='unexpected command line.')
 
 
+class TestScriptHelperEnvironment(unittest.TestCase):
+    """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.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())
+        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())
+        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 --git a/Lib/test/test_tracemalloc.py b/Lib/test/test_tracemalloc.py
--- a/Lib/test/test_tracemalloc.py
+++ b/Lib/test/test_tracemalloc.py
@@ -5,7 +5,7 @@
 import unittest
 from unittest.mock import patch
 from test.script_helper import assert_python_ok, assert_python_failure
-from test import support
+from test import script_helper, support
 try:
     import threading
 except ImportError:
@@ -755,6 +755,8 @@
         stdout = stdout.rstrip()
         self.assertEqual(stdout, b'False')
 
+    @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())'

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list