Merge branch 'glc/redundant-keywords'

Closes #880. The changes compared to the pull request are:

 - defn-alias and defmacro-alias are moved to contrib instead of being
   fully removed.
 - Minor documentation fixes, that were left in after the redundant
   symbol removals.

Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
This commit is contained in:
Gergely Nagy 2015-08-10 09:34:36 +02:00
commit bc81e8cc51
No known key found for this signature in database
GPG Key ID: 0A083C5F06E0DD42
25 changed files with 278 additions and 290 deletions

60
docs/contrib/alias.rst Normal file
View File

@ -0,0 +1,60 @@
============
Alias macros
============
.. versionadded:: 0.12
The alias macro module provides the ``(defn-alias)`` and
``(defmacro-alias)``, that were in Hy core previously.
Macros
======
.. _defn-alias:
defn-alias
------------------------
The ``defn-alias`` macro is much like ``defn``,
with the distinction that instead of defining a function with a single
name, these can also define aliases. Other than taking a list of
symbols for function names as the first parameter, ``defn-alias``
is no different from ``defn``.
.. code-block:: clj
=> (defn-alias [main-name alias] []
... (print "Hello!"))
=> (main-name)
"Hello!"
=> (alias)
"Hello!"
.. _defmacro-alias:
defmacro-alias
--------------
``defmacro-alias`` is used to define macros with multiple names
(aliases). The general format is ``(defmacro-alias [names] [parameters]
expr)``. It creates multiple macros with the same parameter list and
body, under the specified list of names.
The following example defines two macros, both of which allow the user
to write code in infix notation.
.. code-block:: clj
=> (defmacro-alias [infix infi] [code]
... (quasiquote (
... (unquote (get code 1))
... (unquote (get code 0))
... (unquote (get code 2)))))
=> (infix (1 + 1))
2
=> (infi (1 + 1))
2

View File

@ -11,3 +11,4 @@ Contents:
loop
multi
flow
alias

View File

@ -37,7 +37,7 @@ loop
``loop`` establishes a recursion point. With ``loop``, ``recur``
rebinds the variables set in the recursion point and sends code
execution back to that recursion point. If ``recur`` is used in a
non-tail position, an exception is thrown.
non-tail position, an exception is raised.
Usage: `(loop bindings &rest body)`

View File

