|
21 | 21 | verbose, |
22 | 22 | ) |
23 | 23 | from test import support |
| 24 | +from test.support import os_helper |
24 | 25 | from test.support.import_helper import forget, make_legacy_pyc, unload |
25 | 26 | from test.support.os_helper import create_empty_file, temp_dir, FakePath |
26 | 27 | from test.support.script_helper import make_script, make_zip_script |
@@ -917,5 +918,95 @@ def test_pymain_run_module(self): |
917 | 918 | self.assertSigInt(["-m", ham.stem], cwd=ham.parent) |
918 | 919 |
|
919 | 920 |
|
| 921 | +class MiscTests(unittest.TestCase): |
| 922 | + def test_remove_sys_path0(self): |
| 923 | + # Check that all path0 copies are removed |
| 924 | + PATH0 = '/path/zero' |
| 925 | + STDLIB_PATH = '/to/stdlib' |
| 926 | + OTHER_PATH = '/other/path' |
| 927 | + sys_path = [PATH0, STDLIB_PATH, PATH0, '', OTHER_PATH, PATH0] |
| 928 | + expected = [STDLIB_PATH, '', OTHER_PATH] |
| 929 | + with (support.swap_attr(sys, '_stdlib_dir', STDLIB_PATH), |
| 930 | + support.swap_attr(sys, '_path0', PATH0), |
| 931 | + support.swap_attr(sys, 'path', sys_path)): |
| 932 | + runpy._remove_sys_path0() |
| 933 | + self.assertEqual(sys.path, expected) |
| 934 | + |
| 935 | + # Calling it twice does nothing |
| 936 | + runpy._remove_sys_path0() |
| 937 | + self.assertEqual(sys.path, expected) |
| 938 | + |
| 939 | + # Do nothing if sys._path0 is sys._stdlib_dir |
| 940 | + sys_path = ['', STDLIB_PATH, OTHER_PATH] |
| 941 | + expected = sys_path.copy() |
| 942 | + with (support.swap_attr(sys, '_stdlib_dir', STDLIB_PATH), |
| 943 | + support.swap_attr(sys, '_path0', STDLIB_PATH), |
| 944 | + support.swap_attr(sys, 'path', sys_path)): |
| 945 | + runpy._remove_sys_path0() |
| 946 | + self.assertEqual(sys.path, expected) |
| 947 | + |
| 948 | + # Do nothing if sys._path0 is None |
| 949 | + sys_path = ['', STDLIB_PATH, OTHER_PATH] |
| 950 | + expected = sys_path.copy() |
| 951 | + with (support.swap_attr(sys, '_stdlib_dir', STDLIB_PATH), |
| 952 | + support.swap_attr(sys, '_path0', None), |
| 953 | + support.swap_attr(sys, 'path', sys_path)): |
| 954 | + runpy._remove_sys_path0() |
| 955 | + self.assertEqual(sys.path, expected) |
| 956 | + |
| 957 | + def run_python(self, *args, PYTHONPATH=None): |
| 958 | + cmd = [sys.executable, *args] |
| 959 | + env = support.make_clean_env() |
| 960 | + if PYTHONPATH: |
| 961 | + env['PYTHONPATH'] = PYTHONPATH |
| 962 | + proc = subprocess.run(cmd, text=True, stderr=subprocess.PIPE, env=env) |
| 963 | + self.assertEqual(proc.returncode, 0, proc.stderr) |
| 964 | + |
| 965 | + @support.requires_subprocess() |
| 966 | + def test_remove_sys_path0_run_python(self): |
| 967 | + CODE = textwrap.dedent(""" |
| 968 | + import runpy, sys |
| 969 | +
|
| 970 | + # Remove sys.path[0] |
| 971 | + orig_path = sys.path.copy() |
| 972 | + path0 = sys._path0 |
| 973 | + runpy._remove_sys_path0() |
| 974 | +
|
| 975 | + if path0 is not None and path0 in sys.path: |
| 976 | + raise Exception(f"path0 {path0!r} found in sys.path {sys.path!r}") |
| 977 | + if not sys.flags.safe_path: |
| 978 | + if sys.path == orig_path: |
| 979 | + raise Exception("sys.path was not changed") |
| 980 | + else: |
| 981 | + if sys.path != orig_path: |
| 982 | + raise Exception("sys.path was changed") |
| 983 | +
|
| 984 | + # Calling it twice must do nothing |
| 985 | + clean_path = sys.path.copy() |
| 986 | + runpy._remove_sys_path0() |
| 987 | + if sys.path != clean_path: |
| 988 | + raise Exception("sys.path was changed") |
| 989 | + """) |
| 990 | + |
| 991 | + # Test "python -c code" |
| 992 | + self.run_python('-c', CODE) |
| 993 | + self.run_python('-P', '-c', CODE) |
| 994 | + |
| 995 | + with tempfile.TemporaryDirectory() as tmpdir: |
| 996 | + name = 'test_remove_sys_path0' |
| 997 | + filename = os.path.join(tmpdir, f'{name}.py') |
| 998 | + with open(filename, 'w') as fp: |
| 999 | + fp.write(CODE) |
| 1000 | + |
| 1001 | + # Test "python script.py" |
| 1002 | + self.run_python(filename) |
| 1003 | + self.run_python('-P', filename) |
| 1004 | + |
| 1005 | + with os_helper.change_cwd(tmpdir): |
| 1006 | + # Test "python -m module" |
| 1007 | + self.run_python('-m', name) |
| 1008 | + self.run_python('-P', '-m', name, PYTHONPATH=tmpdir) |
| 1009 | + |
| 1010 | + |
920 | 1011 | if __name__ == "__main__": |
921 | 1012 | unittest.main() |
0 commit comments