# halgari/clojure-py

Fix equality between {} and [], fix #169.

`(closes #142 at the same time.)`
1 parent ba49968 commit 60689b4ff54c9f1260aae68c31ddc3b6b4c0bb98 anntzer committed Dec 14, 2012
Showing with 20 additions and 29 deletions.
1. +10 −21 clojure/lang/apersistentmap.py
2. +5 −7 clojure/lang/apersistentvector.py
3. +5 −1 tests/persistenthashmap-tests.clj
31 clojure/lang/apersistentmap.py
 @@ -4,6 +4,7 @@ from clojure.lang.mapentry import MapEntry from clojure.lang.iprintable import IPrintable from clojure.lang.ipersistentmap import IPersistentMap +from clojure.lang.ipersistentset import IPersistentSet from clojure.lang.ipersistentvector import IPersistentVector from clojure.lang.cljexceptions import (ArityException, InvalidArgumentException) @@ -35,7 +36,15 @@ def toDict(self): return d def __eq__(self, other): - return mapEquals(self, other) + if self is other: + return True + if isinstance(other, (IPersistentSet, IPersistentVector)): + return False + try: + return (len(self) == len(other) and + all(s in other and other[s] == self[s] for s in self)) + except TypeError: + return False def __ne__(self, other): return not self == other @@ -87,25 +96,6 @@ def writeAsReplString(self, writer): writer.write("}") -def mapEquals(m1, m2): - if m1 is m2: - return True - if not hasattr(m2, "__getitem__"): - return False - if not hasattr(m2, "__len__"): - return False - if not hasattr(m2, "__iter__"): - return False - - if len(m1) != len(m2): - return False - - for s in m1: - if s not in m2 or m2[s] != m1[s]: - return False - return True - - def mapHash(m): return reduce(lambda h, v: h + (0 if v.getKey() is None else hash(v.getKey())) @@ -115,7 +105,6 @@ def mapHash(m): 0) - class KeySeq(ASeq): def __init__(self, *args): if len(args) == 1:
12 clojure/lang/apersistentvector.py
 @@ -4,6 +4,7 @@ from clojure.lang.iobj import IObj from clojure.lang.iprintable import IPrintable from clojure.lang.indexableseq import IndexableSeq +from clojure.lang.ipersistentmap import IPersistentMap from clojure.lang.ipersistentset import IPersistentSet from clojure.lang.ipersistentvector import IPersistentVector from clojure.lang.cljexceptions import ArityException @@ -46,13 +47,10 @@ def __eq__(self, other): other -- ISeq or something that implements the seq protocol ASeq.__eq__ is actually used.""" - if self is other: - return True - if not RT.isSeqable(other) or isinstance(other, IPersistentSet): - return False - s = self.seq() - o = RT.seq(other) - return s == o + return (self is other or + (RT.isSeqable(other) and + not isinstance(other, (IPersistentSet, IPersistentMap)) and + self.seq() == RT.seq(other))) def __hash__(self): """Return the hash on this vector or 1 if the vector is empty.
6 tests/persistenthashmap-tests.clj
 @@ -7,6 +7,10 @@ (.assoc "a" 1) (.assoc "b" 2))) +(deftest equality-tests + (assertions/assert-false (= {} [])) + (assertions/assert-false (= {} #{}))) + (deftest assoc-tests (assertions/assert-true (.containsKey testmap "a"))) @@ -17,4 +21,4 @@ (deftest entryAt-tests (assertions/assert-false (-> testmap (.without "a") - (.entryAt "a")))) + (.entryAt "a"))))