@ -63,10 +63,10 @@ Compiles down to:
which to do the attribute dereference. It uses bare symbols as attributes
to access (in the example, *bar*, *baz*, *frob*), and compiles the contents
of lists (in the example, ``[(+ 1 2)]``) for indexation. Other arguments
throw a compilation error.
raise a compilation error.
Access to unknown attributes throws an :exc:`AttributeError`. Access to
unknown keys throws an :exc:`IndexError` (on lists and tuples) or a
Access to unknown attributes raises an :exc:`AttributeError`. Access to
unknown keys raises an :exc:`IndexError` (on lists and tuples) or a
:exc:`KeyError` (on dictionaries).
->
@ -289,10 +289,10 @@ conditional expression.
{1: 2, 3: 6, 9: 18, 5: 10, 7: 14}
do / progn
do
----------
``do`` and `progn` are used to evaluate each of their arguments and return the
``do`` is used to evaluate each of its arguments and return the
last one. Return values from every other than the last argument are discarded.
It can be used in ``lambda`` or ``list-comp`` to perform more complex logic as
shown in one of the following examples.
@ -378,10 +378,10 @@ below:
.. _defn:
defn / defun
defn
------------
``defn`` and ``defun`` macros are used to define functions. They take three
``defn`` macro is used to define functions. It takes three
parameters: the *name* of the function to define, a vector of *parameters*,
and the *body* of the function:
@ -488,28 +488,6 @@ Parameters may have the following keywords in front of them:
Availability: Python 3.
.. _defn-alias / defun-alias:
defn-alias / defun-alias
------------------------
.. versionadded:: 0.10.0
The ``defn-alias`` and ``defun-alias`` macros are much like `defn`_,
with the distinction that instead of defining a function with a single
name, these can also define aliases. Other than taking a list of
symbols for function names as the first parameter, ``defn-alias`` and
``defun-alias`` are no different from ``defn`` and ``defun``.
.. code-block:: clj
=> (defn-alias [main-name alias] []
... (print "Hello!"))
=> (main-name)
"Hello!"
=> (alias)
"Hello!"
defmain
-------
@ -571,31 +549,6 @@ between the operands.
=> (infix (1 + 1))
2
.. _defmacro-alias:
defmacro-alias
--------------
``defmacro-alias`` is used to define macros with multiple names
(aliases). The general format is ``(defmacro-alias [names] [parameters]
expr)``. It creates multiple macros with the same parameter list and
body, under the specified list of names.
The following example defines two macros, both of which allow the user
to write code in infix notation.
.. code-block:: clj
=> (defmacro-alias [infix infi] [code]
... (quasiquote (
... (unquote (get code 1))
... (unquote (get code 0))
... (unquote (get code 2)))))
=> (infix (1 + 1))
2
=> (infi (1 + 1))
2
.. _defmacro/g!:
@ -835,7 +788,7 @@ assign a value to a global symbol. Reading a global symbol does not require the
The following example shows how the global symbol ``a`` is assigned a value in a
function and is later on printed in another function. Without the ``global``
keyword, the second function would have thrown a ``NameError``.
keyword, the second function would have raised a ``NameError``.
.. code-block:: clj
@ -881,47 +834,39 @@ an empty sequence, and an empty dictionary are considered ``False``; everything
else is considered ``True``.
lisp-if / lif and lisp-if-not / lif-not
lif and lif-not
---------------------------------------
.. versionadded:: 0.10.0
.. versionadded:: 0.11.0
lisp-if-not / lif-not
lif-not
For those that prefer a more Lispy ``if`` clause, we have ``lisp-if``, or
For those that prefer a more Lispy ``if`` clause, we have
``lif``. This *only* considers ``None`` / ``nil`` to be false! All other
"false-ish" Python values are considered true. Conversely, we have
``lisp-if-not`` and ``lif-not`` in parallel to ``if`` and ``if-not`` which
``lif-not`` in parallel to ``if`` and ``if-not`` which
reverses the comparison.
.. code-block:: clj
=> (lisp-if True "true" "false")
"true"
=> (lisp-if False "true" "false")
"true"
=> (lisp-if 0 "true" "false")
"true"
=> (lisp-if nil "true" "false")
"false"
=> (lisp-if None "true" "false")
"false"
=> (lisp-if-not nil "true" "false")
"true"
=> (lisp-if-not None "true" "false")
"true"
=> (lisp-if-not False "true" "false")
"false"
; Equivalent but shorter
=> (lif True "true" "false")
"true"
=> (lif False "true" "false")
"true"
=> (lif 0 "true" "false")
"true"
=> (lif nil "true" "false")
"false"
=> (lif None "true" "false")
"false"
=> (lif-not nil "true" "false")
"true"
=> (lif-not None "true" "false")
"true"
=> (lif-not False "true" "false")
"false"
import
@ -1275,45 +1220,45 @@ counted starting from the end of the list. Some example usage:
[6, 7]
throw / raise
raise
-------------
The ``throw`` or ``raise`` forms can be used to raise an ``Exception`` at
The ``raise`` form can be used to raise an ``Exception`` at
runtime. Example usage:
.. code-block:: clj
(throw)
(raise)
; re-rase the last exception
(throw IOError)
; Throw an IOError
(raise IOError)
; raise an IOError
(throw (IOError "foobar"))
; Throw an IOError("foobar")
(raise (IOError "foobar"))
; raise an IOError("foobar")
``throw`` can accept a single argument (an ``Exception`` class or instance)
``raise`` can accept a single argument (an ``Exception`` class or instance)
or no arguments to re-raise the last ``Exception``.
try
---
The ``try`` form is used to start a ``try`` / ``catch`` block. The form is
The ``try`` form is used to start a ``try`` / ``except`` block. The form is
used as follows:
.. code-block:: clj
(try
(error-prone-function)
(catch [e ZeroDivisionError] (print "Division by zero"))
(except [e ZeroDivisionError] (print "Division by zero"))
(else (print "no errors"))
(finally (print "all done")))
``try`` must contain at least one ``catch`` block, and may optionally include
an ``else`` or ``finally`` block. If an error is raised with a matching catch
block during the execution of ``error-prone-function``, that ``catch`` block
``try`` must contain at least one ``except`` block, and may optionally include
an ``else`` or ``finally`` block. If an error is raised with a matching except
block during the execution of ``error-prone-function``, that ``except`` block
will be executed. If no errors are raised, the ``else`` block is executed. The
``finally`` block will be executed last regardless of whether or not an error
was raised.

View File

@ -1072,7 +1072,7 @@ if *from-file* ends before a complete expression can be parsed.
... (do
... (print "OHY" exp)
... (eval exp))))
... (catch [e EOFError]
... (except [e EOFError]
... (print "EOF!"))))
OHY ('print' 'hello')
hello

View File

