diff --git a/hy/cmdline.py b/hy/cmdline.py
index f78008e..08f6c0b 100644
--- a/hy/cmdline.py
+++ b/hy/cmdline.py
@@ -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 = ''
+
+ 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 = 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(
diff --git a/tests/resources/relative_import.hy b/tests/resources/relative_import.hy
new file mode 100644
index 0000000..65acc66
--- /dev/null
+++ b/tests/resources/relative_import.hy
@@ -0,0 +1,3 @@
+(import bin.printenv)
+(import sys)
+(print sys.path)
diff --git a/tests/test_bin.py b/tests/test_bin.py
index 8827fd6..e642f53 100644
--- a/tests/test_bin.py
+++ b/tests/test_bin.py
@@ -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