2b11b9be20
Importing or executing a Hy file now loads the byte-compiled version if it exists and is up to date, and if not, the source is byte-compiled after it's parsed.
This change can speed up Hy a lot. Here are some examples comparing run times of the current master (491b474e
) to this commit, on my laptop with Python 3.6:
- `nosetests --exclude='test_bin'` goes from 3.8 s to 0.7 s (a 5-fold speedup)
- `hy -c '(print "hello world")` goes from 0.47 s to 0.20 s (a 2-fold speedup)
- Rogue TV's startup goes from 3.6 s to 0.4 s (a 9-fold speedup)
Accompanying changes include:
- `setup.py` now creates and installs bytecode for `hy.core`, `hy.contrib`, and `hy.extra`.
- The `hyc` command under Python 3 now creates bytecode in `__pycache__`, as usual for Python 3, instead of putting the `.pyc` right next to the source file like Python 2 does.
I've removed a test of `hy.extra.anaphoric.a-if` that triggers #1268 when the test file is byte-compiled and then hits some weird `macroexpand` bug or something when I try to work around that—Nose crashes when trying to produce an error message, and I can't seem to replicate the bug without Nose.
63 lines
1.6 KiB
Python
63 lines
1.6 KiB
Python
from hy.importer import (import_file_to_module, import_buffer_to_ast,
|
|
MetaLoader, get_bytecode_path)
|
|
from hy.errors import HyTypeError
|
|
import os
|
|
import ast
|
|
import tempfile
|
|
|
|
|
|
def test_basics():
|
|
"Make sure the basics of the importer work"
|
|
import_file_to_module("basic",
|
|
"tests/resources/importer/basic.hy")
|
|
|
|
|
|
def test_stringer():
|
|
_ast = import_buffer_to_ast("(defn square [x] (* x x))", '')
|
|
assert type(_ast.body[0]) == ast.FunctionDef
|
|
|
|
|
|
def test_imports():
|
|
path = os.getcwd() + "/tests/resources/importer/a.hy"
|
|
testLoader = MetaLoader(path)
|
|
|
|
def _import_test():
|
|
try:
|
|
return testLoader.load_module("tests.resources.importer.a")
|
|
except:
|
|
return "Error"
|
|
|
|
assert _import_test() == "Error"
|
|
assert _import_test() is not None
|
|
|
|
|
|
def test_import_error_reporting():
|
|
"Make sure that (import) reports errors correctly."
|
|
|
|
def _import_error_test():
|
|
try:
|
|
import_buffer_to_ast("(import \"sys\")", '')
|
|
except HyTypeError:
|
|
return "Error reported"
|
|
|
|
assert _import_error_test() == "Error reported"
|
|
assert _import_error_test() is not None
|
|
|
|
|
|
def test_import_autocompiles():
|
|
"Test that (import) byte-compiles the module."
|
|
|
|
f = tempfile.NamedTemporaryFile(suffix='.hy', delete=False)
|
|
f.write(b'(defn pyctest [s] (+ "X" s "Y"))')
|
|
f.close()
|
|
|
|
try:
|
|
os.remove(get_bytecode_path(f.name))
|
|
except (IOError, OSError):
|
|
pass
|
|
import_file_to_module("mymodule", f.name)
|
|
assert os.path.exists(get_bytecode_path(f.name))
|
|
|
|
os.remove(f.name)
|
|
os.remove(get_bytecode_path(f.name))
|