class MutableString(UserString, collections.MutableSequence): """mutable string objects
Python strings are immutable objects. This has the advantage, that strings may be used as dictionary keys. If this property isn't needed and you insist on changing string values in place instead, you may cheat and use MutableString.
But the purpose of this class is an educational one: to prevent people from inventing their own mutable string class derived from UserString and than forget thereby to remove (override) the __hash__ method inherited from UserString. This would lead to errors that would be very hard to track down.
A faster and better solution is to rewrite your program using lists.""" def __init__(self, string=""): from warnings import warnpy3k warnpy3k('the class UserString.MutableString has been removed in ' 'Python 3.0', stacklevel=2) self.data = string
# We inherit object.__hash__, so we must deny this explicitly __hash__ = None
def __setitem__(self, index, sub): if isinstance(index, slice): if isinstance(sub, UserString): sub = sub.data elif not isinstance(sub, basestring): sub = str(sub) start, stop, step = index.indices(len(self.data)) if step == -1: start, stop = stop+1, start+1 sub = sub[::-1] elif step != 1: # XXX(twouters): I guess we should be reimplementing # the extended slice assignment/deletion algorithm here... raise TypeError, "invalid step in slicing assignment" start = min(start, stop) self.data = self.data[:start] + sub + self.data[stop:] else: if index < 0: index += len(self.data) if index < 0 or index >= len(self.data): raise IndexError self.data = self.data[:index] + sub + self.data[index+1:] def __delitem__(self, index): if isinstance(index, slice): start, stop, step = index.indices(len(self.data)) if step == -1: start, stop = stop+1, start+1 elif step != 1: # XXX(twouters): see same block in __setitem__ raise TypeError, "invalid step in slicing deletion" start = min(start, stop) self.data = self.data[:start] + self.data[stop:] else: if index < 0: index += len(self.data) if index < 0 or index >= len(self.data): raise IndexError self.data = self.data[:index] + self.data[index+1:] def __setslice__(self, start, end, sub): start = max(start, 0); end = max(end, 0) if isinstance(sub, UserString): self.data = self.data[:start]+sub.data+self.data[end:] elif isinstance(sub, basestring): self.data = self.data[:start]+sub+self.data[end:] else: self.data = self.data[:start]+str(sub)+self.data[end:] def __delslice__(self, start, end): start = max(start, 0); end = max(end, 0) self.data = self.data[:start] + self.data[end:] def immutable(self): return UserString(self.data) def __iadd__(self, other): if isinstance(other, UserString): self.data += other.data elif isinstance(other, basestring): self.data += other else: self.data += str(other) return self def __imul__(self, n): self.data *= n return self def insert(self, index, value): self[index:index] = value
if __name__ == "__main__": # execute the regression test to stdout, if called as a script: import os called_in_dir, called_as = os.path.split(sys.argv[0]) called_as, py = os.path.splitext(called_as) if '-q' in sys.argv: from test import test_support test_support.verbose = 0 __import__('test.test_' + called_as.lower())