-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathKeywords.py
66 lines (45 loc) · 1.6 KB
/
Keywords.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
"""Module to handle keywords and sets of keywords"""
import types, itertools
from sets import Set as _Set
class Keyword(str) :
"""Keyword is a case insensitive string with the spaces omitted,
that is Keyword(Foo Bar) == Keyword(foobar)"""
def __init__(self, s) :
t = ""
for x in str(s).split() :
# FIXME : speed up the hashing by xor'ing the parts on which self is split
# instead of performing this string concatenation
t += x
self.hash = hash(t.lower())
str.__init__(self, s)
def __hash__(self) :
return self.hash
def __eq__(self, other) :
if not isinstance(other, Keyword) :
other = Keyword(other)
return self.hash == other.hash # Use direct hash comparison to save a call to self.__hash__()
class Set(_Set) :
"""Mutable set of keywords. Besides keywords, it can operate on ordinary strings as well,
which get implicitly converted into the Keyword instances"""
def __init__(self, *args) :
# Handle special case when this __init__ is used as a copy constructor,
# i.e. with Set or ifilter instance as a sole argument
# This is needed to overcome flawed standard sets implementation in Python 2.3+
if len(args) == 1 :
x = args[0]
if isinstance(x, (Set, itertools.ifilter)) :
_Set.__init__(self, x)
return
# ALARM : dependence on the sets.Set implementation !!!
xargs = []
for x in args :
if isinstance(x, Keyword) :
xargs.append(x)
else :
xargs.append(Keyword(x))
_Set.__init__(self, xargs)
def __contains__(self, x) :
if isinstance(x, Keyword) :
return _Set.__contains__(self, x)
else :
return _Set.__contains__(self, Keyword(x))