31 """represent a known config item |
32 """represent a known config item |
32 |
33 |
33 :section: the official config section where to find this item, |
34 :section: the official config section where to find this item, |
34 :name: the official name within the section, |
35 :name: the official name within the section, |
35 :default: default value for this item, |
36 :default: default value for this item, |
36 :alias: optional list of tuples as alternatives. |
37 :alias: optional list of tuples as alternatives, |
|
38 :generic: this is a generic definition, match name using regular expression. |
37 """ |
39 """ |
38 |
40 |
39 def __init__(self, section, name, default=None, alias=()): |
41 def __init__(self, section, name, default=None, alias=(), |
|
42 generic=False, priority=0): |
40 self.section = section |
43 self.section = section |
41 self.name = name |
44 self.name = name |
42 self.default = default |
45 self.default = default |
43 self.alias = list(alias) |
46 self.alias = list(alias) |
|
47 self.generic = generic |
|
48 self.priority = priority |
|
49 self._re = None |
|
50 if generic: |
|
51 self._re = re.compile(self.name) |
|
52 |
|
53 class itemregister(dict): |
|
54 """A specialized dictionary that can handle wild-card selection""" |
|
55 |
|
56 def __init__(self): |
|
57 super(itemregister, self).__init__() |
|
58 self._generics = set() |
|
59 |
|
60 def update(self, other): |
|
61 super(itemregister, self).update(other) |
|
62 self._generics.update(other._generics) |
|
63 |
|
64 def __setitem__(self, key, item): |
|
65 super(itemregister, self).__setitem__(key, item) |
|
66 if item.generic: |
|
67 self._generics.add(item) |
|
68 |
|
69 def get(self, key): |
|
70 if key in self: |
|
71 return self[key] |
|
72 |
|
73 # search for a matching generic item |
|
74 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name))) |
|
75 for item in generics: |
|
76 if item._re.match(key): |
|
77 return item |
|
78 |
|
79 # fallback to dict get |
|
80 return super(itemregister, self).get(key) |
44 |
81 |
45 coreitems = {} |
82 coreitems = {} |
46 |
83 |
47 def _register(configtable, *args, **kwargs): |
84 def _register(configtable, *args, **kwargs): |
48 item = configitem(*args, **kwargs) |
85 item = configitem(*args, **kwargs) |
49 section = configtable.setdefault(item.section, {}) |
86 section = configtable.setdefault(item.section, itemregister()) |
50 if item.name in section: |
87 if item.name in section: |
51 msg = "duplicated config item registration for '%s.%s'" |
88 msg = "duplicated config item registration for '%s.%s'" |
52 raise error.ProgrammingError(msg % (item.section, item.name)) |
89 raise error.ProgrammingError(msg % (item.section, item.name)) |
53 section[item.name] = item |
90 section[item.name] = item |
54 |
91 |