defmain macro; handles the whole if __name__ == __main__ / main function dance
Example: (defmain [&rest args] (print "now we're having a fun time!") (print args)) Which outputs: $ hy test.hy now we're having a fun time! (['test.hy'],) Includes documentation and tests.
This commit is contained in:
parent
5de39a4e1d
commit
774aad2ca8
@ -441,6 +441,44 @@ symbols for function names as the first parameter, `defn-alias` and
|
|||||||
=> (alias)
|
=> (alias)
|
||||||
"Hello!"
|
"Hello!"
|
||||||
|
|
||||||
|
|
||||||
|
defmain
|
||||||
|
-------
|
||||||
|
|
||||||
|
.. versionadded:: 0.9.13
|
||||||
|
|
||||||
|
The `defmain` macro defines a main function that is immediately called
|
||||||
|
with sys.argv as arguments if and only if this file is being executed
|
||||||
|
as a script. In other words this:
|
||||||
|
|
||||||
|
.. code-block:: clj
|
||||||
|
|
||||||
|
(defmain [&rest args]
|
||||||
|
(do-something-with args))
|
||||||
|
|
||||||
|
is the equivalent of::
|
||||||
|
|
||||||
|
def main(*args):
|
||||||
|
do_something_with(args)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
retval = main(*sys.arg)
|
||||||
|
|
||||||
|
if isinstance(retval, int):
|
||||||
|
sys.exit(retval)
|
||||||
|
|
||||||
|
Note, as you can see above, if you return an integer from this
|
||||||
|
function, this will be used as the exit status for your script.
|
||||||
|
(Python defaults to exit status 0 otherwise, which means everything's
|
||||||
|
okay!)
|
||||||
|
|
||||||
|
(Since (sys.exit 0) is not run explicitly in case of a non-integer
|
||||||
|
return from defmain, it's good to put (defmain) as the last bit of
|
||||||
|
code in your file.)
|
||||||
|
|
||||||
|
|
||||||
.. _defmacro:
|
.. _defmacro:
|
||||||
|
|
||||||
defmacro
|
defmacro
|
||||||
|
@ -171,6 +171,21 @@
|
|||||||
(let ~(HyList (map (fn [x] `[~x (gensym (slice '~x 2))]) syms))
|
(let ~(HyList (map (fn [x] `[~x (gensym (slice '~x 2))]) syms))
|
||||||
~@body))))
|
~@body))))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro defmain [args &rest body]
|
||||||
|
"Write a function named \"main\" and do the if __main__ dance"
|
||||||
|
(let [[retval (gensym)]]
|
||||||
|
`(do
|
||||||
|
(defn main [~@args]
|
||||||
|
~@body)
|
||||||
|
|
||||||
|
(when (= --name-- "__main__")
|
||||||
|
(import sys)
|
||||||
|
(setv ~retval (apply main sys.argv))
|
||||||
|
(if (integer? ~retval)
|
||||||
|
(sys.exit ~retval))))))
|
||||||
|
|
||||||
|
|
||||||
(defmacro-alias [defn-alias defun-alias] [names lambda-list &rest body]
|
(defmacro-alias [defn-alias defun-alias] [names lambda-list &rest body]
|
||||||
"define one function with several names"
|
"define one function with several names"
|
||||||
(let [[main (first names)]
|
(let [[main (first names)]
|
||||||
|
5
tests/resources/bin/main.hy
Normal file
5
tests/resources/bin/main.hy
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
(defmain [&rest args]
|
||||||
|
(print args)
|
||||||
|
(print "Hello World")
|
||||||
|
(if (in "exit1" args)
|
||||||
|
1))
|
4
tests/resources/bin/nomain.hy
Normal file
4
tests/resources/bin/nomain.hy
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
(print "This Should Still Works")
|
||||||
|
|
||||||
|
(defn main []
|
||||||
|
(print "This Should Not Work"))
|
@ -142,3 +142,27 @@ def test_bin_hy_builtins():
|
|||||||
|
|
||||||
assert str(exit) == "Use (exit) or Ctrl-D (i.e. EOF) to exit"
|
assert str(exit) == "Use (exit) or Ctrl-D (i.e. EOF) to exit"
|
||||||
assert str(quit) == "Use (quit) or Ctrl-D (i.e. EOF) to exit"
|
assert str(quit) == "Use (quit) or Ctrl-D (i.e. EOF) to exit"
|
||||||
|
|
||||||
|
|
||||||
|
def test_bin_hy_main():
|
||||||
|
ret = run_cmd("hy tests/resources/bin/main.hy")
|
||||||
|
assert ret[0] == 0
|
||||||
|
assert "Hello World" in ret[1]
|
||||||
|
|
||||||
|
|
||||||
|
def test_bin_hy_main_args():
|
||||||
|
ret = run_cmd("hy tests/resources/bin/main.hy test 123")
|
||||||
|
assert ret[0] == 0
|
||||||
|
assert "test" in ret[1]
|
||||||
|
assert "123" in ret[1]
|
||||||
|
|
||||||
|
|
||||||
|
def test_bin_hy_main_exitvalue():
|
||||||
|
ret = run_cmd("hy tests/resources/bin/main.hy exit1")
|
||||||
|
assert ret[0] == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_bin_hy_no_main():
|
||||||
|
ret = run_cmd("hy tests/resources/bin/nomain.hy")
|
||||||
|
assert ret[0] == 0
|
||||||
|
assert "This Should Still Work" in ret[1]
|
||||||
|
Loading…
Reference in New Issue
Block a user