diff --git a/hy/errors.py b/hy/errors.py index a0cd589..0b7619e 100644 --- a/hy/errors.py +++ b/hy/errors.py @@ -207,6 +207,15 @@ class HySyntaxError(HyLanguageError, SyntaxError): """Error during the Lexing of a Hython expression.""" +class HyWrapperError(HyError, TypeError): + """Errors caused by language model object wrapping. + + These can be caused by improper user-level use of a macro, so they're + not really "internal". If they arise due to anything else, they're an + internal/compiler problem, though. + """ + + def _module_filter_name(module_name): try: compiler_loader = pkgutil.get_loader(module_name) diff --git a/hy/macros.py b/hy/macros.py index d668077..e2cec31 100644 --- a/hy/macros.py +++ b/hy/macros.py @@ -342,10 +342,10 @@ def macroexpand(tree, module, compiler=None, once=False): with macro_exceptions(module, tree, compiler): obj = m(module.__name__, *tree[1:], **opts) - if isinstance(obj, HyExpression): - obj.module = inspect.getmodule(m) + if isinstance(obj, HyExpression): + obj.module = inspect.getmodule(m) - tree = replace_hy_obj(obj, tree) + tree = replace_hy_obj(obj, tree) if once: break diff --git a/hy/models.py b/hy/models.py index 134e322..478c691 100644 --- a/hy/models.py +++ b/hy/models.py @@ -7,6 +7,7 @@ from contextlib import contextmanager from math import isnan, isinf from hy import _initialize_env_var from hy._compat import PY3, str_type, bytes_type, long_type, string_types +from hy.errors import HyWrapperError from fractions import Fraction from clint.textui import colored @@ -64,7 +65,7 @@ def wrap_value(x): new = _wrappers.get(type(x), lambda y: y)(x) if not isinstance(new, HyObject): - raise TypeError("Don't know how to wrap {!r}: {!r}".format(type(x), x)) + raise HyWrapperError("Don't know how to wrap {!r}: {!r}".format(type(x), x)) if isinstance(x, HyObject): new = new.replace(x, recursive=False) if not hasattr(new, "start_column"): diff --git a/tests/native_tests/native_macros.hy b/tests/native_tests/native_macros.hy index 6759f42..d5c48c7 100644 --- a/tests/native_tests/native_macros.hy +++ b/tests/native_tests/native_macros.hy @@ -162,8 +162,8 @@ ") ;; expand the macro twice, should use a different ;; gensym each time - (setv _ast1 (hy-compile (hy-parse macro1) "foo")) - (setv _ast2 (hy-compile (hy-parse macro1) "foo")) + (setv _ast1 (hy-compile (hy-parse macro1) __name__)) + (setv _ast2 (hy-compile (hy-parse macro1) __name__)) (setv s1 (to_source _ast1)) (setv s2 (to_source _ast2)) ;; and make sure there is something new that starts with _;G| @@ -189,8 +189,8 @@ ") ;; expand the macro twice, should use a different ;; gensym each time - (setv _ast1 (hy-compile (hy-parse macro1) "foo")) - (setv _ast2 (hy-compile (hy-parse macro1) "foo")) + (setv _ast1 (hy-compile (hy-parse macro1) __name__)) + (setv _ast2 (hy-compile (hy-parse macro1) __name__)) (setv s1 (to_source _ast1)) (setv s2 (to_source _ast2)) (assert (in (mangle "_;a|") s1)) @@ -213,8 +213,8 @@ ") ;; expand the macro twice, should use a different ;; gensym each time - (setv _ast1 (hy-compile (hy-parse macro1) "foo")) - (setv _ast2 (hy-compile (hy-parse macro1) "foo")) + (setv _ast1 (hy-compile (hy-parse macro1) __name__)) + (setv _ast2 (hy-compile (hy-parse macro1) __name__)) (setv s1 (to_source _ast1)) (setv s2 (to_source _ast2)) (assert (in (mangle "_;res|") s1)) @@ -224,7 +224,7 @@ ;; defmacro/g! didn't like numbers initially because they ;; don't have a startswith method and blew up during expansion (setv macro2 "(defmacro/g! two-point-zero [] `(+ (float 1) 1.0))") - (assert (hy-compile (hy-parse macro2) "foo"))) + (assert (hy-compile (hy-parse macro2) __name__))) (defn test-defmacro! [] ;; defmacro! must do everything defmacro/g! can @@ -243,8 +243,8 @@ ") ;; expand the macro twice, should use a different ;; gensym each time - (setv _ast1 (hy-compile (hy-parse macro1) "foo")) - (setv _ast2 (hy-compile (hy-parse macro1) "foo")) + (setv _ast1 (hy-compile (hy-parse macro1) __name__)) + (setv _ast2 (hy-compile (hy-parse macro1) __name__)) (setv s1 (to_source _ast1)) (setv s2 (to_source _ast2)) (assert (in (mangle "_;res|") s1)) @@ -254,7 +254,7 @@ ;; defmacro/g! didn't like numbers initially because they ;; don't have a startswith method and blew up during expansion (setv macro2 "(defmacro! two-point-zero [] `(+ (float 1) 1.0))") - (assert (hy-compile (hy-parse macro2) "foo")) + (assert (hy-compile (hy-parse macro2) __name__)) (defmacro! foo! [o!foo] `(do ~g!foo ~g!foo)) ;; test that o! becomes g! @@ -507,4 +507,13 @@ in expansions." (assert (= (cut expected 0 -1) (cut output 0 -1))) (assert (or (= (get expected -1) (get output -1)) ;; Handle PyPy's peculiarities - (= (.replace (get expected -1) "global " "") (get output -1))))) + (= (.replace (get expected -1) "global " "") (get output -1)))) + + + ;; This should throw a `HyWrapperError` that gets turned into a + ;; `HyMacroExpansionError`. + (with [excinfo (pytest.raises HyMacroExpansionError)] + (eval '(do (defmacro wrap-error-test [] + (fn [])) + (wrap-error-test)))) + (assert (in "HyWrapperError" (str excinfo.value))))