From 0880610401ae1249cd434514ddc607a1f25705d8 Mon Sep 17 00:00:00 2001 From: Kodi Arfer Date: Mon, 26 Sep 2016 09:47:04 -0700 Subject: [PATCH] Don't sort or deduplicate the items in a HySet Fixes #1120. I also added hy.models._wrapper[set] so a macro can return an ordinary set in place of a HySet. --- hy/models/set.py | 11 ++++------- tests/lex/test_lex.py | 10 ++++++++++ tests/models/test_set.py | 2 +- tests/native_tests/language.hy | 1 + tests/native_tests/native_macros.hy | 3 +++ 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/hy/models/set.py b/hy/models/set.py index 3a81aed..fda7b52 100644 --- a/hy/models/set.py +++ b/hy/models/set.py @@ -18,19 +18,16 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. +from hy.models import _wrappers, wrap_value from hy.models.list import HyList -from functools import reduce class HySet(HyList): """ - Hy set (actually a list that pretends to be a set) + Hy set (just a representation of a set) """ - def __init__(self, items): - items = sorted(items) - items = list(reduce(lambda r, v: v in r and r or r+[v], items, [])) - super(HySet, self).__init__(items) - def __repr__(self): return "#{%s}" % (" ".join([repr(x) for x in self])) + +_wrappers[set] = lambda s: HySet(wrap_value(x) for x in s) diff --git a/tests/lex/test_lex.py b/tests/lex/test_lex.py index 4413a6b..81407cc 100644 --- a/tests/lex/test_lex.py +++ b/tests/lex/test_lex.py @@ -230,6 +230,16 @@ def test_sets(): HyExpression([HySymbol("baz"), HySymbol("quux")]) ])] + # Duplicate items in a literal set should be okay (and should + # be preserved). + objs = tokenize("#{1 2 1 1 2 1}") + assert objs == [HySet([HyInteger(n) for n in [1, 2, 1, 1, 2, 1]])] + assert len(objs[0]) == 6 + + # https://github.com/hylang/hy/issues/1120 + objs = tokenize("#{a 1}") + assert objs == [HySet([HySymbol("a"), HyInteger(1)])] + def test_nospace(): """ Ensure we can tokenize without spaces if we have to """ diff --git a/tests/models/test_set.py b/tests/models/test_set.py index ceea726..0462c2c 100644 --- a/tests/models/test_set.py +++ b/tests/models/test_set.py @@ -5,4 +5,4 @@ hyset = HySet([3, 1, 2, 2]) def test_set(): - assert hyset == [1, 2, 3] + assert hyset == [3, 1, 2, 2] diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy index 0300ffb..54b3e61 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -47,6 +47,7 @@ (defn test-sets [] "NATIVE: test sets work right" (assert (= #{1 2 3 4} (| #{1 2} #{3 4}))) + (assert (= (type #{1 2 3 4}) set)) (assert (= #{} (set)))) diff --git a/tests/native_tests/native_macros.hy b/tests/native_tests/native_macros.hy index eca4538..788e52b 100644 --- a/tests/native_tests/native_macros.hy +++ b/tests/native_tests/native_macros.hy @@ -39,6 +39,9 @@ (defmacro a-dict [] {1 2}) (assert (= (a-dict) {1 2})) +(defmacro a-set [] #{1 2}) +(assert (= (a-set) #{1 2})) + (defmacro a-none []) (assert (= (a-none) None))