From b8b02c9df9e58808d9c7f6d1c048fc87f9cb65db Mon Sep 17 00:00:00 2001 From: "Brandon T. Willard" Date: Mon, 26 Nov 2018 13:17:32 -0600 Subject: [PATCH] Handle empty `defmain` args Closes hylang/hy#1707. --- hy/core/macros.hy | 12 ++++++++--- tests/native_tests/native_macros.hy | 32 +++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 7 deletions(-) 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 []