@ -7,7 +7,7 @@
(try
(import [urllib.request [urlopen]])
(catch [ImportError]
(except [ImportError]
(import [urllib2 [urlopen]])))
(defn get-rss-feed-name [tumblr]

View File

@ -748,15 +748,13 @@ class HyASTCompiler(object):
return ret
@builds("do")
@builds("progn")
def compile_progn(self, expression):
def compile_do(self, expression):
expression.pop(0)
return self._compile_branch(expression)
@builds("throw")
@builds("raise")
@checkargs(multiple=[0, 1, 3])
def compile_throw_expression(self, expr):
def compile_raise_expression(self, expr):
expr.pop(0)
ret = Result()
if expr:
@ -828,7 +826,7 @@ class HyASTCompiler(object):
if not len(e):
raise HyTypeError(e, "Empty list not allowed in `try'")
if e[0] in (HySymbol("except"), HySymbol("catch")):
if e[0] == HySymbol("except"):
handler_results += self._compile_catch_expression(e, name)
handlers.append(handler_results.stmts.pop())
elif e[0] == HySymbol("else"):
@ -906,7 +904,6 @@ class HyASTCompiler(object):
return accumulated
@builds("except")
@builds("catch")
def magic_internal_form(self, expr):
raise HyTypeError(expr,
"Error: `%s' can't be used like that." % (expr[0]))
@ -2373,7 +2370,7 @@ class HyASTCompiler(object):
@builds("eval_and_compile")
def compile_eval_and_compile(self, expression):
expression[0] = HySymbol("progn")
expression[0] = HySymbol("do")
hy.importer.hy_eval(expression,
compile_time_ns(self.module_name),
self.module_name)
@ -2382,7 +2379,7 @@ class HyASTCompiler(object):
@builds("eval_when_compile")
def compile_eval_when_compile(self, expression):
expression[0] = HySymbol("progn")
expression[0] = HySymbol("do")
hy.importer.hy_eval(expression,
compile_time_ns(self.module_name),
self.module_name)

39
hy/contrib/alias.hy Normal file
View File

@ -0,0 +1,39 @@
;; Copyright (c) 2014, 2015 Gergely Nagy
;; Copyright (c) 2014, 2015 Paul Tagliamonte <paultag@debian.org>
;; Permission is hereby granted, free of charge, to any person obtaining a
;; copy of this software and associated documentation files (the "Software"),
;; to deal in the Software without restriction, including without limitation
;; the rights to use, copy, modify, merge, publish, distribute, sublicense,
;; and/or sell copies of the Software, and to permit persons to whom the
;; Software is furnished to do so, subject to the following conditions:
;; The above copyright notice and this permission notice shall be included in
;; all copies or substantial portions of the Software.
;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
;; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
;; DEALINGS IN THE SOFTWARE.
(defmacro defmacro-alias [names lambda-list &rest body]
"define one macro with several names"
(setv ret `(do))
(for* [name names]
(.append ret
`(defmacro ~name ~lambda-list ~@body)))
ret)
(defmacro defn-alias [names lambda-list &rest body]
"define one function with several names"
(let [[main (first names)]
[aliases (rest names)]]
(setv ret `(do (defn ~main ~lambda-list ~@body)))
(for* [name aliases]
(.append ret
`(setv ~name ~main)))
ret))

View File

@ -18,7 +18,7 @@
;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
;; DEALINGS IN THE SOFTWARE.
(defun Botsbuildbots () (Botsbuildbots))
(defn Botsbuildbots () (Botsbuildbots))
(defmacro Botsbuildbots []
"Build bots, repeatedly.^W^W^WPrint the AUTHORS, forever."
@ -29,5 +29,5 @@
(let [[r (requests.get
"https://raw.githubusercontent.com/hylang/hy/master/AUTHORS")]]
(repeat r.text)))
(catch [e ImportError]
(except [e ImportError]
(repeat "Botsbuildbots requires `requests' to function."))))

View File

