[Python-checkins] python/dist/src/Lib sets.py,1.16,1.17
rhettinger@users.sourceforge.net
rhettinger@users.sourceforge.net
2002年8月23日 19:35:50 -0700
Update of /cvsroot/python/python/dist/src/Lib
In directory usw-pr-cvs1:/tmp/cvs-serv21371
Modified Files:
sets.py
Log Message:
1. Removed module self test in favor of unittests -- Timbot's suggestion.
2. Replaced calls to Set([]) with Set() -- Timbot's suggestion
3. Fixed subtle bug in sets of sets:
The following code did not work (will add to test suite):
d = Set('d')
s = Set([d]) # Stores inner set as an ImmutableSet
s.remove(d) # For comparison, wraps d in _TemporarilyImmutableSet
The comparison proceeds by computing the hash of the
_TemporarilyImmutableSet and finding it in the dictionary.
It then verifies equality by calling ImmutableSet.__eq__()
and crashes from the binary sanity check.
The problem is that the code assumed equality would be checked
with _TemporarilyImmutableSet.__eq__().
The solution is to let _TemporarilyImmutableSet derive from BaseSet
so it will pass the sanity check and then to provide it with the
._data element from the wrapped set so that ImmutableSet.__eq__()
will find ._data where it expects.
Since ._data is now provided and because BaseSet is the base class,
_TemporarilyImmutableSet no longer needs .__eq__() or .__ne__().
Note that inheriting all of BaseSet's methods is harmless because
none of those methods (except ones starting with an underscore)
can mutate the .data element. Also _TemporarilyImmutableSet is only
used internally as is not otherwise visible.
Index: sets.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/sets.py,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -d -r1.16 -r1.17
*** sets.py 23 Aug 2002 20:36:58 -0000 1.16
--- sets.py 24 Aug 2002 02:35:48 -0000 1.17
***************
*** 134,138 ****
def copy(self):
"""Return a shallow copy of a set."""
! result = self.__class__([])
result._data.update(self._data)
return result
--- 134,138 ----
def copy(self):
"""Return a shallow copy of a set."""
! result = self.__class__()
result._data.update(self._data)
return result
***************
*** 148,152 ****
# itself.
from copy import deepcopy
! result = self.__class__([])
memo[id(self)] = result
data = result._data
--- 148,152 ----
# itself.
from copy import deepcopy
! result = self.__class__()
memo[id(self)] = result
data = result._data
***************
*** 189,193 ****
else:
little, big = other, self
! result = self.__class__([])
data = result._data
value = True
--- 189,193 ----
else:
little, big = other, self
! result = self.__class__()
data = result._data
value = True
***************
*** 211,215 ****
if not isinstance(other, BaseSet):
return NotImplemented
! result = self.__class__([])
data = result._data
value = True
--- 211,215 ----
if not isinstance(other, BaseSet):
return NotImplemented
! result = self.__class__()
data = result._data
value = True
***************
*** 236,240 ****
if not isinstance(other, BaseSet):
return NotImplemented
! result = self.__class__([])
data = result._data
value = True
--- 236,240 ----
if not isinstance(other, BaseSet):
return NotImplemented
! result = self.__class__()
data = result._data
value = True
***************
*** 468,472 ****
! class _TemporarilyImmutableSet(object):
# Wrap a mutable set as if it was temporarily immutable.
# This only supplies hashing and equality comparisons.
--- 468,472 ----
! class _TemporarilyImmutableSet(BaseSet):
# Wrap a mutable set as if it was temporarily immutable.
# This only supplies hashing and equality comparisons.
***************
*** 476,479 ****
--- 476,480 ----
def __init__(self, set):
self._set = set
+ self._data = set._data # Needed by ImmutableSet.__eq__()
def __hash__(self):
***************
*** 481,585 ****
self._hashcode = self._set._compute_hash()
return self._hashcode
-
- def __eq__(self, other):
- return self._set == other
-
- def __ne__(self, other):
- return self._set != other
-
-
- # Rudimentary self-tests
-
- def _test():
-
- # Empty set
- red = Set()
- assert `red` == "Set([])", "Empty set: %s" % `red`
-
- # Unit set
- green = Set((0,))
- assert `green` == "Set([0])", "Unit set: %s" % `green`
-
- # 3-element set
- blue = Set([0, 1, 2])
- assert blue._repr(True) == "Set([0, 1, 2])", "3-element set: %s" % `blue`
-
- # 2-element set with other values
- black = Set([0, 5])
- assert black._repr(True) == "Set([0, 5])", "2-element set: %s" % `black`
-
- # All elements from all sets
- white = Set([0, 1, 2, 5])
- assert white._repr(True) == "Set([0, 1, 2, 5])", "4-element set: %s" % `white`
-
- # Add element to empty set
- red.add(9)
- assert `red` == "Set([9])", "Add to empty set: %s" % `red`
-
- # Remove element from unit set
- red.remove(9)
- assert `red` == "Set([])", "Remove from unit set: %s" % `red`
-
- # Remove element from empty set
- try:
- red.remove(0)
- assert 0, "Remove element from empty set: %s" % `red`
- except LookupError:
- pass
-
- # Length
- assert len(red) == 0, "Length of empty set"
- assert len(green) == 1, "Length of unit set"
- assert len(blue) == 3, "Length of 3-element set"
-
- # Compare
- assert green == Set([0]), "Equality failed"
- assert green != Set([1]), "Inequality failed"
-
- # Union
- assert blue | red == blue, "Union non-empty with empty"
- assert red | blue == blue, "Union empty with non-empty"
- assert green | blue == blue, "Union non-empty with non-empty"
- assert blue | black == white, "Enclosing union"
-
- # Intersection
- assert blue & red == red, "Intersect non-empty with empty"
- assert red & blue == red, "Intersect empty with non-empty"
- assert green & blue == green, "Intersect non-empty with non-empty"
- assert blue & black == green, "Enclosing intersection"
-
- # Symmetric difference
- assert red ^ green == green, "Empty symdiff non-empty"
- assert green ^ blue == Set([1, 2]), "Non-empty symdiff"
- assert white ^ white == red, "Self symdiff"
-
- # Difference
- assert red - green == red, "Empty - non-empty"
- assert blue - red == blue, "Non-empty - empty"
- assert white - black == Set([1, 2]), "Non-empty - non-empty"
-
- # In-place union
- orange = Set([])
- orange |= Set([1])
- assert orange == Set([1]), "In-place union"
-
- # In-place intersection
- orange = Set([1, 2])
- orange &= Set([2])
- assert orange == Set([2]), "In-place intersection"
-
- # In-place difference
- orange = Set([1, 2, 3])
- orange -= Set([2, 4])
- assert orange == Set([1, 3]), "In-place difference"
-
- # In-place symmetric difference
- orange = Set([1, 2, 3])
- orange ^= Set([3, 4])
- assert orange == Set([1, 2, 4]), "In-place symmetric difference"
-
- print "All tests passed"
-
-
- if __name__ == "__main__":
- _test()
--- 482,483 ----