tools.py

changeset 40
1bbea188a7e5
parent 39
8becd52c2171
child 41
9a453b2479c5
equal deleted inserted replaced
39:8becd52c2171 40:1bbea188a7e5
1 #
2 """
3 Helper functions and classes
4 """
5 import re
6
7 def str_num_cmp(s1,s2):
8 """
9 string comparator function that will put 'toto_10' after 'toto_2'
10 Also works for strings like 'toto_1_et_23er25'.
11 """
12 r = re.compile(r'((?<=\d)\D+|(?<=\D)\d+)')
13 r1= r.split(s1)
14 r2= r.split(s2)
15 r1=[not x.isdigit() and x or int(x) for x in r1 if x!='']
16 r2=[not x.isdigit() and x or int(x) for x in r2 if x!='']
17 return cmp(r1,r2)
18
19
20 class AbstractRegister(object):
21 _instance = None
22 _registered_type = None
23 def __new__(cls):
24 # implements a singleton
25 if cls._instance is None:
26 #debug('Instanciating %s', cls.__name__)
27 cls._instance = super(AbstractRegister, cls).__new__(cls)
28 cls._instance.registered = {}
29 cls._instance.accepts = set()
30 return cls._instance
31
32 def add(self, cls):
33 assert issubclass(cls, self._registered_type)
34 if cls is self._registered_type:
35 return
36 if cls._accepts is None:
37 return
38 #assert isinstance(cls._accepts, (basestring, tuple))
39
40 #debug("Registerered %s for %s", cls.__name__)
41 if not isinstance(cls._accepts, tuple):
42 cls._accepts = (cls._accepts,)
43 for key in cls._accepts:
44 key = self._get_typ(key)
45 #debug(" new key = %s", key)
46 self.registered.setdefault(key, []).append(cls)
47 self.accepts.add(key)
48
49 def _get_typ(self, typ):
50 if not isinstance(typ, basestring):
51 if not isinstance(typ, type):
52 return None
53 typ = typ.__name__
54 return typ
55
56 def __contains__(self, val):
57 val = self._get_typ(val)
58 return val in self.accepts
59
60 def get_class(self, typ):
61 item = typ
62 if not isinstance(typ, type):
63 typ = typ.__class__
64 name = typ.__name__
65 #debug("Looking a widget for %s", typ.__name__)
66 orig_typ = typ
67 while typ is not None:
68 if typ.__name__ in self.registered:
69 for w in self.registered[typ.__name__]:
70 if w._filter is None or w._filter(item):
71 #debug("Widget for %s is %s", typ.__name__, w)
72 return w#self.registered[typ.__name__]
73 if typ.__bases__:
74 typ = typ.__bases__[0]
75 if typ == object:
76 typ = None
77 elif typ.__name__ in ("ObjectItem_", "AbstractListItem_"):
78 typ = orig_typ._type
79 else:
80 typ = None
81 raise ValueError('No registered class for %s' % (name))

mercurial