Add Python cmdline bytecode option and set sys.executable

Closes hylang/hy#459.
This commit is contained in:
Brandon T. Willard 2018-08-22 13:20:07 -05:00
parent 4839acadf7
commit c022abc831
3 changed files with 33 additions and 16 deletions

View File

@ -262,6 +262,8 @@ def cmdline_handler(scriptname, argv):
help="module to run, passed in as a string")
parser.add_argument("-E", action='store_true',
help="ignore PYTHON* environment variables")
parser.add_argument("-B", action='store_true',
help="don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x")
parser.add_argument("-i", dest="icommand",
help="program passed in as a string, then stay in REPL")
parser.add_argument("--spy", action="store_true",
@ -278,13 +280,17 @@ def cmdline_handler(scriptname, argv):
parser.add_argument('args', nargs=argparse.REMAINDER,
help=argparse.SUPPRESS)
# stash the hy executable in case we need it later
# mimics Python sys.executable
# Get the path of the Hy cmdline executable and swap it with
# `sys.executable` (saving the original, just in case).
# XXX: The `__main__` module will also have `__file__` set to the
# entry-point script. Currently, I don't see an immediate problem, but
# that's not how the Python cmdline works.
hy.executable = argv[0]
hy.sys_executable = sys.executable
sys.executable = hy.executable
# need to split the args if using "-m"
# all args after the MOD are sent to the module
# in sys.argv
# Need to split the args. If using "-m" all args after the MOD are sent to
# the module in sys.argv.
module_args = []
if "-m" in argv:
mloc = argv.index("-m")
@ -298,13 +304,13 @@ def cmdline_handler(scriptname, argv):
global SIMPLE_TRACEBACKS
SIMPLE_TRACEBACKS = False
# reset sys.argv like Python
# sys.argv = [sys.argv[0]] + options.args + module_args
if options.E:
# User did "hy -E ..."
_remove_python_envs()
if options.B:
sys.dont_write_bytecode = True
if options.command:
# User did "hy -c ..."
return run_command(options.command)

View File

@ -84,7 +84,7 @@ def test_import_error_reporting():
assert _import_error_test() is not None
@pytest.mark.skipif(os.environ.get('PYTHONDONTWRITEBYTECODE'),
@pytest.mark.skipif(sys.dont_write_bytecode,
reason="Bytecode generation is suppressed")
def test_import_autocompiles():
"Test that (import) byte-compiles the module."

View File

@ -6,6 +6,7 @@
import os
import re
import sys
import shlex
import subprocess
@ -285,15 +286,20 @@ def test_bin_hy_no_main():
assert "This Should Still Work" in output
@pytest.mark.parametrize('scenario', [
"normal", "prevent_by_force", "prevent_by_env"])
@pytest.mark.parametrize('cmd_fmt', [
'hy -m {modname}', "hy -c '(import {modname})'"])
@pytest.mark.parametrize('scenario', ["normal", "prevent_by_force",
"prevent_by_env", "prevent_by_option"])
@pytest.mark.parametrize('cmd_fmt', [['hy', '{fpath}'],
['hy', '-m', '{modname}'],
['hy', '-c', "'(import {modname})'"]])
def test_bin_hy_byte_compile(scenario, cmd_fmt):
modname = "tests.resources.bin.bytecompile"
fpath = modname.replace(".", "/") + ".hy"
cmd = cmd_fmt.format(**locals())
if scenario == 'prevent_by_option':
cmd_fmt.insert(1, '-B')
cmd = ' '.join(cmd_fmt).format(**locals())
rm(cache_from_source(fpath))
@ -304,14 +310,14 @@ def test_bin_hy_byte_compile(scenario, cmd_fmt):
# Whether or not we can byte-compile the module, we should be able
# to run it.
output, _ = run_cmd(cmd, dontwritebytecode=scenario == "prevent_by_env")
output, _ = run_cmd(cmd, dontwritebytecode=(scenario == "prevent_by_env"))
assert "Hello from macro" in output
assert "The macro returned: boink" in output
if scenario == "normal":
# That should've byte-compiled the module.
assert os.path.exists(cache_from_source(fpath))
elif scenario == "prevent_by_env":
elif scenario == "prevent_by_env" or scenario == "prevent_by_option":
# No byte-compiled version should've been created.
assert not os.path.exists(cache_from_source(fpath))
@ -353,3 +359,8 @@ def test_bin_hy_module_main_exitvalue():
def test_bin_hy_module_no_main():
output, _ = run_cmd("hy -m tests.resources.bin.nomain")
assert "This Should Still Work" in output
def test_bin_hy_sys_executable():
output, _ = run_cmd("hy -c '(do (import sys) (print sys.executable))'")
assert output.strip().endswith('/hy')