Skip to content

Commit d457345

Browse files
authored
gh-99437: runpy: decode path-like objects before setting globals
1 parent 3eae765 commit d457345

File tree

3 files changed

+14
-9
lines changed

3 files changed

+14
-9
lines changed

Lib/runpy.py

+8-7
Original file line numberDiff line numberDiff line change
@@ -247,17 +247,17 @@ def _get_main_module_details(error=ImportError):
247247
sys.modules[main_name] = saved_main
248248

249249

250-
def _get_code_from_file(run_name, fname):
250+
def _get_code_from_file(fname):
251251
# Check for a compiled file first
252252
from pkgutil import read_code
253-
decoded_path = os.path.abspath(os.fsdecode(fname))
254-
with io.open_code(decoded_path) as f:
253+
code_path = os.path.abspath(fname)
254+
with io.open_code(code_path) as f:
255255
code = read_code(f)
256256
if code is None:
257257
# That didn't work, so try it as normal source code
258-
with io.open_code(decoded_path) as f:
258+
with io.open_code(code_path) as f:
259259
code = compile(f.read(), fname, 'exec')
260-
return code, fname
260+
return code
261261

262262
def run_path(path_name, init_globals=None, run_name=None):
263263
"""Execute code located at the specified filesystem location.
@@ -279,12 +279,13 @@ def run_path(path_name, init_globals=None, run_name=None):
279279
pkg_name = run_name.rpartition(".")[0]
280280
from pkgutil import get_importer
281281
importer = get_importer(path_name)
282+
path_name = os.fsdecode(path_name)
282283
if isinstance(importer, type(None)):
283284
# Not a valid sys.path entry, so run the code directly
284285
# execfile() doesn't help as we want to allow compiled files
285-
code, fname = _get_code_from_file(run_name, path_name)
286+
code = _get_code_from_file(path_name)
286287
return _run_module_code(code, init_globals, run_name,
287-
pkg_name=pkg_name, script_name=fname)
288+
pkg_name=pkg_name, script_name=path_name)
288289
else:
289290
# Finder is defined for path, so add it to
290291
# the start of sys.path

Lib/test/test_runpy.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -661,8 +661,10 @@ def test_basic_script_with_path_object(self):
661661
mod_name = 'script'
662662
script_name = pathlib.Path(self._make_test_script(script_dir,
663663
mod_name))
664-
self._check_script(script_name, "<run_path>", script_name,
665-
script_name, expect_spec=False)
664+
self._check_script(script_name, "<run_path>",
665+
os.fsdecode(script_name),
666+
os.fsdecode(script_name),
667+
expect_spec=False)
666668

667669
def test_basic_script_no_suffix(self):
668670
with temp_dir() as script_dir:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:func:`runpy.run_path` now decodes path-like objects, making sure __file__
2+
and sys.argv[0] of the module being run are always strings.

0 commit comments

Comments
 (0)