From ef8e268eca6cc46f8bbce13d2f55746f4ac09224 Mon Sep 17 00:00:00 2001 From: Allison Casey Date: Fri, 11 Mar 2022 23:32:13 -0800 Subject: [PATCH] Fix: references to old style defmacro tag macros --- tests/compilers/test_ast.py | 9 +- tests/native_tests/core.hy | 8 -- tests/native_tests/language.hy | 5 - tests/native_tests/mangling.hy | 9 -- tests/native_tests/native_macros.hy | 17 +--- tests/native_tests/reader_macros.hy | 12 +-- tests/native_tests/tag_macros.hy | 136 ++++++++++++++++---------- tests/resources/macro_with_require.hy | 11 --- tests/resources/tlib.hy | 3 - tests/test_lex.py | 7 -- 10 files changed, 94 insertions(+), 123 deletions(-) diff --git a/tests/compilers/test_ast.py b/tests/compilers/test_ast.py index 1185c4923..368098f92 100644 --- a/tests/compilers/test_ast.py +++ b/tests/compilers/test_ast.py @@ -273,7 +273,7 @@ def test_ast_good_import_from(): def test_ast_require(): "Make sure AST respects (require) syntax" can_compile("(require tests.resources.tlib)") - can_compile('(require tests.resources.tlib [qplah parald "#taggart"])') + can_compile("(require tests.resources.tlib [qplah parald])") can_compile("(require tests.resources.tlib *)") can_compile("(require tests.resources.tlib :as foobar)") can_compile("(require tests.resources.tlib [qplah :as quiz])") @@ -631,13 +631,6 @@ def test_inline_python(): cant_compile('(pys "if 1\n 2")') -def test_bad_tag_macros(): - # https://github.com/hylang/hy/issues/1965 - cant_compile('(defmacro "#a" [] (raise (ValueError))) #a ()') - cant_compile('(defmacro "#a" [x] (raise (ValueError))) #a ()') - can_compile('(defmacro "#a" [x] 3) #a ()') - - def test_models_accessible(): # https://github.com/hylang/hy/issues/1045 can_eval("hy.models.Symbol") diff --git a/tests/native_tests/core.hy b/tests/native_tests/core.hy index 59d500982..ddd2f14e4 100644 --- a/tests/native_tests/core.hy +++ b/tests/native_tests/core.hy @@ -151,14 +151,6 @@ result['y in globals'] = 'y' in globals()") (assert (in "a fancy docstring" out)) (assert (not err)) - (defmacro "#pillgrums" [x] - "Look at the quality of that picture!" - x) - (doc "#pillgrums") - (setv [out err] (.readouterr capsys)) - (assert (in "Look at the quality of that picture!" out)) - (assert (not err)) - ;; make sure doc raises an error instead of ;; presenting a default value help screen (with [(pytest.raises NameError)] diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy index a6d3298f1..bbb16fb8e 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -1298,7 +1298,6 @@ cee"} dee" "ey bee\ncee dee")) (assert (= (tests.resources.tlib.parald 1 2 3) [9 1 2 3])) (assert (= (tests.resources.tlib.✈ "silly") "plane silly")) (assert (= (tests.resources.tlib.hyx_XairplaneX "foolish") "plane foolish")) - (assert (= #tests.resources.tlib.taggart 15 [10 15])) (with [(pytest.raises NameError)] (parald 1 2 3 4)) @@ -1306,7 +1305,6 @@ cee"} dee" "ey bee\ncee dee")) (assert (= (T.parald 1 2 3) [9 1 2 3])) (assert (= (T.✈ "silly") "plane silly")) (assert (= (T.hyx_XairplaneX "foolish") "plane foolish")) - (assert (= #T.taggart 15 [10 15])) (with [(pytest.raises NameError)] (parald 1 2 3 4)) @@ -1315,9 +1313,6 @@ cee"} dee" "ey bee\ncee dee")) (with [(pytest.raises NameError)] (parald 1 2 3 4)) - (require tests.resources.tlib ["#taggart"]) - (assert (= #taggart 15 [10 15])) - (require tests.resources.tlib *) (assert (= (parald 1 2 3) [9 1 2 3])) (assert (= (✈ "silly") "plane silly")) diff --git a/tests/native_tests/mangling.hy b/tests/native_tests/mangling.hy index 2ab69a268..c0e458e4f 100644 --- a/tests/native_tests/mangling.hy +++ b/tests/native_tests/mangling.hy @@ -109,15 +109,6 @@ (assert (= x "aabb"))) -(defmacro "#tm---x" [form] - [form form]) -(defn test-tag-macro [] - (setv x "") - (assert (= #tm---x (do (+= x "a") 1) [1 1])) - (assert (= #tm___x (do (+= x "b") 2) [2 2])) - (assert (= x "aabb"))) - - (defn test-special-form [] (setv not-in 1) ; We set the variable to make sure that if this test works, it's diff --git a/tests/native_tests/native_macros.hy b/tests/native_tests/native_macros.hy index aa6d8efc0..d5610861d 100644 --- a/tests/native_tests/native_macros.hy +++ b/tests/native_tests/native_macros.hy @@ -75,7 +75,7 @@ (assert (in "got unexpected token: :kw" e.value.msg)) (with [e (pytest.raises HySyntaxError)] - (hy.eval '(defmacro "foo.bar" []))) + (hy.eval '(defmacro foo.bar []))) (assert (in "periods are not allowed in macro names" e.value.msg))) (defn test-macro-calling-fn [] @@ -192,10 +192,6 @@ in expansions." "expanded in tests.native_tests.native_macros.test-macro-namespace-resolution " "and passed the value 2.") (test-module-macro 2))) - (assert (= (+ "This macro was created in tests.resources.macros, " - "expanded in tests.native_tests.native_macros.test-macro-namespace-resolution " - "and passed the value 2.") - #test-module-tag 2)) ;; Now, let's use a `require`d macro that depends on another macro defined only ;; in this scope. @@ -203,9 +199,7 @@ in expansions." (.format "This is the local version of `nonlocal-test-macro` returning {}!" (int x))) (assert (= "This is the local version of `nonlocal-test-macro` returning 3!" - (test-module-macro-2 3))) - (assert (= "This is the local version of `nonlocal-test-macro` returning 3!" - #test-module-tag-2 3))) + (test-module-macro-2 3)))) (defn test-requires-pollutes-core [] ;; https://github.com/hylang/hy/issues/1978 @@ -301,12 +295,7 @@ in expansions." (assert (= (+ "This macro was created in tests.resources.macros, " "expanded in tests.native_tests.native_macros " "and passed the value 1.") - (test-module-macro 1))) - - (assert (= (+ "This macro was created in tests.resources.macros, " - "expanded in tests.native_tests.native_macros " - "and passed the value 1.") - #test-module-tag 1))) + (test-module-macro 1)))) (test-requires-and-macros) diff --git a/tests/native_tests/reader_macros.hy b/tests/native_tests/reader_macros.hy index 7fa5ba542..f19ab2c3b 100644 --- a/tests/native_tests/reader_macros.hy +++ b/tests/native_tests/reader_macros.hy @@ -60,12 +60,12 @@ (assert (= 'HELLO (next it)))) ;; test require :readers & :macros is order independent - (for [s ["[\"#taggart\"] :readers [\"#upper\"]" - ":readers [\"#upper\"] [\"#taggart\"]" - ":macros [\"#taggart\"] :readers [\"#upper\"]" - ":readers [\"#upper\"] :macros [\"#taggart\"]"] - :setv test-str #[f[(require tests.resources.tlib {s}) [#taggart 1 #upper "hello"]]f]] - (assert (= [[10 1] "HELLO"] (eval-module test-str)))) + (for [s ["[qplah] :readers [\"#upper\"]" + ":readers [\"#upper\"] [qplah]" + ":macros [qplah] :readers [\"#upper\"]" + ":readers [\"#upper\"] :macros [qplah]"] + :setv test-str #[f[(require tests.resources.tlib {s}) [(qplah 1) #upper "hello"]]f]] + (assert (= [[8 1] "HELLO"] (eval-module test-str)))) ;; test can't redefine :macros or :readers assignment brackets (with [(pytest.raises hy.errors.HySyntaxError)] diff --git a/tests/native_tests/tag_macros.hy b/tests/native_tests/tag_macros.hy index ef9882f6a..f12269b1f 100644 --- a/tests/native_tests/tag_macros.hy +++ b/tests/native_tests/tag_macros.hy @@ -1,85 +1,105 @@ -(import pytest - functools [wraps]) - +(import + itertools + sys + types + contextlib [contextmanager] + functools [wraps] + + pytest) + +(with-decorator + contextmanager + (defn temp-module [module-name] + (let [module (types.ModuleType module-name) + old-module (sys.modules.get module-name)] + (setv (get sys.modules module-name) module) + (try + (yield module) + (finally + (if old-module + (setv (get sys.modules module-name) module) + (sys.modules.pop module-name))))))) + + +(defn eval-isolated [tree [module None]] + (if module + (hy.eval tree :locals {} :module module) + (with [module (temp-module "")] + (hy.eval tree :locals {} :module module)))) + +(defn eval-n [seq n module] + (lfor node (itertools.islice seq None n) + (eval-isolated node module))) + +(defn eval-module [s] + (eval-isolated (hy.read-module s))) + +(defn run-tag-fn [s] + (fn [input] (eval-module f"{s} {input}"))) (defn test-tag-macro [] "Test a basic tag macro" - (defmacro "#^" [expr] - expr) - - (assert (= #^"works" "works"))) - + (assert (= "works" (eval-module "(deftag ^ [expr] expr) #^ \"works\"")))) (defn test-long-tag-macro [] "Test a tag macro with a name longer than one character" - (defmacro "#foo" [expr] - `['foo ~expr]) - (assert (= #foo'bar ['foo 'bar])) - (assert (= #foo"baz" ['foo "baz"])) - (assert (= #foo(- 44 2) ['foo 42])) - (assert (= #foo(, 42) ['foo (, 42)])) - (assert (= #foo[42] ['foo [42]])) - (assert (= #foo{4 2} ['foo {4 2}]))) + (setv tag-runner (run-tag-fn "(deftag foo [expr] `['foo ~expr])")) + (assert (= ['foo 'bar] (tag-runner "#foo 'bar"))) + (assert (= ['foo "baz"] (tag-runner "#foo \"baz\""))) + (assert (= ['foo 42] (tag-runner "#foo (- 44 2)"))) + (assert (= ['foo (, 42) (tag-runner "#foo (, 42)")])) + (assert (= ['foo [42]] (tag-runner "#foo [42]"))) + (assert (= ['foo {4 2}] (tag-runner "#foo {4 2}")))) (defn test-hyphenated-tag-macro [] "Test if hyphens translate properly" - (defmacro "#foo-bar" [x] - `['foo ~x 'bar]) - (assert (= #foo-bar 42) ['foo 42 'bar]) - (assert (= #foo_bar 42) ['foo 42 'bar]) - (defmacro "#spam_eggs" [x] - `['spam ~x 'eggs]) - (assert (= #spam-eggs 42 ['spam 42 'eggs])) - (assert (= #spam_eggs 42 ['spam 42 'eggs]))) + (setv tag-runner (run-tag-fn "(deftag foo-bar [x] `['foo ~x 'bar])")) + (assert (= ['foo 42 'bar] (tag-runner "#foo-bar 42"))) + (setv tag-runner (run-tag-fn "(deftag spam_eggs [x] `['spam ~x 'eggs])")) + (assert (= ['spam 42 'eggs] (tag-runner "#spam_eggs 42")))) (defn test-bang-tag-macro [] "Test tag macros whose names start with `!`" ; https://github.com/hylang/hy/issues/1334 - (defmacro "#!a" [x] `["foo" ~x]) - (assert (= #!a 3 ["foo" 3])) - (defmacro "#!" [x] `["bar" ~x]) - (assert (= #! 4 ["bar" 4]))) - + (assert (= ["foo" 3] (eval-module "(deftag !a [x] `[\"foo\" ~x]) #!a 3"))) + (assert (= ["bar" 4] (eval-module "(deftag ! [x] `[\"bar\" ~x]) #! 4")))) (defn test-tag-macro-whitespace [] "Test whitespace after a tag macro" - (defmacro "#foo" [expr] - `['foo ~expr]) - (assert (= #foo 42) ['foo 42]) - (assert (= #foo (- 44 2) ['foo 42])) - (defmacro "#b" [x] - `['bar ~x]) - (assert (= #b 42) ['bar 42]) + (setv foo-tag "(deftag foo [expr] `['foo ~expr])") + (setv b-tag "(deftag b [x] `['bar ~x])") + + (assert (= ['foo 42] (eval-module f"{foo-tag} #foo 42"))) + (assert (= ['foo 42] (eval-module f"{foo-tag} #foo (- 44 2)"))) + (assert (= ['bar 42] (eval-module f"{b-tag} #b 42"))) + ; # is allowed in tags, so this must be separated - (assert (= #b #{42} ['bar #{42}])) + (assert (= ['bar #{42}] (eval-module (+ b-tag "#b #{42}")))) ; multiple tags must likewise be separated - (assert (= #b #foo 42 ['bar ['foo 42]])) + (assert (= ['bar ['foo 42]] + (eval-module f"{foo-tag} {b-tag} #b #foo 42"))) ; newlines are also whitespace - (assert (= #foo + (assert (= ['foo 42] (eval-module f"{foo-tag} + #foo - 42 ['foo 42])) - (assert (= #foo; a semicolon/comment should count as whitespace - 42 - ['foo 42]))) + 42"))) + (assert (= ['foo 42] (eval-module f"{foo-tag} + #foo ; a semicolon/comment should count as whitespace + 42")))) (defn test-tag-macro-expr [] "Test basic exprs like lists and arrays" - (defmacro "#n" [expr] - (get expr 1)) - - (assert (= #n[1 2] 2)) - (assert (= #n(1 2) 2))) + (setv tag-runner (run-tag-fn "(deftag n [expr] (get expr 1))")) + (assert (= 2 (tag-runner "#n [1 2]"))) + (assert (= 2 (tag-runner "#n (1 2)")))) (defn test-tag-macro-override [] "Test if we can override function symbols" - (defmacro "#+" [n] - (+ n 1)) - - (assert (= #+ 2 3))) + (assert (= 3 (eval-module "(deftag + [n] (+ n 1)) #+ 2")))) (defn test-builtin-decorator-tag [] (defn increment-arguments [func] @@ -115,3 +135,15 @@ ;; https://github.com/hylang/hy/issues/1565 (with [(pytest.raises hy.lex.exceptions.LexException)] ; and not IndexError (hy.read "#@()"))) + +(defn test-tag-documentation [capsys] + (eval-module #[[ + (deftag pillgrums [x] + "Look at the quality of that picture!" + x) + (doc "#pillgrums") + ]]) + + (setv [out err] (.readouterr capsys)) + (assert (in "Look at the quality of that picture!" out)) + (assert (not err))) diff --git a/tests/resources/macro_with_require.hy b/tests/resources/macro_with_require.hy index 175d6e4a4..c1b69f56f 100644 --- a/tests/resources/macro_with_require.hy +++ b/tests/resources/macro_with_require.hy @@ -8,18 +8,7 @@ in the expansion of `nonlocal-test-macro'." (setv macro-level-var "tests.resources.macros.macro-with-require") `(nonlocal-test-macro ~a)) -(defmacro "#test-module-tag" [a] - "The variable `macro-level-var' here should not bind to the same-named symbol -in the expansion of `nonlocal-test-macro'." - (setv macro-level-var "tests.resources.macros.macro-with-require") - `(nonlocal-test-macro ~a)) - (defmacro test-module-macro-2 [a] "The macro `local-test-macro` isn't in this module's namespace, so it better be in the expansion's!" `(local-test-macro ~a)) - -(defmacro "#test-module-tag-2" [a] - "The macro `local-test-macro` isn't in this module's namespace, so it better - be in the expansion's!" - `(local-test-macro ~a)) diff --git a/tests/resources/tlib.hy b/tests/resources/tlib.hy index 28e0e6fa0..c6b49efeb 100644 --- a/tests/resources/tlib.hy +++ b/tests/resources/tlib.hy @@ -9,9 +9,6 @@ (defmacro ✈ [arg] `(+ "plane " ~arg)) -(defmacro "#taggart" [x] - `[10 ~x]) - (defreader upper (let [node (&reader.parse-one-node)] (if (isinstance node (, hy.models.Symbol hy.models.String)) diff --git a/tests/test_lex.py b/tests/test_lex.py index 99b6a2176..138671db2 100644 --- a/tests/test_lex.py +++ b/tests/test_lex.py @@ -468,13 +468,6 @@ def test_complex(): assert entry == Symbol("J") -def test_tag_macro(): - """Ensure tag macros are handled properly""" - entry = read_many("#^()") - assert entry[0][0] == Symbol("#^") - assert len(entry[0]) == 2 - - def test_lex_comment_382(): """Ensure that we can tokenize sources with a comment at the end""" entry = read_many("foo ;bar\n;baz")