diff --git a/hy/compiler.py b/hy/compiler.py index 46a2deb..260b600 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -55,6 +55,11 @@ import keyword from collections import defaultdict +if PY3: + import builtins +else: + import __builtin__ as builtins + _compile_time_ns = {} @@ -75,7 +80,11 @@ def load_stdlib(): for module in hy.core.STDLIB: mod = importlib.import_module(module) for e in mod.EXPORTS: - _stdlib[e] = module + if getattr(mod, e) is not getattr(builtins, e, ''): + # Don't bother putting a name in _stdlib if it + # points to a builtin with the same name. This + # prevents pointless imports. + _stdlib[e] = module # True, False and None included here since they diff --git a/tests/compilers/test_ast.py b/tests/compilers/test_ast.py index 4719ef8..6b4d3dc 100644 --- a/tests/compilers/test_ast.py +++ b/tests/compilers/test_ast.py @@ -263,6 +263,21 @@ def test_ast_require(): cant_compile("(require [tests.resources.tlib [* *]])") +def test_ast_no_pointless_imports(): + def contains_import_from(code): + return any([isinstance(node, ast.ImportFrom) + for node in hy_compile(tokenize(code), "__main__").body]) + # `reduce` is a builtin in Python 2, but not Python 3. + # The version of `map` that returns an iterator is a builtin in + # Python 3, but not Python 2. + if PY3: + assert contains_import_from("reduce") + assert not contains_import_from("map") + else: + assert not contains_import_from("reduce") + assert contains_import_from("map") + + def test_ast_good_get(): "Make sure AST can compile valid get" can_compile("(get x y)")