https://github.com/python/cpython/commit/0585a3fdb9821624050e140fe89e1e39df1f3866 commit: 0585a3fdb9821624050e140fe89e1e39df1f3866 branch: 3.12 author: Miss Islington (bot) <[email protected]> committer: hugovk <[email protected]> date: 2024-08-12T11:22:13+03:00 summary:
[3.12] gh-99437: runpy: decode path-like objects before setting globals (#114838) Co-authored-by: Kamil Turek <[email protected]> Co-authored-by: Hugo van Kemenade <[email protected]> files: A Misc/NEWS.d/next/Library/2023-08-04-18-43-21.gh-issue-99437.Et8hu8.rst M Lib/runpy.py M Lib/test/test_runpy.py diff --git a/Lib/runpy.py b/Lib/runpy.py index 42f896c9cd5094..ef54d3282eee06 100644 --- a/Lib/runpy.py +++ b/Lib/runpy.py @@ -247,17 +247,17 @@ def _get_main_module_details(error=ImportError): sys.modules[main_name] = saved_main -def _get_code_from_file(run_name, fname): +def _get_code_from_file(fname): # Check for a compiled file first from pkgutil import read_code - decoded_path = os.path.abspath(os.fsdecode(fname)) - with io.open_code(decoded_path) as f: + code_path = os.path.abspath(fname) + with io.open_code(code_path) as f: code = read_code(f) if code is None: # That didn't work, so try it as normal source code - with io.open_code(decoded_path) as f: + with io.open_code(code_path) as f: code = compile(f.read(), fname, 'exec') - return code, fname + return code def run_path(path_name, init_globals=None, run_name=None): """Execute code located at the specified filesystem location. @@ -279,12 +279,13 @@ def run_path(path_name, init_globals=None, run_name=None): pkg_name = run_name.rpartition(".")[0] from pkgutil import get_importer importer = get_importer(path_name) + path_name = os.fsdecode(path_name) if isinstance(importer, type(None)): # Not a valid sys.path entry, so run the code directly # execfile() doesn't help as we want to allow compiled files - code, fname = _get_code_from_file(run_name, path_name) + code = _get_code_from_file(path_name) return _run_module_code(code, init_globals, run_name, - pkg_name=pkg_name, script_name=fname) + pkg_name=pkg_name, script_name=path_name) else: # Finder is defined for path, so add it to # the start of sys.path diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index 9c8494105838fc..3f68962a589d6d 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -660,8 +660,10 @@ def test_basic_script_with_pathlike_object(self): with temp_dir() as script_dir: mod_name = 'script' script_name = FakePath(self._make_test_script(script_dir, mod_name)) - self._check_script(script_name, "<run_path>", script_name, - script_name, expect_spec=False) + self._check_script(script_name, "<run_path>", + os.fsdecode(script_name), + os.fsdecode(script_name), + expect_spec=False) def test_basic_script_no_suffix(self): with temp_dir() as script_dir: diff --git a/Misc/NEWS.d/next/Library/2023-08-04-18-43-21.gh-issue-99437.Et8hu8.rst b/Misc/NEWS.d/next/Library/2023-08-04-18-43-21.gh-issue-99437.Et8hu8.rst new file mode 100644 index 00000000000000..da4e20f426b6cf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-08-04-18-43-21.gh-issue-99437.Et8hu8.rst @@ -0,0 +1,2 @@ +:func:`runpy.run_path` now decodes path-like objects, making sure __file__ +and sys.argv[0] of the module being run are always strings. _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: [email protected]