@ -75,7 +75,7 @@
(defmacro/g! loop [bindings &rest body]
;; Use inside functions like so:
;; (defun factorial [n]
;; (defn factorial [n]
;; (loop [[i n]
;; [acc 1]]
;; (if (= i 0)

View File

@ -7,7 +7,7 @@
{"methods" ~methods})]]
(with-decorator deco
(defn ~name ~params
(progn ~@code)))))
(do ~@code)))))
;; Some macro examples
(defmacro route [name path params &rest code]

View File

@ -31,21 +31,12 @@
`(raise (hy.errors.HyMacroExpansionError ~location ~reason)))
(defmacro defmacro-alias [names lambda-list &rest body]
"define one macro with several names"
(setv ret `(do))
(for* [name names]
(.append ret
`(defmacro ~name ~lambda-list ~@body)))
ret)
(defmacro-alias [defn defun] [name lambda-list &rest body]
(defmacro defn [name lambda-list &rest body]
"define a function `name` with signature `lambda-list` and body `body`"
(if (not (= (type name) HySymbol))
(macro-error name "defn/defun takes a name as first argument"))
(macro-error name "defn takes a name as first argument"))
(if (not (isinstance lambda-list HyList))
(macro-error name "defn/defun takes a parameter list as second argument"))
(macro-error name "defn takes a parameter list as second argument"))
`(setv ~name (fn ~lambda-list ~@body)))

View File

@ -222,8 +222,8 @@
"Return True if char `x` parses as an integer"
(try
(integer? (int x))
(catch [e ValueError] False)
(catch [e TypeError] False)))
(except [e ValueError] False)
(except [e TypeError] False)))
(defn interleave [&rest seqs]
"Return an iterable of the first item in each of seqs, then the second etc."
@ -381,7 +381,7 @@
(while true
(def inn (str (.read from-file 1)))
(if (= inn eof)
(throw (EOFError "Reached end of file" )))
(raise (EOFError "Reached end of file" )))
(setv buff (+ buff inn))
(try
(def parsed (first (tokenize buff)))
@ -414,7 +414,7 @@
(HyKeyword (+ ":" (hyify value)))
(try
(hyify (.__name__ value))
(catch [] (HyKeyword (+ ":" (string value))))))))
(except [] (HyKeyword (+ ":" (string value))))))))
(defn name [value]
"Convert the given value to a string. Keyword special character will be stripped.
@ -425,7 +425,7 @@
(hyify value)
(try
(hyify (. value __name__))
(catch [] (string value))))))
(except [] (string value))))))
(def *exports*
'[butlast calling-module-name coll? cons cons? cycle dec distinct disassemble

View File

@ -149,11 +149,11 @@
`(if (not ~test) ~not-branch ~yes-branch)))
(defmacro-alias [lisp-if lif] [test &rest branches]
(defmacro lif [test &rest branches]
"Like `if`, but anything that is not None/nil is considered true."
`(if (is-not ~test nil) ~@branches))
(defmacro-alias [lisp-if-not lif-not] [test &rest branches]
(defmacro lif-not [test &rest branches]
"Like `if-not`, but anything that is not None/nil is considered true."
`(if (is ~test nil) ~@branches))
@ -189,7 +189,7 @@
(try (if (isinstance ~g!iter types.GeneratorType)
(setv ~g!message (yield (.send ~g!iter ~g!message)))
(setv ~g!message (yield (next ~g!iter))))
(catch [~g!e StopIteration]
(except [~g!e StopIteration]
(do (setv ~g!return (if (hasattr ~g!e "value")
(. ~g!e value)
nil))
@ -210,16 +210,6 @@
(sys.exit ~retval)))))
(defmacro-alias [defn-alias defun-alias] [names lambda-list &rest body]
"define one function with several names"
(let [[main (first names)]
[aliases (rest names)]]
(setv ret `(do (defn ~main ~lambda-list ~@body)))
(for* [name aliases]
(.append ret
`(setv ~name ~main)))
ret))
(defreader @ [expr]
(let [[decorators (cut expr nil -1)]
[fndef (get expr -1)]]

View File

@ -116,6 +116,6 @@ class HyMacroExpansionError(HyTypeError):
class HyIOError(HyError, IOError):
"""
Trivial subclass of IOError and HyError, to distinguish between
IOErrors thrown by Hy itself as opposed to Hy programs.
IOErrors raised by Hy itself as opposed to Hy programs.
"""
pass

View File

@ -7,13 +7,13 @@
(setv *maintainer-line*
" -- Alexander Artemenko <svetlyak.40wt@gmail.com> Thu, 30 Sep 2014 13:06:09 +0400")
(defun read-lines-from-file [filename]
(defn read-lines-from-file [filename]
(let [[f (codecs.open filename "r" "utf-8")]]
(fn [] (let [[line (.readline f) ]]
line))))
(defun get-version-number [line]
(defn get-version-number [line]
(let [[match (re.search r"Changes from.*(\d+\.\d+\.\d+)$" line)]]
(if match
(let [[version (.group match (int 1))]
@ -26,7 +26,7 @@
(.join "." (map str numbered)))))))
(defun read-version-content [reader]
(defn read-version-content [reader]
(setv line (reader))
(setv content [])
(while (and line (not (get-version-number line)))
@ -35,12 +35,12 @@
[content line])
(defun read-versions-from-file [filename]
(defn read-versions-from-file [filename]
(let [[reader (read-lines-from-file filename)]]
(read-versions-rec (reader)
reader)))
(defun read-versions-rec [line reader]
(defn read-versions-rec [line reader]
(if line
(let [[version (get-version-number line)]
[[content next-line] (read-version-content reader)]]
@ -50,7 +50,7 @@
(read-versions-rec next-line reader)))
[]))
(defun format-deb-version [version]
(defn format-deb-version [version]
(setv result [(.format "hy ({}) unstable; urgency=low"
(get version "from"))])
(for [line (get version "content")]

View File

@ -111,17 +111,6 @@ def test_ast_good_do():
can_compile("(do 1)")
def test_ast_good_throw():
"Make sure AST can compile valid throw"
can_compile("(throw)")
can_compile("(throw Exception)")
def test_ast_bad_throw():
"Make sure AST can't compile invalid throw"
cant_compile("(throw Exception Exception)")
def test_ast_good_raise():
"Make sure AST can compile valid raise"
can_compile("(raise)")
@ -160,26 +149,6 @@ def test_ast_bad_try():
cant_compile("(try 1 (else 1))")
def test_ast_good_catch():
"Make sure AST can compile valid catch"
can_compile("(try 1 (catch))")
can_compile("(try 1 (catch []))")
can_compile("(try 1 (catch [Foobar]))")
can_compile("(try 1 (catch [[]]))")
can_compile("(try 1 (catch [x FooBar]))")
can_compile("(try 1 (catch [x [FooBar BarFoo]]))")
can_compile("(try 1 (catch [x [FooBar BarFoo]]))")
def test_ast_bad_catch():
"Make sure AST can't compile invalid catch"
cant_compile("(catch 22)") # heh
cant_compile("(try (catch 1))")
cant_compile("(try (catch \"A\"))")
cant_compile("(try (catch [1 3]))")
cant_compile("(try (catch [x [FooBar] BarBar]))")
def test_ast_good_except():
"Make sure AST can compile valid except"
can_compile("(try 1 (except))")

View File

@ -0,0 +1,8 @@
(require hy.contrib.alias)
(defn test-defn-alias []
(defn-alias [tda-main tda-a1 tda-a2] [] :bazinga)
(assert (= (tda-main) :bazinga))
(assert (= (tda-a1) :bazinga))
(assert (= (tda-a2) :bazinga))
(assert (= tda-main tda-a1 tda-a2)))

View File

@ -18,7 +18,7 @@
;; non-tco-sum should fail
(try
(setv n (non-tco-sum 100 10000))
(catch [e RuntimeError]
(except [e RuntimeError]
(assert true))
(else
(assert false)))
@ -26,7 +26,7 @@
;; tco-sum should not fail
(try
(setv n (tco-sum 100 10000))
(catch [e RuntimeError]
(except [e RuntimeError]
(assert false))
(else
(assert (= n 10100)))))
@ -40,7 +40,7 @@
(try
(bad-recur 3)
(catch [e TypeError]
(except [e TypeError]
(assert true))
(else
(assert false))))

View File

@ -67,11 +67,11 @@
(assert-equal -1 (dec 0))
(assert-equal 0 (dec (dec 2)))
(try (do (dec "foo") (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
(except [e [TypeError]] (assert (in "not a number" (str e)))))
(try (do (dec []) (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
(except [e [TypeError]] (assert (in "not a number" (str e)))))
(try (do (dec None) (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e))))))
(except [e [TypeError]] (assert (in "not a number" (str e))))))
(defn test-setv []
"NATIVE: testing setv mutation"
@ -85,9 +85,9 @@
(assert-equal (x y) 9)
(assert-equal (y x) 9)
(try (do (setv a.b 1) (assert False))
(catch [e [NameError]] (assert (in "name 'a' is not defined" (str e)))))
(except [e [NameError]] (assert (in "name 'a' is not defined" (str e)))))
(try (do (setv b.a (fn [x] x)) (assert False))
(catch [e [NameError]] (assert (in "name 'b' is not defined" (str e)))))
(except [e [NameError]] (assert (in "name 'b' is not defined" (str e)))))
(import itertools)
(setv foopermutations (fn [x] (itertools.permutations x)))
(setv p (set [(, 1 3 2) (, 3 2 1) (, 2 1 3) (, 3 1 2) (, 1 2 3) (, 2 3 1)]))
@ -127,7 +127,7 @@
(setv res (list (drop 0 [1 2 3 4 5])))
(assert-equal res [1 2 3 4 5])
(try (do (list (drop -1 [1 2 3 4 5])) (assert False))
(catch [e [ValueError]] nil))
(except [e [ValueError]] nil))
(setv res (list (drop 6 (iter [1 2 3 4 5]))))
(assert-equal res [])
(setv res (list (take 5 (drop 2 (iterate inc 0)))))
@ -174,11 +174,11 @@
(assert-false (even? 1))
(assert-true (even? 0))
(try (even? "foo")
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
(except [e [TypeError]] (assert (in "not a number" (str e)))))
(try (even? [])
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
(except [e [TypeError]] (assert (in "not a number" (str e)))))
(try (even? None)
(catch [e [TypeError]] (assert (in "not a number" (str e))))))
(except [e [TypeError]] (assert (in "not a number" (str e))))))
(defn test-every? []
"NATIVE: testing the every? function"
@ -221,9 +221,9 @@
(setv res (flatten (, 1 (, None 3))))
(assert-equal res [1 None 3])
(try (flatten "foo")
(catch [e [TypeError]] (assert (in "not a collection" (str e)))))
(except [e [TypeError]] (assert (in "not a collection" (str e)))))
(try (flatten 12.34)
(catch [e [TypeError]] (assert (in "not a collection" (str e))))))
(except [e [TypeError]] (assert (in "not a collection" (str e))))))
(defn test-float? []
"NATIVE: testing the float? function"
@ -264,11 +264,11 @@
(assert-equal 3 (inc 2))
(assert-equal 0 (inc -1))
(try (do (inc "foo") (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
(except [e [TypeError]] (assert (in "not a number" (str e)))))
(try (do (inc []) (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
(except [e [TypeError]] (assert (in "not a number" (str e)))))
(try (do (inc None) (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e))))))
(except [e [TypeError]] (assert (in "not a number" (str e))))))
(defn test-instance []
"NATIVE: testing instance? function"
@ -395,11 +395,11 @@
(assert-false (neg? 1))
(assert-false (neg? 0))
(try (do (neg? "foo") (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
(except [e [TypeError]] (assert (in "not a number" (str e)))))
(try (do (neg? []) (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
(except [e [TypeError]] (assert (in "not a number" (str e)))))
(try (do (neg? None) (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e))))))
(except [e [TypeError]] (assert (in "not a number" (str e))))))
(defn test-zero []
"NATIVE: testing the zero? function"
@ -407,11 +407,11 @@
(assert-false (zero? 1))
(assert-true (zero? 0))
(try (do (zero? "foo") (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
(except [e [TypeError]] (assert (in "not a number" (str e)))))
(try (do (zero? []) (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
(except [e [TypeError]] (assert (in "not a number" (str e)))))
(try (do (zero? None) (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e))))))
(except [e [TypeError]] (assert (in "not a number" (str e))))))
(defn test-none []
"NATIVE: testing for `is None`"
@ -438,7 +438,7 @@
(assert-equal (nth [1 2 4 7] 5 "some default value")
"some default value") ; with default specified
(try (do (nth [1 2 4 7] -1) (assert False))
(catch [e [ValueError]] nil))
(except [e [ValueError]] nil))
;; now for iterators
(assert-equal 2 (nth (iter [1 2 4 7]) 1))
(assert-equal 7 (nth (iter [1 2 4 7]) 3))
@ -446,7 +446,7 @@
(assert-equal (nth (iter [1 2 4 7]) 5 "some default value")
"some default value") ; with default specified
(try (do (nth (iter [1 2 4 7]) -1) (assert False))
(catch [e [ValueError]] nil))
(except [e [ValueError]] nil))
(assert-equal 5 (nth (take 3 (drop 2 [1 2 3 4 5 6])) 2)))
(defn test-numeric? []
@ -464,11 +464,11 @@
(assert-true (odd? 1))
(assert-false (odd? 0))
(try (do (odd? "foo") (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
(except [e [TypeError]] (assert (in "not a number" (str e)))))
(try (do (odd? []) (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
(except [e [TypeError]] (assert (in "not a number" (str e)))))
(try (do (odd? None) (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e))))))
(except [e [TypeError]] (assert (in "not a number" (str e))))))
(defn test-partition []
"NATIVE: testing the partition function"
@ -488,11 +488,11 @@
(assert-false (pos? -1))
(assert-false (pos? 0))
(try (do (pos? "foo") (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
(except [e [TypeError]] (assert (in "not a number" (str e)))))
(try (do (pos? []) (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e)))))
(except [e [TypeError]] (assert (in "not a number" (str e)))))
(try (do (pos? None) (assert False))
(catch [e [TypeError]] (assert (in "not a number" (str e))))))
(except [e [TypeError]] (assert (in "not a number" (str e))))))
(defn test-remove []
"NATIVE: testing the remove function"
@ -555,7 +555,7 @@
(setv res (list (take 0 (repeat "s"))))
(assert-equal res [])
(try (do (list (take -1 (repeat "s"))) (assert False))
(catch [e [ValueError]] nil))
(except [e [ValueError]] nil))
(setv res (list (take 6 [1 2 None 4])))
(assert-equal res [1 2 None 4]))
@ -582,7 +582,7 @@
(let [[passed false]]
(try
(setv res (list (take-nth 0 [1 2 3 4 5 6 7])))
(catch [ValueError] (setv passed true)))
(except [ValueError] (setv passed true)))
(assert passed)))
(defn test-take-while []

View File

@ -43,25 +43,25 @@
(defn test-setv-builtin []
"NATIVE: test that setv doesn't work on builtins"
(try (eval '(setv False 1))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv True 0))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv None 1))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv false 1))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv true 0))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv nil 1))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv null 1))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(defn defclass [] (print "hello")))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(defn get [] (print "hello")))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(defn lambda [] (print "hello")))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e))))))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e))))))
(defn test-setv-pairs []
@ -72,16 +72,16 @@
(setv y 0 x 1 y x)
(assert y)
(try (eval '(setv a 1 b))
(catch [e [TypeError]] (assert (in "setv needs an even number of arguments" (str e))))))
(except [e [TypeError]] (assert (in "setv needs an even number of arguments" (str e))))))
(defn test-fn-corner-cases []
"NATIVE: tests that fn/defn handles corner cases gracefully"
(try (eval '(fn "foo"))
(catch [e [Exception]] (assert (in "to (fn) must be a list"
(except [e [Exception]] (assert (in "to (fn) must be a list"
(str e)))))
(try (eval '(defn foo "foo"))
(catch [e [Exception]]
(except [e [Exception]]
(assert (in "takes a parameter list as second" (str e))))))
(defn test-for-loop []
@ -115,21 +115,21 @@
(for [x (range 2)
y (range 2)]
(break)
(else (throw Exception)))
(else (raise Exception)))
;; OK. This next test will ensure that the else is hooked up to the
;; "inner" iteration
(for [x (range 2)
y (range 2)]
(if (= y 1) (break))
(else (throw Exception)))
(else (raise Exception)))
;; OK. This next test will ensure that the else is hooked up to the
;; "outer" iteration
(for [x (range 2)
y (range 2)]
(if (= x 1) (break))
(else (throw Exception)))
(else (raise Exception)))
;; OK. This next test will ensure that we call the else branch exactly
;; once.
@ -365,22 +365,22 @@
(try
(raise (KeyError))
(catch [[IOError]] (assert false))
(catch [e [KeyError]] (assert e)))
(except [[IOError]] (assert false))
(except [e [KeyError]] (assert e)))
(try
(throw (KeyError))
(raise (KeyError))
(except [[IOError]] (assert false))
(catch [e [KeyError]] (assert e)))
(except [e [KeyError]] (assert e)))
(try
(get [1] 3)
(catch [IndexError] (assert true))
(except [IndexError] (assert true))
(except [IndexError] (do)))
(try
(print foobar42ofthebaz)
(catch [IndexError] (assert false))
(except [IndexError] (assert false))
(except [NameError] (do)))
(try
@ -389,7 +389,7 @@
(try
(get [1] 3)
(catch [e [IndexError NameError]] (assert (isinstance e IndexError))))
(except [e [IndexError NameError]] (assert (isinstance e IndexError))))
(try
(print foobar42ofthebaz)
@ -397,15 +397,15 @@
(try
(print foobar42)
(catch [[IndexError NameError]] (do)))
(except [[IndexError NameError]] (do)))
(try
(get [1] 3)
(catch [[IndexError NameError]] (do)))
(except [[IndexError NameError]] (do)))
(try
(print foobar42ofthebaz)
(catch))
(except))
(try
(print foobar42ofthebaz)
@ -417,7 +417,7 @@
(try
(print foobar42ofthebaz)
(catch []
(except []
(setv foobar42ofthebaz 42)
(assert (= foobar42ofthebaz 42))))
@ -754,7 +754,7 @@
6))
(try
(assert (= x 42)) ; This ain't true
(catch [e [NameError]] (assert e)))
(except [e [NameError]] (assert e)))
(assert (= y 123)))
@ -867,12 +867,12 @@
(assert (= None (eval (quote (print ""))))))
(defmacro assert-throw [exc-type &rest body]
(defmacro assert-raise [exc-type &rest body]
`(try
(do
(eval ~@body)
(assert False "we shouldn't have arrived here"))
(catch [e Exception]
(except [e Exception]
(assert (instance? ~exc-type e)
(.format "Expected exception of type {}, got {}: {}"
(. ~exc-type --name--)
@ -891,16 +891,16 @@
; this should fail with a name error
(eval (quote x) d2)
(assert False "We shouldn't have arrived here"))
(catch [e Exception]
(except [e Exception]
(assert (isinstance e NameError))))))
(defn test-eval-failure []
"NATIVE: test eval failure modes"
(import [hy.errors [HyTypeError]])
(assert-throw HyTypeError '(eval))
(assert-throw HyTypeError '(eval "snafu"))
(assert-throw HyTypeError '(eval 'false []))
(assert-throw HyTypeError '(eval 'false {} 1)))
(assert-raise HyTypeError '(eval))
(assert-raise HyTypeError '(eval "snafu"))
(assert-raise HyTypeError '(eval 'false []))
(assert-raise HyTypeError '(eval 'false {} 1)))
(defn test-import-syntax []
@ -991,7 +991,7 @@
"NATIVE: test requiring macros from python code"
(try
(assert (= "this won't happen" (qplah 1 2 3 4)))
(catch [NameError]))
(except [NameError]))
(require tests.resources.tlib)
(assert (= [1 2 3] (qplah 1 2 3))))
@ -1159,7 +1159,7 @@
"NATIVE: test lambda lists are only parsed in defn"
(try
(foo [&rest spam] 1)
(catch [NameError] True)
(except [NameError] True)
(else (raise AssertionError))))
(defn test-read []
@ -1183,7 +1183,7 @@
(read stdin-buffer)
(try
(read stdin-buffer)
(catch [e Exception]
(except [e Exception]
(assert (isinstance e EOFError)))))
(defn test-read-str []

View File

@ -180,14 +180,14 @@
product-of-test-matrices))
;; Python <= 3.4
(let [[matmul-attempt (try (@ first-test-matrix second-test-matrix)
(catch [e [Exception]] e))]]
(except [e [Exception]] e))]]
(assert (isinstance matmul-attempt NameError)))))
(defn test-augassign-matmul []
"NATIVE: test augmented-assignment matrix multiplication"
(let [[matrix first-test-matrix]
[matmul-attempt (try (@= matrix second-test-matrix)
(catch [e [Exception]] e))]]
(except [e [Exception]] e))]]
(if PY35
(assert (= product-of-test-matrices matrix))
(assert (isinstance matmul-attempt NameError)))))

