Viewing file: caseless.py (3.33 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# -*- test-case-name: epsilon.test.test_caseless -*- """ Helpers for case-insensitive string handling. """
class Caseless(object): """ Case-insensitive string wrapper type. This wrapper is intended for use with strings that have case-insensitive semantics, such as HTTP/MIME header values. It implements comparison-based operations case-insensitively, avoiding the need to manually call C{lower} where appropriate, or keep track of which strings are case-insensitive throughout various function calls.
Example usage:
>>> Caseless('Spam') == Caseless('spam') True >>> 'spam' in Caseless('Eggs and Spam') True
>>> sorted(['FOO', 'bar'], key=Caseless) ['bar', 'FOO']
>>> d = {Caseless('Content-type'): Caseless('Text/Plain')} >>> d[Caseless('Content-Type')].startswith('text/') True
Note: String methods that return modified strings (such as C{decode}/C{encode}, C{join}, C{partition}, C{replace}, C{strip}/C{split}) don't have an unambiguous return types with regards to case sensitivity, so they are not implemented by L{Caseless}. They should be accessed on the underlying cased string instead. (Excepted are methods like C{lower}/C{upper}, whose return case is unambiguous.)
@ivar cased: the wrapped string-like object """
def __init__(self, cased): if isinstance(cased, Caseless): cased = cased.cased self.cased = cased
def __repr__(self): return '%s(%r)' % (type(self).__name__, self.cased)
# Methods delegated to cased
def __str__(self): return str(self.cased)
def __unicode__(self): return unicode(self.cased)
def __len__(self): return len(self.cased)
def __getitem__(self, key): return self.cased[key]
def __iter__(self): return iter(self.cased)
def lower(self): return self.cased.lower()
def upper(self): return self.cased.upper()
def title(self): return self.cased.title()
def swapcase(self): return self.cased.swapcase()
# Methods delegated to lower()
def __cmp__(self, other): return cmp(self.lower(), other.lower())
def __hash__(self): return hash(self.lower())
def __contains__(self, substring): return substring.lower() in self.lower()
def startswith(self, prefix, *rest): if isinstance(prefix, tuple): lprefix = tuple(s.lower() for s in prefix) else: lprefix = prefix.lower() return self.lower().startswith(lprefix, *rest)
def endswith(self, suffix, *rest): if isinstance(suffix, tuple): lsuffix = tuple(s.lower() for s in suffix) else: lsuffix = suffix.lower() return self.lower().endswith(lsuffix, *rest)
def count(self, substring, *rest): return self.lower().count(substring.lower(), *rest)
def find(self, substring, *rest): return self.lower().find(substring.lower(), *rest)
def index(self, substring, *rest): return self.lower().index(substring.lower(), *rest)
def rfind(self, substring, *rest): return self.lower().rfind(substring.lower(), *rest)
def rindex(self, substring, *rest): return self.lower().rindex(substring.lower(), *rest)
|