10c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#!/usr/bin/env python
20c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## vim:ts=4:et:nowrap
30c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi"""A user-defined wrapper around string objects
40c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
50c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiNote: string objects have grown methods in Python 1.6
60c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiThis module requires Python 1.6 or later.
70c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi"""
80c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport sys
90c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport collections
100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi__all__ = ["UserString","MutableString"]
120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass UserString(collections.Sequence):
140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self, seq):
150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(seq, basestring):
160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.data = seq
170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif isinstance(seq, UserString):
180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.data = seq.data[:]
190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.data = str(seq)
210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __str__(self): return str(self.data)
220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __repr__(self): return repr(self.data)
230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __int__(self): return int(self.data)
240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __long__(self): return long(self.data)
250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __float__(self): return float(self.data)
260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __complex__(self): return complex(self.data)
270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __hash__(self): return hash(self.data)
280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __cmp__(self, string):
300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(string, UserString):
310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return cmp(self.data, string.data)
320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return cmp(self.data, string)
340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __contains__(self, char):
350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return char in self.data
360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __len__(self): return len(self.data)
380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __getitem__(self, index): return self.__class__(self.data[index])
390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __getslice__(self, start, end):
400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        start = max(start, 0); end = max(end, 0)
410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.__class__(self.data[start:end])
420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __add__(self, other):
440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(other, UserString):
450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self.__class__(self.data + other.data)
460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif isinstance(other, basestring):
470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self.__class__(self.data + other)
480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self.__class__(self.data + str(other))
500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __radd__(self, other):
510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(other, basestring):
520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self.__class__(other + self.data)
530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self.__class__(str(other) + self.data)
550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __mul__(self, n):
560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.__class__(self.data*n)
570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    __rmul__ = __mul__
580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __mod__(self, args):
590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.__class__(self.data % args)
600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # the following methods are defined in alphabetical order:
620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def capitalize(self): return self.__class__(self.data.capitalize())
630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def center(self, width, *args):
640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.__class__(self.data.center(width, *args))
650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def count(self, sub, start=0, end=sys.maxint):
660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.data.count(sub, start, end)
670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def decode(self, encoding=None, errors=None): # XXX improve this?
680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if encoding:
690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if errors:
700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                return self.__class__(self.data.decode(encoding, errors))
710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                return self.__class__(self.data.decode(encoding))
730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self.__class__(self.data.decode())
750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def encode(self, encoding=None, errors=None): # XXX improve this?
760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if encoding:
770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if errors:
780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                return self.__class__(self.data.encode(encoding, errors))
790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                return self.__class__(self.data.encode(encoding))
810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self.__class__(self.data.encode())
830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def endswith(self, suffix, start=0, end=sys.maxint):
840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.data.endswith(suffix, start, end)
850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def expandtabs(self, tabsize=8):
860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.__class__(self.data.expandtabs(tabsize))
870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def find(self, sub, start=0, end=sys.maxint):
880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.data.find(sub, start, end)
890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def index(self, sub, start=0, end=sys.maxint):
900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.data.index(sub, start, end)
910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def isalpha(self): return self.data.isalpha()
920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def isalnum(self): return self.data.isalnum()
930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def isdecimal(self): return self.data.isdecimal()
940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def isdigit(self): return self.data.isdigit()
950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def islower(self): return self.data.islower()
960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def isnumeric(self): return self.data.isnumeric()
970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def isspace(self): return self.data.isspace()
980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def istitle(self): return self.data.istitle()
990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def isupper(self): return self.data.isupper()
1000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def join(self, seq): return self.data.join(seq)
1010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def ljust(self, width, *args):
1020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.__class__(self.data.ljust(width, *args))
1030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def lower(self): return self.__class__(self.data.lower())
1040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars))
1050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def partition(self, sep):
1060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.data.partition(sep)
1070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def replace(self, old, new, maxsplit=-1):
1080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.__class__(self.data.replace(old, new, maxsplit))
1090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def rfind(self, sub, start=0, end=sys.maxint):
1100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.data.rfind(sub, start, end)
1110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def rindex(self, sub, start=0, end=sys.maxint):
1120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.data.rindex(sub, start, end)
1130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def rjust(self, width, *args):
1140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.__class__(self.data.rjust(width, *args))
1150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def rpartition(self, sep):
1160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.data.rpartition(sep)
1170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def rstrip(self, chars=None): return self.__class__(self.data.rstrip(chars))
1180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def split(self, sep=None, maxsplit=-1):
1190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.data.split(sep, maxsplit)
1200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def rsplit(self, sep=None, maxsplit=-1):
1210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.data.rsplit(sep, maxsplit)
1220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def splitlines(self, keepends=0): return self.data.splitlines(keepends)
1230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def startswith(self, prefix, start=0, end=sys.maxint):
1240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.data.startswith(prefix, start, end)
1250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def strip(self, chars=None): return self.__class__(self.data.strip(chars))
1260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def swapcase(self): return self.__class__(self.data.swapcase())
1270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def title(self): return self.__class__(self.data.title())
1280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def translate(self, *args):
1290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.__class__(self.data.translate(*args))
1300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def upper(self): return self.__class__(self.data.upper())
1310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def zfill(self, width): return self.__class__(self.data.zfill(width))
1320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass MutableString(UserString, collections.MutableSequence):
1340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """mutable string objects
1350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Python strings are immutable objects.  This has the advantage, that
1370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    strings may be used as dictionary keys.  If this property isn't needed
1380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    and you insist on changing string values in place instead, you may cheat
1390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    and use MutableString.
1400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    But the purpose of this class is an educational one: to prevent
1420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    people from inventing their own mutable string class derived
1430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    from UserString and than forget thereby to remove (override) the
1440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    __hash__ method inherited from UserString.  This would lead to
1450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    errors that would be very hard to track down.
1460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    A faster and better solution is to rewrite your program using lists."""
1480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self, string=""):
1490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from warnings import warnpy3k
1500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        warnpy3k('the class UserString.MutableString has been removed in '
1510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    'Python 3.0', stacklevel=2)
1520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.data = string
1530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # We inherit object.__hash__, so we must deny this explicitly
1550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    __hash__ = None
1560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __setitem__(self, index, sub):
1580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(index, slice):
1590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if isinstance(sub, UserString):
1600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                sub = sub.data
1610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            elif not isinstance(sub, basestring):
1620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                sub = str(sub)
1630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            start, stop, step = index.indices(len(self.data))
1640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if step == -1:
1650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                start, stop = stop+1, start+1
1660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                sub = sub[::-1]
1670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            elif step != 1:
1680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                # XXX(twouters): I guess we should be reimplementing
1690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                # the extended slice assignment/deletion algorithm here...
1700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                raise TypeError, "invalid step in slicing assignment"
1710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            start = min(start, stop)
1720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.data = self.data[:start] + sub + self.data[stop:]
1730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
1740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if index < 0:
1750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                index += len(self.data)
1760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if index < 0 or index >= len(self.data): raise IndexError
1770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.data = self.data[:index] + sub + self.data[index+1:]
1780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __delitem__(self, index):
1790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(index, slice):
1800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            start, stop, step = index.indices(len(self.data))
1810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if step == -1:
1820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                start, stop = stop+1, start+1
1830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            elif step != 1:
1840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                # XXX(twouters): see same block in __setitem__
1850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                raise TypeError, "invalid step in slicing deletion"
1860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            start = min(start, stop)
1870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.data = self.data[:start] + self.data[stop:]
1880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
1890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if index < 0:
1900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                index += len(self.data)
1910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if index < 0 or index >= len(self.data): raise IndexError
1920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.data = self.data[:index] + self.data[index+1:]
1930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __setslice__(self, start, end, sub):
1940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        start = max(start, 0); end = max(end, 0)
1950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(sub, UserString):
1960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.data = self.data[:start]+sub.data+self.data[end:]
1970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif isinstance(sub, basestring):
1980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.data = self.data[:start]+sub+self.data[end:]
1990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
2000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.data =  self.data[:start]+str(sub)+self.data[end:]
2010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __delslice__(self, start, end):
2020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        start = max(start, 0); end = max(end, 0)
2030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.data = self.data[:start] + self.data[end:]
2040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def immutable(self):
2050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return UserString(self.data)
2060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __iadd__(self, other):
2070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(other, UserString):
2080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.data += other.data
2090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif isinstance(other, basestring):
2100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.data += other
2110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
2120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.data += str(other)
2130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self
2140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __imul__(self, n):
2150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.data *= n
2160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self
2170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def insert(self, index, value):
2180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self[index:index] = value
2190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiif __name__ == "__main__":
2210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # execute the regression test to stdout, if called as a script:
2220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    import os
2230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    called_in_dir, called_as = os.path.split(sys.argv[0])
2240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    called_as, py = os.path.splitext(called_as)
2250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if '-q' in sys.argv:
2260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        from test import test_support
2270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        test_support.verbose = 0
2280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    __import__('test.test_' + called_as.lower())
229