View File

@ -188,51 +188,39 @@
:yes)))
(defn test-lisp-if []
"test that lisp-if works as expected"
(defn test-lif []
"test that lif works as expected"
; nil is false
(assert (= (lisp-if None "true" "false") "false"))
(assert (= (lisp-if nil "true" "false") "false"))
(assert (= (lif None "true" "false") "false"))
(assert (= (lif nil "true" "false") "false"))
; But everything else is True! Even falsey things.
(assert (= (lisp-if True "true" "false") "true"))
(assert (= (lisp-if False "true" "false") "true"))
(assert (= (lisp-if 0 "true" "false") "true"))
(assert (= (lisp-if "some-string" "true" "false") "true"))
(assert (= (lisp-if "" "true" "false") "true"))
(assert (= (lisp-if (+ 1 2 3) "true" "false") "true"))
; Just to be sure, test the alias lif
(assert (= (lif True "true" "false") "true"))
(assert (= (lif False "true" "false") "true"))
(assert (= (lif 0 "true" "false") "true"))
(assert (= (lif "some-string" "true" "false") "true"))
(assert (= (lif "" "true" "false") "true"))
(assert (= (lif (+ 1 2 3) "true" "false") "true"))
(assert (= (lif nil "true" "false") "false"))
(assert (= (lif 0 "true" "false") "true")))
(defn test-lisp-if-not []
"test that lisp-if-not works as expected"
(defn test-lif-not []
"test that lif-not works as expected"
; nil is false
(assert (= (lisp-if-not None "false" "true") "false"))
(assert (= (lisp-if-not nil "false" "true") "false"))
(assert (= (lif-not None "false" "true") "false"))
(assert (= (lif-not nil "false" "true") "false"))
; But everything else is True! Even falsey things.
(assert (= (lisp-if-not True "false" "true") "true"))
(assert (= (lisp-if-not False "false" "true") "true"))
(assert (= (lisp-if-not 0 "false" "true") "true"))
(assert (= (lisp-if-not "some-string" "false" "true") "true"))
(assert (= (lisp-if-not "" "false" "true") "true"))
(assert (= (lisp-if-not (+ 1 2 3) "false" "true") "true"))
; Just to be sure, test the alias lif-not
(assert (= (lif-not True "false" "true") "true"))
(assert (= (lif-not False "false" "true") "true"))
(assert (= (lif-not 0 "false" "true") "true"))
(assert (= (lif-not "some-string" "false" "true") "true"))
(assert (= (lif-not "" "false" "true") "true"))
(assert (= (lif-not (+ 1 2 3) "false" "true") "true"))
(assert (= (lif-not nil "false" "true") "false"))
(assert (= (lif-not 0 "false" "true") "true")))
(defn test-defn-alias []
(defn-alias [tda-main tda-a1 tda-a2] [] :bazinga)
(defun-alias [tda-main tda-a1 tda-a2] [] :bazinga)
(assert (= (tda-main) :bazinga))
(assert (= (tda-a1) :bazinga))
(assert (= (tda-a2) :bazinga))
(assert (= tda-main tda-a1 tda-a2)))
(defn test-yield-from []
"NATIVE: testing yield from"
(defn yield-from-test []
@ -253,7 +241,7 @@
(yield i))
(try
(yield-from (yield-from-subgenerator-test))
(catch [e AssertionError]
(except [e AssertionError]
(yield 4))))
(assert (= (list (yield-from-test)) [0 1 2 1 2 3 4])))

View File

@ -22,7 +22,7 @@
(let [[kwonly-foo-no-default (fn [&kwonly foo] foo)]
[attempt-to-omit-default (try
(kwonly-foo-no-default)
(catch [e [Exception]] e))]]
(except [e [Exception]] e))]]
;; works
(assert (= (apply kwonly-foo-no-default [] {"foo" "quux"}) "quux"))
;; raises TypeError with appropriate message if not supplied

