Use Python cmdline file-relative sys.path

Closes hylang/hy#1457.
This commit is contained in:
Brandon T. Willard 2018-08-22 15:21:17 -05:00
parent c022abc831
commit cbaba4a10a
3 changed files with 40 additions and 2 deletions

View File

@ -229,13 +229,21 @@ def run_repl(hr=None, **kwargs):
def run_icommand(source, **kwargs):
hr = HyREPL(**kwargs)
if os.path.exists(source):
# Emulate Python cmdline behavior by setting `sys.path` relative
# to the executed file's location.
if sys.path[0] == '':
sys.path[0] = os.path.realpath(os.path.split(source)[0])
else:
sys.path.insert(0, os.path.split(source)[0])
with io.open(source, "r", encoding='utf-8') as f:
source = f.read()
filename = source
else:
filename = '<input>'
hr = HyREPL(**kwargs)
hr.runsource(source, filename=filename, symbol='single')
return run_repl(hr)
@ -333,9 +341,18 @@ def cmdline_handler(scriptname, argv):
else:
# User did "hy <filename>"
filename = options.args[0]
# Emulate Python cmdline behavior by setting `sys.path` relative
# to the executed file's location.
if sys.path[0] == '':
sys.path[0] = os.path.realpath(os.path.split(filename)[0])
else:
sys.path.insert(0, os.path.split(filename)[0])
try:
sys.argv = options.args
runpy.run_path(options.args[0], run_name='__main__')
runpy.run_path(filename, run_name='__main__')
return 0
except FileNotFoundError as e:
print("hy: Can't open file '{0}': [Errno {1}] {2}".format(

View File

@ -0,0 +1,3 @@
(import bin.printenv)
(import sys)
(print sys.path)

View File

@ -214,6 +214,10 @@ def test_bin_hy_icmd_file():
output, _ = run_cmd("hy -i resources/icmd_test_file.hy", "(ideas)")
assert "Hy!" in output
file_relative_path = os.path.realpath(os.path.split('tests/resources/relative_import.hy')[0])
output, _ = run_cmd("hy -i tests/resources/relative_import.hy None")
assert file_relative_path in output
def test_bin_hy_icmd_and_spy():
output, _ = run_cmd("hy -i \"(+ [] [])\" --spy", "(+ 1 1)")
@ -346,6 +350,20 @@ def test_bin_hy_file_main_file():
assert "This is a __main__.hy" in output
def test_bin_hy_file_sys_path():
"""The test resource `relative_import.hy` will perform an absolute import
of a module in its directory: a directory that is not on the `sys.path` of
the script executing the module (i.e. `hy`). We want to make sure that Hy
adopts the file's location in `sys.path`, instead of the runner's current
dir (e.g. '' in `sys.path`).
"""
file_path, _ = os.path.split('tests/resources/relative_import.hy')
file_relative_path = os.path.realpath(file_path)
output, _ = run_cmd("hy tests/resources/relative_import.hy")
assert file_relative_path in output
def test_bin_hy_module_main_args():
output, _ = run_cmd("hy -m tests.resources.bin.main test 123")
assert "test" in output