diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -33,7 +33,10 @@ def _make_relax_case(): if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS): def _relax_case(): """True if filenames must be checked case-insensitively.""" - return b'PYTHONCASEOK' in _os.environ + if sys.flags.ignore_environment: + return False + else: + return b'PYTHONCASEOK' in _os.environ else: def _relax_case(): """True if filenames must be checked case-insensitively.""" diff --git a/Lib/test/test_importlib/extension/test_case_sensitivity.py b/Lib/test/test_importlib/extension/test_case_sensitivity.py --- a/Lib/test/test_importlib/extension/test_case_sensitivity.py +++ b/Lib/test/test_importlib/extension/test_case_sensitivity.py @@ -5,7 +5,8 @@ import unittest from importlib import _bootstrap from .. import util from . import util as ext_util - +import os +import subprocess @util.case_insensitive_tests class ExtensionModuleCaseSensitivityTest(unittest.TestCase): @@ -29,14 +30,34 @@ class ExtensionModuleCaseSensitivityTest self.assertIsNone(loader) def test_case_insensitivity(self): - with support.EnvironmentVarGuard() as env: - env.set('PYTHONCASEOK', '1') - if b'PYTHONCASEOK' not in _bootstrap._os.environ: - self.skipTest('os.environ changes not reflected in ' - '_os.environ') - loader = self.find_module() - self.assertTrue(hasattr(loader, 'load_module')) + find_snippet = """if True: + from importlib import _bootstrap + import sys + finder = _bootstrap.FileFinder('{path}', + (_bootstrap.ExtensionFileLoader, + _bootstrap.EXTENSION_SUFFIXES)) + loader = finder.find_module('{bad_name}') + print(str(hasattr(loader, 'load_module'))) + """.format(bad_name=ext_util.NAME.upper(), path=ext_util.PATH) + newenv = os.environ.copy() + newenv["PYTHONCASEOK"] = "1" + + def check_output(expected, extra_arg=None): + args = [sys.executable] + if extra_arg: + args.append(extra_arg) + args.extend(["-c", find_snippet]) + p = subprocess.Popen(args, stdout=subprocess.PIPE, env=newenv) + actual = p.communicate()[0].decode().strip() + self.assertEqual(expected, actual) + self.assertEqual(p.wait(), 0) + + # Test with PYTHONCASEOK=1. + check_output("True") + + # Test with PYTHONCASEOK=1 ignored because of -E. + check_output("False", "-E") diff --git a/Lib/test/test_importlib/source/test_case_sensitivity.py b/Lib/test/test_importlib/source/test_case_sensitivity.py --- a/Lib/test/test_importlib/source/test_case_sensitivity.py +++ b/Lib/test/test_importlib/source/test_case_sensitivity.py @@ -8,6 +8,7 @@ import os import sys from test import support as test_support import unittest +import subprocess @util.case_insensitive_tests @@ -50,16 +51,62 @@ class CaseSensitivityTest(unittest.TestC self.assertIsNone(insensitive) def test_insensitive(self): - with test_support.EnvironmentVarGuard() as env: - env.set('PYTHONCASEOK', '1') - if b'PYTHONCASEOK' not in _bootstrap._os.environ: - self.skipTest('os.environ changes not reflected in ' - '_os.environ') - sensitive, insensitive = self.sensitivity_test() - self.assertTrue(hasattr(sensitive, 'load_module')) - self.assertIn(self.name, sensitive.get_filename(self.name)) - self.assertTrue(hasattr(insensitive, 'load_module')) - self.assertIn(self.name, insensitive.get_filename(self.name)) + sensitive_pkg = 'sensitive.{0}'.format(self.name) + insensitive_pkg = 'insensitive.{0}'.format(self.name.lower()) + context = source_util.create_modules(insensitive_pkg, sensitive_pkg) + with context as mapping: + sensitive_path = os.path.join(mapping['.root'], 'sensitive') + insensitive_path = os.path.join(mapping['.root'], 'insensitive') + find_snippet = """if True: + import sys + from importlib import machinery + + def find(path): + f = machinery.FileFinder(path, + (machinery.SourceFileLoader, + machinery.SOURCE_SUFFIXES), + (machinery.SourcelessFileLoader, + machinery.BYTECODE_SUFFIXES)) + return f.find_module('{name}') + + sensitive = find('{sensitive_path}') + insensitive = find('{insensitive_path}') + print(str(hasattr(sensitive, 'load_module'))) + if hasattr(sensitive, 'load_module'): + print(sensitive.get_filename('{name}')) + else: + print('None') + print(str(hasattr(insensitive, 'load_module'))) + if hasattr(insensitive, 'load_module'): + print(insensitive.get_filename('{name}')) + else: + print('None') + """.format(sensitive_path=sensitive_path, + insensitive_path=insensitive_path, + name=self.name) + + newenv = os.environ.copy() + newenv["PYTHONCASEOK"] = "1" + + def check_output(expected, extra_arg=None): + args = [sys.executable] + if extra_arg: + args.append(extra_arg) + args.extend(["-c", find_snippet]) + p = subprocess.Popen(args, stdout=subprocess.PIPE, + env=newenv) + actual = p.communicate()[0].decode().split() + self.assertEqual(expected[0], actual[0]) + self.assertIn(expected[1], actual[1]) + self.assertEqual(expected[2], actual[2]) + self.assertIn(expected[3], actual[3]) + self.assertEqual(p.wait(), 0) + + # Test with PYTHONCASEOK=1. + check_output(["True", self.name, "True", self.name]) + + # Test with PYTHONCASEOK=1 ignored because of -E. + check_output(["True", self.name, "False", "None"], "-E") def test_main():