Merge pull request #1708 from brandonwillard/defmain-args-fix

Make `defmain` args optional or variadic when empty
This commit is contained in:
Kodi Arfer 2018-12-11 10:32:18 -05:00 committed by GitHub
commit 55ec6a0552
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 7 deletions

View File

@ -21,6 +21,7 @@ New Features
Bug Fixes Bug Fixes
------------------------------ ------------------------------
* Fixed issue with empty arguments in `defmain`.
* `require` now compiles to Python AST. * `require` now compiles to Python AST.
* Fixed circular `require`s. * Fixed circular `require`s.
* Fixed module reloading. * Fixed module reloading.

View File

@ -223,11 +223,17 @@ Such 'o!' params are available within `body` as the equivalent 'g!' symbol."
(defmacro defmain [args &rest body] (defmacro defmain [args &rest body]
"Write a function named \"main\" and do the 'if __main__' dance" "Write a function named \"main\" and do the 'if __main__' dance.
(setv retval (gensym))
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__") `(when (= --name-- "__main__")
(import sys) (import sys)
(setv ~retval ((fn [~@args] ~@body) #* sys.argv)) (setv ~retval ((fn [~@(or args `[&rest ~restval])] ~@body) #* sys.argv))
(if (integer? ~retval) (if (integer? ~retval)
(sys.exit ~retval)))) (sys.exit ~retval))))

View File

@ -325,14 +325,38 @@
(global --name--) (global --name--)
(setv oldname --name--) (setv oldname --name--)
(setv --name-- "__main__") (setv --name-- "__main__")
(defn main []
(print 'Hy) (defn main [x]
42) (print (integer? x))
x)
(try (try
(defmain [&rest args] (defmain [&rest args]
(main)) (main 42))
(assert False)
(except [e SystemExit] (except [e SystemExit]
(assert (= (str e) "42")))) (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)) (setv --name-- oldname))
(defn test-macro-namespace-resolution [] (defn test-macro-namespace-resolution []