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.
This commit is contained in:
Kodi Arfer 2016-09-26 09:47:04 -07:00
parent 399d2bcf21
commit 0880610401
5 changed files with 19 additions and 8 deletions

View File

@ -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)

View File

@ -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 """

View File

@ -5,4 +5,4 @@ hyset = HySet([3, 1, 2, 2])
def test_set():
assert hyset == [1, 2, 3]
assert hyset == [3, 1, 2, 2]

View File

@ -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))))

View File

@ -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))