View File

@ -3,8 +3,8 @@
(let [[x +]]
(assert (try
(x)
(catch [TypeError] True)
(else (throw AssertionError))))
(except [TypeError] True)
(else (raise AssertionError))))
(assert (= (x 1 2 3 4) 10))
(assert (= (x 1 2 3 4 5) 15))
; with strings
@ -24,8 +24,8 @@
(let [[x -]]
(assert (try
(x)
(catch [TypeError] True)
(else (throw AssertionError))))
(except [TypeError] True)
(else (raise AssertionError))))
(assert (= (x 1) -1))
(assert (= (x 2 1) 1))
(assert (= (x 2 1 1) 0))))
@ -44,8 +44,8 @@
(let [[x /]]
(assert (try
(x)
(catch [TypeError] True)
(else (throw AssertionError))))
(except [TypeError] True)
(else (raise AssertionError))))
(assert (= (x 1) 1))
(assert (= (x 8 2) 4))
(assert (= (x 8 2 2) 2))
@ -57,12 +57,12 @@
(for [x [< <= = != >= >]]
(assert (try
(x)
(catch [TypeError] True)
(else (throw AssertionError))))
(except [TypeError] True)
(else (raise AssertionError))))
(assert (try
(x 1)
(catch [TypeError] True)
(else (throw AssertionError)))))
(except [TypeError] True)
(else (raise AssertionError)))))
(for [(, x y) [[< >=]
[<= >]
[= !=]]]