diff --git a/hy/core/macros.hy b/hy/core/macros.hy index 0e6ab5f..f8ce33b 100644 --- a/hy/core/macros.hy +++ b/hy/core/macros.hy @@ -223,11 +223,17 @@ Such 'o!' params are available within `body` as the equivalent 'g!' symbol." (defmacro defmain [args &rest body] - "Write a function named \"main\" and do the 'if __main__' dance" - (setv retval (gensym)) + "Write a function named \"main\" and do the 'if __main__' dance. + +The symbols in `args` are bound to the elements in `sys.argv`, which means that +the first symbol in `args` will always take the value of the script/executable +name (i.e. `sys.argv[0]`). +" + (setv retval (gensym) + restval (gensym)) `(when (= --name-- "__main__") (import sys) - (setv ~retval ((fn [~@args] ~@body) #* sys.argv)) + (setv ~retval ((fn [~@(or args `[&rest ~restval])] ~@body) #* sys.argv)) (if (integer? ~retval) (sys.exit ~retval)))) diff --git a/tests/native_tests/native_macros.hy b/tests/native_tests/native_macros.hy index fc17edb..b5cb979 100644 --- a/tests/native_tests/native_macros.hy +++ b/tests/native_tests/native_macros.hy @@ -325,14 +325,38 @@ (global --name--) (setv oldname --name--) (setv --name-- "__main__") - (defn main [] - (print 'Hy) - 42) + + (defn main [x] + (print (integer? x)) + x) + (try (defmain [&rest args] - (main)) + (main 42)) + (assert False) (except [e SystemExit] (assert (= (str e) "42")))) + + ;; Try a `defmain` without args + (try + (defmain [] + (main 42)) + (assert False) + (except [e SystemExit] + (assert (= (str e) "42")))) + + ;; Try a `defmain` with only one arg + (import sys) + (setv oldargv sys.argv) + (try + (setv sys.argv [1]) + (defmain [x] + (main x)) + (assert False) + (except [e SystemExit] + (assert (= (str e) "1")))) + + (setv sys.argv oldargv) (setv --name-- oldname)) (defn test-macro-namespace-resolution []