diff --git a/hy/compiler.py b/hy/compiler.py index c2e4dc3..ca8c0e9 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -2449,6 +2449,9 @@ class HyASTCompiler(object): raise HyTypeError(name, ("received a `%s' instead of a symbol " "for macro name" % type(name).__name__)) name = HyString(name).replace(name) + for kw in ("&kwonly", "&kwargs", "&key"): + if kw in expression[0]: + raise HyTypeError(name, "macros cannot use %s" % kw) new_expression = HyExpression([ HySymbol("with_decorator"), HyExpression([HySymbol("hy.macros.macro"), name]), diff --git a/tests/native_tests/native_macros.hy b/tests/native_tests/native_macros.hy index f833a30..eca4538 100644 --- a/tests/native_tests/native_macros.hy +++ b/tests/native_tests/native_macros.hy @@ -1,3 +1,5 @@ +(import [hy.errors [HyTypeError]]) + (defmacro rev [&rest body] "Execute the `body` statements in reverse" (quasiquote (do (unquote-splice (list (reversed body)))))) @@ -48,6 +50,26 @@ (defmacro bar [x y] (foo x y)) +(defn test-macro-kw [] + "NATIVE: test that an error is raised when &kwonly, &kwargs, or &key is used in a macro" + (try + (eval '(defmacro f [&kwonly a b])) + (except [e HyTypeError] + (assert (= e.message "macros cannot use &kwonly"))) + (else (assert false))) + + (try + (eval '(defmacro f [&kwargs kw])) + (except [e HyTypeError] + (assert (= e.message "macros cannot use &kwargs"))) + (else (assert false))) + + (try + (eval '(defmacro f [&key {"kw" "xyz"}])) + (except [e HyTypeError] + (assert (= e.message "macros cannot use &key"))) + (else (assert false)))) + (defn test-fn-calling-macro [] "NATIVE: test macro calling a plain function" (assert (= 3 (bar 1 2))))