14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#!/usr/bin/env python
24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm## vim:ts=4:et:nowrap
34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"""A user-defined wrapper around string objects
44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmNote: string objects have grown methods in Python 1.6
64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThis module requires Python 1.6 or later.
74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"""
84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport sys
94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport collections
104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__all__ = ["UserString","MutableString"]
124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass UserString(collections.Sequence):
144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __init__(self, seq):
154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if isinstance(seq, basestring):
164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.data = seq
174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        elif isinstance(seq, UserString):
184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.data = seq.data[:]
194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.data = str(seq)
214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __str__(self): return str(self.data)
224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __repr__(self): return repr(self.data)
234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __int__(self): return int(self.data)
244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __long__(self): return long(self.data)
254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __float__(self): return float(self.data)
264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __complex__(self): return complex(self.data)
274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __hash__(self): return hash(self.data)
284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __cmp__(self, string):
304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if isinstance(string, UserString):
314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return cmp(self.data, string.data)
324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return cmp(self.data, string)
344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __contains__(self, char):
354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return char in self.data
364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __len__(self): return len(self.data)
384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __getitem__(self, index): return self.__class__(self.data[index])
394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __getslice__(self, start, end):
404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        start = max(start, 0); end = max(end, 0)
414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.__class__(self.data[start:end])
424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __add__(self, other):
444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if isinstance(other, UserString):
454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return self.__class__(self.data + other.data)
464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        elif isinstance(other, basestring):
474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return self.__class__(self.data + other)
484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return self.__class__(self.data + str(other))
504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __radd__(self, other):
514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if isinstance(other, basestring):
524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return self.__class__(other + self.data)
534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return self.__class__(str(other) + self.data)
554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __mul__(self, n):
564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.__class__(self.data*n)
574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    __rmul__ = __mul__
584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __mod__(self, args):
594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.__class__(self.data % args)
604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    # the following methods are defined in alphabetical order:
624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def capitalize(self): return self.__class__(self.data.capitalize())
634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def center(self, width, *args):
644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.__class__(self.data.center(width, *args))
654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def count(self, sub, start=0, end=sys.maxint):
664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.data.count(sub, start, end)
674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def decode(self, encoding=None, errors=None): # XXX improve this?
684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if encoding:
694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if errors:
704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return self.__class__(self.data.decode(encoding, errors))
714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else:
724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return self.__class__(self.data.decode(encoding))
734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return self.__class__(self.data.decode())
754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def encode(self, encoding=None, errors=None): # XXX improve this?
764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if encoding:
774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if errors:
784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return self.__class__(self.data.encode(encoding, errors))
794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else:
804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return self.__class__(self.data.encode(encoding))
814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return self.__class__(self.data.encode())
834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def endswith(self, suffix, start=0, end=sys.maxint):
844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.data.endswith(suffix, start, end)
854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def expandtabs(self, tabsize=8):
864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.__class__(self.data.expandtabs(tabsize))
874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def find(self, sub, start=0, end=sys.maxint):
884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.data.find(sub, start, end)
894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def index(self, sub, start=0, end=sys.maxint):
904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.data.index(sub, start, end)
914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def isalpha(self): return self.data.isalpha()
924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def isalnum(self): return self.data.isalnum()
934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def isdecimal(self): return self.data.isdecimal()
944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def isdigit(self): return self.data.isdigit()
954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def islower(self): return self.data.islower()
964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def isnumeric(self): return self.data.isnumeric()
974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def isspace(self): return self.data.isspace()
984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def istitle(self): return self.data.istitle()
994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def isupper(self): return self.data.isupper()
1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def join(self, seq): return self.data.join(seq)
1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def ljust(self, width, *args):
1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.__class__(self.data.ljust(width, *args))
1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def lower(self): return self.__class__(self.data.lower())
1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars))
1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def partition(self, sep):
1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.data.partition(sep)
1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def replace(self, old, new, maxsplit=-1):
1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.__class__(self.data.replace(old, new, maxsplit))
1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def rfind(self, sub, start=0, end=sys.maxint):
1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.data.rfind(sub, start, end)
1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def rindex(self, sub, start=0, end=sys.maxint):
1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.data.rindex(sub, start, end)
1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def rjust(self, width, *args):
1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.__class__(self.data.rjust(width, *args))
1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def rpartition(self, sep):
1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.data.rpartition(sep)
1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def rstrip(self, chars=None): return self.__class__(self.data.rstrip(chars))
1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def split(self, sep=None, maxsplit=-1):
1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.data.split(sep, maxsplit)
1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def rsplit(self, sep=None, maxsplit=-1):
1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.data.rsplit(sep, maxsplit)
1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def splitlines(self, keepends=0): return self.data.splitlines(keepends)
1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def startswith(self, prefix, start=0, end=sys.maxint):
1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.data.startswith(prefix, start, end)
1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def strip(self, chars=None): return self.__class__(self.data.strip(chars))
1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def swapcase(self): return self.__class__(self.data.swapcase())
1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def title(self): return self.__class__(self.data.title())
1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def translate(self, *args):
1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.__class__(self.data.translate(*args))
1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def upper(self): return self.__class__(self.data.upper())
1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def zfill(self, width): return self.__class__(self.data.zfill(width))
1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass MutableString(UserString, collections.MutableSequence):
1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    """mutable string objects
1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Python strings are immutable objects.  This has the advantage, that
1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    strings may be used as dictionary keys.  If this property isn't needed
1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    and you insist on changing string values in place instead, you may cheat
1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    and use MutableString.
1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    But the purpose of this class is an educational one: to prevent
1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    people from inventing their own mutable string class derived
1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    from UserString and than forget thereby to remove (override) the
1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    __hash__ method inherited from UserString.  This would lead to
1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    errors that would be very hard to track down.
1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    A faster and better solution is to rewrite your program using lists."""
1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __init__(self, string=""):
1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        from warnings import warnpy3k
1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        warnpy3k('the class UserString.MutableString has been removed in '
1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    'Python 3.0', stacklevel=2)
1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.data = string
1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    # We inherit object.__hash__, so we must deny this explicitly
1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    __hash__ = None
1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __setitem__(self, index, sub):
1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if isinstance(index, slice):
1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if isinstance(sub, UserString):
1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sub = sub.data
1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            elif not isinstance(sub, basestring):
1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sub = str(sub)
1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            start, stop, step = index.indices(len(self.data))
1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if step == -1:
1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                start, stop = stop+1, start+1
1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sub = sub[::-1]
1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            elif step != 1:
1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # XXX(twouters): I guess we should be reimplementing
1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # the extended slice assignment/deletion algorithm here...
1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                raise TypeError, "invalid step in slicing assignment"
1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            start = min(start, stop)
1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.data = self.data[:start] + sub + self.data[stop:]
1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if index < 0:
1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                index += len(self.data)
1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if index < 0 or index >= len(self.data): raise IndexError
1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.data = self.data[:index] + sub + self.data[index+1:]
1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __delitem__(self, index):
1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if isinstance(index, slice):
1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            start, stop, step = index.indices(len(self.data))
1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if step == -1:
1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                start, stop = stop+1, start+1
1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            elif step != 1:
1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                # XXX(twouters): see same block in __setitem__
1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                raise TypeError, "invalid step in slicing deletion"
1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            start = min(start, stop)
1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.data = self.data[:start] + self.data[stop:]
1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if index < 0:
1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                index += len(self.data)
1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if index < 0 or index >= len(self.data): raise IndexError
1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.data = self.data[:index] + self.data[index+1:]
1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __setslice__(self, start, end, sub):
1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        start = max(start, 0); end = max(end, 0)
1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if isinstance(sub, UserString):
1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.data = self.data[:start]+sub.data+self.data[end:]
1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        elif isinstance(sub, basestring):
1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.data = self.data[:start]+sub+self.data[end:]
1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.data =  self.data[:start]+str(sub)+self.data[end:]
2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __delslice__(self, start, end):
2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        start = max(start, 0); end = max(end, 0)
2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.data = self.data[:start] + self.data[end:]
2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def immutable(self):
2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return UserString(self.data)
2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __iadd__(self, other):
2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if isinstance(other, UserString):
2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.data += other.data
2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        elif isinstance(other, basestring):
2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.data += other
2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.data += str(other)
2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self
2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def __imul__(self, n):
2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.data *= n
2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self
2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def insert(self, index, value):
2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self[index:index] = value
2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif __name__ == "__main__":
2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    # execute the regression test to stdout, if called as a script:
2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    import os
2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    called_in_dir, called_as = os.path.split(sys.argv[0])
2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    called_as, py = os.path.splitext(called_as)
2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if '-q' in sys.argv:
2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        from test import test_support
2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        test_support.verbose = 0
2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    __import__('test.test_' + called_as.lower())
229