1
# -*- test-case-name: epsilon.test.test_caseless -*-
3
Helpers for case-insensitive string handling.
6
class Caseless(object):
8
Case-insensitive string wrapper type.
10
This wrapper is intended for use with strings that have case-insensitive
11
semantics, such as HTTP/MIME header values. It implements comparison-based
12
operations case-insensitively, avoiding the need to manually call C{lower}
13
where appropriate, or keep track of which strings are case-insensitive
14
throughout various function calls.
18
>>> Caseless('Spam') == Caseless('spam')
20
>>> 'spam' in Caseless('Eggs and Spam')
23
>>> sorted(['FOO', 'bar'], key=Caseless)
26
>>> d = {Caseless('Content-type'): Caseless('Text/Plain')}
27
>>> d[Caseless('Content-Type')].startswith('text/')
30
Note: String methods that return modified strings (such as
31
C{decode}/C{encode}, C{join}, C{partition}, C{replace}, C{strip}/C{split})
32
don't have an unambiguous return types with regards to case sensitivity, so
33
they are not implemented by L{Caseless}. They should be accessed on the
34
underlying cased string instead. (Excepted are methods like
35
C{lower}/C{upper}, whose return case is unambiguous.)
37
@ivar cased: the wrapped string-like object
40
def __init__(self, cased):
41
if isinstance(cased, Caseless):
47
return '%s(%r)' % (type(self).__name__, self.cased)
50
# Methods delegated to cased
53
return str(self.cased)
56
def __unicode__(self):
57
return unicode(self.cased)
61
return len(self.cased)
64
def __getitem__(self, key):
65
return self.cased[key]
69
return iter(self.cased)
73
return self.cased.lower()
77
return self.cased.upper()
81
return self.cased.title()
85
return self.cased.swapcase()
88
# Methods delegated to lower()
90
def __cmp__(self, other):
91
return cmp(self.lower(), other.lower())
95
return hash(self.lower())
98
def __contains__(self, substring):
99
return substring.lower() in self.lower()
102
def startswith(self, prefix, *rest):
103
if isinstance(prefix, tuple):
104
lprefix = tuple(s.lower() for s in prefix)
106
lprefix = prefix.lower()
107
return self.lower().startswith(lprefix, *rest)
110
def endswith(self, suffix, *rest):
111
if isinstance(suffix, tuple):
112
lsuffix = tuple(s.lower() for s in suffix)
114
lsuffix = suffix.lower()
115
return self.lower().endswith(lsuffix, *rest)
118
def count(self, substring, *rest):
119
return self.lower().count(substring.lower(), *rest)
122
def find(self, substring, *rest):
123
return self.lower().find(substring.lower(), *rest)
126
def index(self, substring, *rest):
127
return self.lower().index(substring.lower(), *rest)
130
def rfind(self, substring, *rest):
131
return self.lower().rfind(substring.lower(), *rest)
134
def rindex(self, substring, *rest):
135
return self.lower().rindex(substring.lower(), *rest)