From 4b0296d257be392068ed1ffbab037857fa8bbc38 Mon Sep 17 00:00:00 2001 From: Kodi Arfer Date: Tue, 11 Oct 2016 14:04:50 -0700 Subject: [PATCH] Don't check the type of arguments to `inc`, `odd?`, etc. This allows them to be used with numeric types that aren't built in, such as NumPy arrays. Because Python uses duck typing, there's generally no way to know in advance whether a given value will accept a given operator. Of course, things like `(inc "hello")` will still raise a `TypeError`, because so does `(+ "hello" 1)`. --- hy/core/language.hy | 11 ------- tests/native_tests/core.hy | 59 +++++++++++--------------------------- 2 files changed, 16 insertions(+), 54 deletions(-) diff --git a/hy/core/language.hy b/hy/core/language.hy index 07bc202..b7fce7e 100644 --- a/hy/core/language.hy +++ b/hy/core/language.hy @@ -39,10 +39,6 @@ (import [hy.lex [LexException PrematureEndOfInput tokenize]]) (import [hy.compiler [HyASTCompiler]]) -(defn _numeric-check [x] - (if (not (numeric? x)) - (raise (TypeError (.format "{0!r} is not a number" x))))) - (defn butlast [coll] "Returns coll except of last element." (drop-last 1 coll)) @@ -66,7 +62,6 @@ (defn dec [n] "Decrement n by 1" - (_numeric-check n) (- n 1)) (defn disassemble [tree &optional [codegen false]] @@ -170,7 +165,6 @@ (defn even? [n] "Return true if n is an even number" - (_numeric-check n) (= (% n 2) 0)) (defn every? [pred coll] @@ -239,7 +233,6 @@ (defn inc [n] "Increment n by 1" - (_numeric-check n) (+ n 1)) (defn instance? [klass x] @@ -325,7 +318,6 @@ (defn neg? [n] "Return true if n is < 0" - (_numeric-check n) (< n 0)) (defn none? [x] @@ -347,7 +339,6 @@ (defn odd? [n] "Return true if n is an odd number" - (_numeric-check n) (= (% n 2) 1)) (def -sentinel (object)) @@ -364,7 +355,6 @@ (defn pos? [n] "Return true if n is > 0" - (_numeric_check n) (> n 0)) (defn rest [coll] @@ -415,7 +405,6 @@ (defn zero? [n] "Return true if n is 0" - (_numeric_check n) (= n 0)) (defn read [&optional [from-file sys.stdin] diff --git a/tests/native_tests/core.hy b/tests/native_tests/core.hy index 9e3ad52..ead3960 100644 --- a/tests/native_tests/core.hy +++ b/tests/native_tests/core.hy @@ -33,6 +33,11 @@ (defn assert-nil [x] (assert (is x nil))) +(defn assert-requires-num [f] + (for [x ["foo" [] None]] + (assert-true (try (do (f x) False) + (except [e [TypeError]] True))))) + (defn test-coll? [] "NATIVE: testing coll?" (assert-true (coll? [1 2 3])) @@ -66,12 +71,7 @@ (assert-equal 0 (dec 1)) (assert-equal -1 (dec 0)) (assert-equal 0 (dec (dec 2))) - (try (do (dec "foo") (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e))))) - (try (do (dec []) (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e))))) - (try (do (dec None) (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e)))))) + (assert-requires-num dec)) (defn test-setv [] "NATIVE: testing setv mutation" @@ -173,12 +173,7 @@ (assert-true (even? -2)) (assert-false (even? 1)) (assert-true (even? 0)) - (try (even? "foo") - (except [e [TypeError]] (assert (in "not a number" (str e))))) - (try (even? []) - (except [e [TypeError]] (assert (in "not a number" (str e))))) - (try (even? None) - (except [e [TypeError]] (assert (in "not a number" (str e)))))) + (assert-requires-num even?)) (defn test-every? [] "NATIVE: testing the every? function" @@ -263,12 +258,11 @@ "NATIVE: testing the inc function" (assert-equal 3 (inc 2)) (assert-equal 0 (inc -1)) - (try (do (inc "foo") (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e))))) - (try (do (inc []) (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e))))) - (try (do (inc None) (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e)))))) + (assert-requires-num inc) + + (defclass X [object] + [__add__ (fn [self other] (.format "__add__ got {}" other))]) + (assert-equal (inc (X)) "__add__ got 1")) (defn test-instance [] "NATIVE: testing instance? function" @@ -394,24 +388,13 @@ (assert-true (neg? -2)) (assert-false (neg? 1)) (assert-false (neg? 0)) - (try (do (neg? "foo") (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e))))) - (try (do (neg? []) (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e))))) - (try (do (neg? None) (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e)))))) + (assert-requires-num neg?)) (defn test-zero [] "NATIVE: testing the zero? function" (assert-false (zero? -2)) (assert-false (zero? 1)) - (assert-true (zero? 0)) - (try (do (zero? "foo") (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e))))) - (try (do (zero? []) (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e))))) - (try (do (zero? None) (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e)))))) + (assert-true (zero? 0))) (defn test-none [] "NATIVE: testing for `is None`" @@ -463,12 +446,7 @@ (assert-true (odd? -3)) (assert-true (odd? 1)) (assert-false (odd? 0)) - (try (do (odd? "foo") (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e))))) - (try (do (odd? []) (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e))))) - (try (do (odd? None) (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e)))))) + (assert-requires-num odd?)) (defn test-partition [] "NATIVE: testing the partition function" @@ -500,12 +478,7 @@ (assert-true (pos? 2)) (assert-false (pos? -1)) (assert-false (pos? 0)) - (try (do (pos? "foo") (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e))))) - (try (do (pos? []) (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e))))) - (try (do (pos? None) (assert False)) - (except [e [TypeError]] (assert (in "not a number" (str e)))))) + (assert-requires-num pos?)) (defn test-remove [] "NATIVE: testing the remove function"