Better error messages for fn/defn w/o arglists

When (fn) or (defn) does not get an arglist as first/second parameter,
emit a more descriptive error message, rather than an ugly traceback.

Fixes #716.

Reported-by: Joakim Tall
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
This commit is contained in:
Gergely Nagy 2014-12-12 12:41:52 +01:00
parent e56a8d86aa
commit 6b3c552df4
3 changed files with 14 additions and 0 deletions

View File

@ -1893,6 +1893,9 @@ class HyASTCompiler(object):
called_as = expression.pop(0)
arglist = expression.pop(0)
if not isinstance(arglist, HyList):
raise HyTypeError(expression,
"First argument to (fn) must be a list")
ret, args, defaults, stararg, kwargs = self._parse_lambda_list(arglist)
if PY34:

View File

@ -44,6 +44,8 @@
"define a function `name` with signature `lambda-list` and body `body`"
(if (not (= (type name) HySymbol))
(macro-error name "defn/defun takes a name as first argument"))
(if (not (isinstance lambda-list HyList))
(macro-error name "defn/defun takes a parameter list as second argument"))
`(setv ~name (fn ~lambda-list ~@body)))

View File

@ -52,6 +52,15 @@
(try (eval '(defn lambda [] (print "hello")))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e))))))
(defn test-fn-corner-cases []
"NATIVE: tests that fn/defn handles corner cases gracefully"
(try (eval '(fn "foo"))
(catch [e [Exception]] (assert (in "to (fn) must be a list"
(str e)))))
(try (eval '(defn foo "foo"))
(catch [e [Exception]]
(assert (in "takes a parameter list as second" (str e))))))
(defn test-for-loop []
"NATIVE: test for loops"
(setv count 0)