mirror of https://github.com/python/cpython.git
gh-99437: runpy: decode path-like objects before setting globals
This commit is contained in:
parent
3eae76554b
commit
d457345bbc
15
Lib/runpy.py
15
Lib/runpy.py
|
@ -247,17 +247,17 @@ def _get_main_module_details(error=ImportError):
|
||||||
sys.modules[main_name] = saved_main
|
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
|
# Check for a compiled file first
|
||||||
from pkgutil import read_code
|
from pkgutil import read_code
|
||||||
decoded_path = os.path.abspath(os.fsdecode(fname))
|
code_path = os.path.abspath(fname)
|
||||||
with io.open_code(decoded_path) as f:
|
with io.open_code(code_path) as f:
|
||||||
code = read_code(f)
|
code = read_code(f)
|
||||||
if code is None:
|
if code is None:
|
||||||
# That didn't work, so try it as normal source code
|
# 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')
|
code = compile(f.read(), fname, 'exec')
|
||||||
return code, fname
|
return code
|
||||||
|
|
||||||
def run_path(path_name, init_globals=None, run_name=None):
|
def run_path(path_name, init_globals=None, run_name=None):
|
||||||
"""Execute code located at the specified filesystem location.
|
"""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]
|
pkg_name = run_name.rpartition(".")[0]
|
||||||
from pkgutil import get_importer
|
from pkgutil import get_importer
|
||||||
importer = get_importer(path_name)
|
importer = get_importer(path_name)
|
||||||
|
path_name = os.fsdecode(path_name)
|
||||||
if isinstance(importer, type(None)):
|
if isinstance(importer, type(None)):
|
||||||
# Not a valid sys.path entry, so run the code directly
|
# Not a valid sys.path entry, so run the code directly
|
||||||
# execfile() doesn't help as we want to allow compiled files
|
# 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,
|
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:
|
else:
|
||||||
# Finder is defined for path, so add it to
|
# Finder is defined for path, so add it to
|
||||||
# the start of sys.path
|
# the start of sys.path
|
||||||
|
|
|
@ -661,8 +661,10 @@ def test_basic_script_with_path_object(self):
|
||||||
mod_name = 'script'
|
mod_name = 'script'
|
||||||
script_name = pathlib.Path(self._make_test_script(script_dir,
|
script_name = pathlib.Path(self._make_test_script(script_dir,
|
||||||
mod_name))
|
mod_name))
|
||||||
self._check_script(script_name, "<run_path>", script_name,
|
self._check_script(script_name, "<run_path>",
|
||||||
script_name, expect_spec=False)
|
os.fsdecode(script_name),
|
||||||
|
os.fsdecode(script_name),
|
||||||
|
expect_spec=False)
|
||||||
|
|
||||||
def test_basic_script_no_suffix(self):
|
def test_basic_script_no_suffix(self):
|
||||||
with temp_dir() as script_dir:
|
with temp_dir() as script_dir:
|
||||||
|
|
|
@ -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.
|
Loading…
Reference in New Issue