https://github.com/python/cpython/commit/d457345bbc6414db0443819290b04a9a4333313d
commit: d457345bbc6414db0443819290b04a9a4333313d
branch: main
author: Kamil Turek <[email protected]>
committer: FFY00 <[email protected]>
date: 2024-01-15T16:58:50Z
summary:
gh-99437: runpy: decode path-like objects before setting globals
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 628c8cae38a751..57fe859e366b5b 100644
--- a/Lib/test/test_runpy.py
+++ b/Lib/test/test_runpy.py
@@ -661,8 +661,10 @@ def test_basic_script_with_path_object(self):
mod_name = 'script'
script_name = pathlib.Path(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]