hy/tests/native_tests/py3_only_tests.hy
Zack M. Davis ef079d5e08 implement keyword-only arguments
Python 3 supports keyword-only arguments as described in the immortal
PEP 3102. This commit implements keyword-only argument support for Hy
using a `&kwonly` lambda-list-keyword with semantics analogous how
`&optional` arguments are handled: `&kwonly` arguments are either a
symbol, in which case the keyword argument so named is mandatory, or a
two-element list, the first of which is the symbolic name of the keyword
argument and the second of which is its default value if not
supplied. If Hy is running under Python 2, attempting to use `&kwonly`
args will raise a HyTypeError.

This effort is with the aim of resolving #453.
2015-07-22 21:53:06 -07:00

39 lines
1.5 KiB
Hy

;; Tests where the emited code relies on Python 3.
;; Conditionally included in nosetests runs.
(import [hy._compat [PY33]])
(import [hy.errors [HyCompileError]])
(defn test-exception-cause []
(try (raise ValueError :from NameError)
(except [e [ValueError]]
(assert (= (type (. e __cause__)) NameError)))))
(defn test-kwonly []
"NATIVE: test keyword-only arguments"
;; keyword-only with default works
(let [[kwonly-foo-default-false (fn [&kwonly [foo false]] foo)]]
(assert (= (apply kwonly-foo-default-false) false))
(assert (= (apply kwonly-foo-default-false [] {"foo" true}) true)))
;; keyword-only without default ...
(let [[kwonly-foo-no-default (fn [&kwonly foo] foo)]
[attempt-to-omit-default (try
(kwonly-foo-no-default)
(catch [e [Exception]] e))]]
;; works
(assert (= (apply kwonly-foo-no-default [] {"foo" "quux"}) "quux"))
;; raises TypeError with appropriate message if not supplied
(assert (isinstance attempt-to-omit-default TypeError))
(assert (in "missing 1 required keyword-only argument: 'foo'"
(. attempt-to-omit-default args [0]))))
;; keyword-only with other arg types works
(let [[function-of-various-args
(fn [a b &rest args &kwonly foo &kwargs kwargs]
(, a b args foo kwargs))]]
(assert (= (apply function-of-various-args
[1 2 3 4] {"foo" 5 "bar" 6 "quux" 7})
(, 1 2 (, 3 4) 5 {"bar" 6 "quux" 7})))))