43 |
46 |
44 def clear(self): |
47 def clear(self): |
45 self._tagdefs.clear() |
48 self._tagdefs.clear() |
46 |
49 |
47 def _get_keys(self, stype, rtype, otype, tagged): |
50 def _get_keys(self, stype, rtype, otype, tagged): |
48 keys = [(rtype, tagged, '*', '*'), |
51 keys = [('*', rtype, '*', tagged), |
49 (rtype, tagged, '*', otype), |
52 ('*', rtype, otype, tagged), |
50 (rtype, tagged, stype, '*'), |
53 (stype, rtype, '*', tagged), |
51 (rtype, tagged, stype, otype)] |
54 (stype, rtype, otype, tagged)] |
52 if stype == '*' or otype == '*': |
55 if stype == '*' or otype == '*': |
53 keys.remove((rtype, tagged, '*', '*')) |
56 keys.remove( ('*', rtype, '*', tagged) ) |
54 if stype == '*': |
57 if stype == '*': |
55 keys.remove((rtype, tagged, '*', otype)) |
58 keys.remove( ('*', rtype, otype, tagged) ) |
56 if otype == '*': |
59 if otype == '*': |
57 keys.remove((rtype, tagged, stype, '*')) |
60 keys.remove( (stype, rtype, '*', tagged) ) |
58 return keys |
61 return keys |
59 |
62 |
60 def init(self, schema, check=True): |
63 def init(self, schema, check=True): |
61 # XXX check existing keys against schema |
64 # XXX check existing keys against schema |
62 if check: |
65 if check: |
63 for (rtype, tagged, stype, otype), value in self._tagdefs.items(): |
66 for (stype, rtype, otype, tagged), value in self._tagdefs.items(): |
64 for ertype in (stype, rtype, otype): |
67 for ertype in (stype, rtype, otype): |
65 if ertype != '*' and not ertype in schema: |
68 if ertype != '*' and not ertype in schema: |
66 self.warning('removing rtag %s: %s, %s undefined in schema', |
69 self.warning('removing rtag %s: %s, %s undefined in schema', |
67 (stype, rtype, otype, tagged), value, ertype) |
70 (stype, rtype, otype, tagged), value, ertype) |
68 self.del_rtag(stype, rtype, otype, tagged) |
71 self.del_rtag(stype, rtype, otype, tagged) |
101 stype, rtype, otype, tagged = [str(k) for k in key] |
104 stype, rtype, otype, tagged = [str(k) for k in key] |
102 if self._allowed_values is not None: |
105 if self._allowed_values is not None: |
103 assert tag in self._allowed_values, \ |
106 assert tag in self._allowed_values, \ |
104 '%r is not an allowed tag (should be in %s)' % ( |
107 '%r is not an allowed tag (should be in %s)' % ( |
105 tag, self._allowed_values) |
108 tag, self._allowed_values) |
106 self._tagdefs[(rtype, tagged, stype, otype)] = tag |
109 self._tagdefs[_ensure_str_key(key)] = tag |
107 return tag |
110 return tag |
108 |
111 |
109 # rtag runtime api ######################################################## |
112 # rtag runtime api ######################################################## |
110 |
113 |
111 def del_rtag(self, stype, rtype, otype, tagged): |
114 def del_rtag(self, *key): |
112 del self._tagdefs[(rtype, tagged, stype, otype)] |
115 del self._tagdefs[key] |
113 |
116 |
114 def get(self, stype, rtype, otype, tagged): |
117 def get(self, stype, rtype, otype, tagged): |
115 for key in reversed(self._get_keys(stype, rtype, otype, tagged)): |
118 for key in reversed(self._get_keys(stype, rtype, otype, tagged)): |
116 try: |
119 try: |
117 return self._tagdefs[key] |
120 return self._tagdefs[key] |
130 """This class associates a set of tags to each key. |
133 """This class associates a set of tags to each key. |
131 """ |
134 """ |
132 tag_container_cls = set |
135 tag_container_cls = set |
133 |
136 |
134 def tag_relation(self, key, tag): |
137 def tag_relation(self, key, tag): |
135 stype, rtype, otype, tagged = [str(k) for k in key] |
138 rtags = self._tagdefs.setdefault(_ensure_str_key(key), |
136 rtags = self._tagdefs.setdefault((rtype, tagged, stype, otype), |
|
137 self.tag_container_cls()) |
139 self.tag_container_cls()) |
138 rtags.add(tag) |
140 rtags.add(tag) |
139 return rtags |
141 return rtags |
140 |
142 |
141 def get(self, stype, rtype, otype, tagged): |
143 def get(self, stype, rtype, otype, tagged): |
151 class RelationTagsDict(RelationTagsSet): |
153 class RelationTagsDict(RelationTagsSet): |
152 """This class associates a set of tags to each key.""" |
154 """This class associates a set of tags to each key.""" |
153 tag_container_cls = dict |
155 tag_container_cls = dict |
154 |
156 |
155 def tag_relation(self, key, tag): |
157 def tag_relation(self, key, tag): |
156 stype, rtype, otype, tagged = [str(k) for k in key] |
158 key = _ensure_str_key(key) |
157 try: |
159 try: |
158 rtags = self._tagdefs[(rtype, tagged, stype, otype)] |
160 rtags = self._tagdefs[key] |
159 rtags.update(tag) |
161 rtags.update(tag) |
160 return rtags |
162 return rtags |
161 except KeyError: |
163 except KeyError: |
162 self._tagdefs[(rtype, tagged, stype, otype)] = tag |
164 self._tagdefs[key] = tag |
163 return tag |
165 return tag |
164 |
166 |
165 def setdefault(self, key, tagkey, tagvalue): |
167 def setdefault(self, key, tagkey, tagvalue): |
166 stype, rtype, otype, tagged = [str(k) for k in key] |
168 key = _ensure_str_key(key) |
167 try: |
169 try: |
168 rtags = self._tagdefs[(rtype, tagged, stype, otype)] |
170 rtags = self._tagdefs[key] |
169 rtags.setdefault(tagkey, tagvalue) |
171 rtags.setdefault(tagkey, tagvalue) |
170 return rtags |
172 return rtags |
171 except KeyError: |
173 except KeyError: |
172 self._tagdefs[(rtype, tagged, stype, otype)] = {tagkey: tagvalue} |
174 self._tagdefs[key] = {tagkey: tagvalue} |
173 return self._tagdefs[(rtype, tagged, stype, otype)] |
175 return self._tagdefs[key] |
174 |
176 |
175 |
177 |
176 class RelationTagsBool(RelationTags): |
178 class RelationTagsBool(RelationTags): |
177 _allowed_values = frozenset((True, False)) |
179 _allowed_values = frozenset((True, False)) |
178 |
180 |