+++ /dev/null
-#!/usr/bin/env python\r
-## vim:ts=4:et:nowrap\r
-"""A user-defined wrapper around string objects\r
-\r
-Note: string objects have grown methods in Python 1.6\r
-This module requires Python 1.6 or later.\r
-"""\r
-import sys\r
-import collections\r
-\r
-__all__ = ["UserString","MutableString"]\r
-\r
-class UserString(collections.Sequence):\r
- def __init__(self, seq):\r
- if isinstance(seq, basestring):\r
- self.data = seq\r
- elif isinstance(seq, UserString):\r
- self.data = seq.data[:]\r
- else:\r
- self.data = str(seq)\r
- def __str__(self): return str(self.data)\r
- def __repr__(self): return repr(self.data)\r
- def __int__(self): return int(self.data)\r
- def __long__(self): return long(self.data)\r
- def __float__(self): return float(self.data)\r
- def __complex__(self): return complex(self.data)\r
- def __hash__(self): return hash(self.data)\r
-\r
- def __cmp__(self, string):\r
- if isinstance(string, UserString):\r
- return cmp(self.data, string.data)\r
- else:\r
- return cmp(self.data, string)\r
- def __contains__(self, char):\r
- return char in self.data\r
-\r
- def __len__(self): return len(self.data)\r
- def __getitem__(self, index): return self.__class__(self.data[index])\r
- def __getslice__(self, start, end):\r
- start = max(start, 0); end = max(end, 0)\r
- return self.__class__(self.data[start:end])\r
-\r
- def __add__(self, other):\r
- if isinstance(other, UserString):\r
- return self.__class__(self.data + other.data)\r
- elif isinstance(other, basestring):\r
- return self.__class__(self.data + other)\r
- else:\r
- return self.__class__(self.data + str(other))\r
- def __radd__(self, other):\r
- if isinstance(other, basestring):\r
- return self.__class__(other + self.data)\r
- else:\r
- return self.__class__(str(other) + self.data)\r
- def __mul__(self, n):\r
- return self.__class__(self.data*n)\r
- __rmul__ = __mul__\r
- def __mod__(self, args):\r
- return self.__class__(self.data % args)\r
-\r
- # the following methods are defined in alphabetical order:\r
- def capitalize(self): return self.__class__(self.data.capitalize())\r
- def center(self, width, *args):\r
- return self.__class__(self.data.center(width, *args))\r
- def count(self, sub, start=0, end=sys.maxint):\r
- return self.data.count(sub, start, end)\r
- def decode(self, encoding=None, errors=None): # XXX improve this?\r
- if encoding:\r
- if errors:\r
- return self.__class__(self.data.decode(encoding, errors))\r
- else:\r
- return self.__class__(self.data.decode(encoding))\r
- else:\r
- return self.__class__(self.data.decode())\r
- def encode(self, encoding=None, errors=None): # XXX improve this?\r
- if encoding:\r
- if errors:\r
- return self.__class__(self.data.encode(encoding, errors))\r
- else:\r
- return self.__class__(self.data.encode(encoding))\r
- else:\r
- return self.__class__(self.data.encode())\r
- def endswith(self, suffix, start=0, end=sys.maxint):\r
- return self.data.endswith(suffix, start, end)\r
- def expandtabs(self, tabsize=8):\r
- return self.__class__(self.data.expandtabs(tabsize))\r
- def find(self, sub, start=0, end=sys.maxint):\r
- return self.data.find(sub, start, end)\r
- def index(self, sub, start=0, end=sys.maxint):\r
- return self.data.index(sub, start, end)\r
- def isalpha(self): return self.data.isalpha()\r
- def isalnum(self): return self.data.isalnum()\r
- def isdecimal(self): return self.data.isdecimal()\r
- def isdigit(self): return self.data.isdigit()\r
- def islower(self): return self.data.islower()\r
- def isnumeric(self): return self.data.isnumeric()\r
- def isspace(self): return self.data.isspace()\r
- def istitle(self): return self.data.istitle()\r
- def isupper(self): return self.data.isupper()\r
- def join(self, seq): return self.data.join(seq)\r
- def ljust(self, width, *args):\r
- return self.__class__(self.data.ljust(width, *args))\r
- def lower(self): return self.__class__(self.data.lower())\r
- def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars))\r
- def partition(self, sep):\r
- return self.data.partition(sep)\r
- def replace(self, old, new, maxsplit=-1):\r
- return self.__class__(self.data.replace(old, new, maxsplit))\r
- def rfind(self, sub, start=0, end=sys.maxint):\r
- return self.data.rfind(sub, start, end)\r
- def rindex(self, sub, start=0, end=sys.maxint):\r
- return self.data.rindex(sub, start, end)\r
- def rjust(self, width, *args):\r
- return self.__class__(self.data.rjust(width, *args))\r
- def rpartition(self, sep):\r
- return self.data.rpartition(sep)\r
- def rstrip(self, chars=None): return self.__class__(self.data.rstrip(chars))\r
- def split(self, sep=None, maxsplit=-1):\r
- return self.data.split(sep, maxsplit)\r
- def rsplit(self, sep=None, maxsplit=-1):\r
- return self.data.rsplit(sep, maxsplit)\r
- def splitlines(self, keepends=0): return self.data.splitlines(keepends)\r
- def startswith(self, prefix, start=0, end=sys.maxint):\r
- return self.data.startswith(prefix, start, end)\r
- def strip(self, chars=None): return self.__class__(self.data.strip(chars))\r
- def swapcase(self): return self.__class__(self.data.swapcase())\r
- def title(self): return self.__class__(self.data.title())\r
- def translate(self, *args):\r
- return self.__class__(self.data.translate(*args))\r
- def upper(self): return self.__class__(self.data.upper())\r
- def zfill(self, width): return self.__class__(self.data.zfill(width))\r
-\r
-class MutableString(UserString, collections.MutableSequence):\r
- """mutable string objects\r
-\r
- Python strings are immutable objects. This has the advantage, that\r
- strings may be used as dictionary keys. If this property isn't needed\r
- and you insist on changing string values in place instead, you may cheat\r
- and use MutableString.\r
-\r
- But the purpose of this class is an educational one: to prevent\r
- people from inventing their own mutable string class derived\r
- from UserString and than forget thereby to remove (override) the\r
- __hash__ method inherited from UserString. This would lead to\r
- errors that would be very hard to track down.\r
-\r
- A faster and better solution is to rewrite your program using lists."""\r
- def __init__(self, string=""):\r
- from warnings import warnpy3k\r
- warnpy3k('the class UserString.MutableString has been removed in '\r
- 'Python 3.0', stacklevel=2)\r
- self.data = string\r
-\r
- # We inherit object.__hash__, so we must deny this explicitly\r
- __hash__ = None\r
-\r
- def __setitem__(self, index, sub):\r
- if isinstance(index, slice):\r
- if isinstance(sub, UserString):\r
- sub = sub.data\r
- elif not isinstance(sub, basestring):\r
- sub = str(sub)\r
- start, stop, step = index.indices(len(self.data))\r
- if step == -1:\r
- start, stop = stop+1, start+1\r
- sub = sub[::-1]\r
- elif step != 1:\r
- # XXX(twouters): I guess we should be reimplementing\r
- # the extended slice assignment/deletion algorithm here...\r
- raise TypeError, "invalid step in slicing assignment"\r
- start = min(start, stop)\r
- self.data = self.data[:start] + sub + self.data[stop:]\r
- else:\r
- if index < 0:\r
- index += len(self.data)\r
- if index < 0 or index >= len(self.data): raise IndexError\r
- self.data = self.data[:index] + sub + self.data[index+1:]\r
- def __delitem__(self, index):\r
- if isinstance(index, slice):\r
- start, stop, step = index.indices(len(self.data))\r
- if step == -1:\r
- start, stop = stop+1, start+1\r
- elif step != 1:\r
- # XXX(twouters): see same block in __setitem__\r
- raise TypeError, "invalid step in slicing deletion"\r
- start = min(start, stop)\r
- self.data = self.data[:start] + self.data[stop:]\r
- else:\r
- if index < 0:\r
- index += len(self.data)\r
- if index < 0 or index >= len(self.data): raise IndexError\r
- self.data = self.data[:index] + self.data[index+1:]\r
- def __setslice__(self, start, end, sub):\r
- start = max(start, 0); end = max(end, 0)\r
- if isinstance(sub, UserString):\r
- self.data = self.data[:start]+sub.data+self.data[end:]\r
- elif isinstance(sub, basestring):\r
- self.data = self.data[:start]+sub+self.data[end:]\r
- else:\r
- self.data = self.data[:start]+str(sub)+self.data[end:]\r
- def __delslice__(self, start, end):\r
- start = max(start, 0); end = max(end, 0)\r
- self.data = self.data[:start] + self.data[end:]\r
- def immutable(self):\r
- return UserString(self.data)\r
- def __iadd__(self, other):\r
- if isinstance(other, UserString):\r
- self.data += other.data\r
- elif isinstance(other, basestring):\r
- self.data += other\r
- else:\r
- self.data += str(other)\r
- return self\r
- def __imul__(self, n):\r
- self.data *= n\r
- return self\r
- def insert(self, index, value):\r
- self[index:index] = value\r
-\r
-if __name__ == "__main__":\r
- # execute the regression test to stdout, if called as a script:\r
- import os\r
- called_in_dir, called_as = os.path.split(sys.argv[0])\r
- called_as, py = os.path.splitext(called_as)\r
- if '-q' in sys.argv:\r
- from test import test_support\r
- test_support.verbose = 0\r
- __import__('test.test_' + called_as.lower())\r