Skip to content

Commit

Permalink
Fix: references to old style defmacro tag macros
Browse files Browse the repository at this point in the history
  • Loading branch information
allison-casey committed Mar 14, 2022
1 parent 340df76 commit ef8e268
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 123 deletions.
9 changes: 1 addition & 8 deletions tests/compilers/test_ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -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])")
Expand Down Expand Up @@ -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")
Expand Down
8 changes: 0 additions & 8 deletions tests/native_tests/core.hy
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
5 changes: 0 additions & 5 deletions tests/native_tests/language.hy
Original file line number Diff line number Diff line change
Expand Up @@ -1298,15 +1298,13 @@ 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))

(require tests.resources.tlib :as T)
(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))

Expand All @@ -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"))
Expand Down
9 changes: 0 additions & 9 deletions tests/native_tests/mangling.hy
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 3 additions & 14 deletions tests/native_tests/native_macros.hy
Original file line number Diff line number Diff line change
Expand Up @@ -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 []
Expand Down Expand Up @@ -192,20 +192,14 @@ 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.
(defmacro local-test-macro [x]
(.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
Expand Down Expand Up @@ -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)

Expand Down
12 changes: 6 additions & 6 deletions tests/native_tests/reader_macros.hy
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
136 changes: 84 additions & 52 deletions tests/native_tests/tag_macros.hy
Original file line number Diff line number Diff line change
@@ -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 "<test>")]
(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]
Expand Down Expand Up @@ -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)))
11 changes: 0 additions & 11 deletions tests/resources/macro_with_require.hy
Original file line number Diff line number Diff line change
Expand Up @@ -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))
3 changes: 0 additions & 3 deletions tests/resources/tlib.hy
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
7 changes: 0 additions & 7 deletions tests/test_lex.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down

0 comments on commit ef8e268

Please sign in to comment.