new RelationTagsDict class, use it in uicfg where necessary stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Fri, 10 Jul 2009 12:15:09 +0200
branchstable
changeset 2369 5a2b8ed266ca
parent 2368 b41aef0e63a7
child 2370 1e8ce077b62a
child 2371 76bf522c27be
new RelationTagsDict class, use it in uicfg where necessary
rtags.py
test/unittest_rtags.py
web/uicfg.py
--- a/rtags.py	Fri Jul 10 09:44:36 2009 +0200
+++ b/rtags.py	Fri Jul 10 12:15:09 2009 +0200
@@ -101,6 +101,7 @@
                    '%r is not an allowed tag (should be in %s)' % (
                 tag, self._allowed_values)
         self._tagdefs[(rtype, tagged, stype, otype)] = tag
+        return tag
 
     # rtag runtime api ########################################################
 
@@ -123,15 +124,19 @@
 
 
 class RelationTagsSet(RelationTags):
-    """This class associates a set of tags to each key."""
+    """This class associates a set of tags to each key.
+    """
+    tag_container_cls = set
 
     def tag_relation(self, key, tag):
         stype, rtype, otype, tagged = [str(k) for k in key]
-        rtags = self._tagdefs.setdefault((rtype, tagged, stype, otype), set())
+        rtags = self._tagdefs.setdefault((rtype, tagged, stype, otype),
+                                         self.tag_container_cls())
         rtags.add(tag)
+        return rtags
 
     def get(self, stype, rtype, otype, tagged):
-        rtags = set()
+        rtags = self.tag_container_cls()
         for key in self._get_keys(stype, rtype, otype, tagged):
             try:
                 rtags.update(self._tagdefs[key])
@@ -140,6 +145,31 @@
         return rtags
 
 
+class RelationTagsDict(RelationTagsSet):
+    """This class associates a set of tags to each key."""
+    tag_container_cls = dict
+
+    def tag_relation(self, key, tag):
+        stype, rtype, otype, tagged = [str(k) for k in key]
+        try:
+            rtags = self._tagdefs[(rtype, tagged, stype, otype)]
+            rtags.update(tag)
+            return rtags
+        except KeyError:
+            self._tagdefs[(rtype, tagged, stype, otype)] = tag
+            return tag
+
+    def setdefault(self, key, tagkey, tagvalue):
+        stype, rtype, otype, tagged = [str(k) for k in key]
+        try:
+            rtags = self._tagdefs[(rtype, tagged, stype, otype)]
+            rtags.setdefault(tagkey, tagvalue)
+            return rtags
+        except KeyError:
+            self._tagdefs[(rtype, tagged, stype, otype)] = {tagkey: tagvalue}
+            return self._tagdefs[(rtype, tagged, stype, otype)]
+
+
 class RelationTagsBool(RelationTags):
     _allowed_values = frozenset((True, False))
 
--- a/test/unittest_rtags.py	Fri Jul 10 09:44:36 2009 +0200
+++ b/test/unittest_rtags.py	Fri Jul 10 12:15:09 2009 +0200
@@ -6,7 +6,7 @@
 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
 """
 from logilab.common.testlib import TestCase, unittest_main
-from cubicweb.rtags import RelationTags, RelationTagsSet
+from cubicweb.rtags import RelationTags, RelationTagsSet, RelationTagsDict
 
 class RelationTagsTC(TestCase):
 
@@ -53,12 +53,30 @@
         rtags.tag_subject_of(('*', 'travaille', '*'), 'secondary')
         self.assertEquals(rtags.get('Societe', 'travaille', '*', 'subject'),
                           set(('primary', 'secondary')))
-        self.assertEquals(rtags.get('Societe', 'travaille', '*', 'subject'),
-                          set(('primary', 'secondary')))
         self.assertEquals(rtags.get('Note', 'travaille', '*', 'subject'),
                           set(('secondary',)))
         self.assertEquals(rtags.get('Note', 'tags', "*", 'subject'),
                           set())
 
+    def test_rtagdict_expansion(self):
+        rtags = RelationTagsDict()
+        rtags.tag_subject_of(('Societe', 'travaille', '*'),
+                             {'key1': 'val1', 'key2': 'val1'})
+        rtags.tag_subject_of(('*', 'travaille', '*'),
+                             {'key1': 'val0', 'key3': 'val0'})
+        rtags.tag_subject_of(('Societe', 'travaille', '*'),
+                             {'key2': 'val2'})
+        self.assertEquals(rtags.get('Societe', 'travaille', '*', 'subject'),
+                          {'key1': 'val1', 'key2': 'val2', 'key3': 'val0'})
+        self.assertEquals(rtags.get('Note', 'travaille', '*', 'subject'),
+                          {'key1': 'val0', 'key3': 'val0'})
+        self.assertEquals(rtags.get('Note', 'tags', "*", 'subject'),
+                          {})
+
+        rtags.setdefault(('Societe', 'travaille', '*', 'subject'), 'key1', 'val4')
+        rtags.setdefault(('Societe', 'travaille', '*', 'subject'), 'key4', 'val4')
+        self.assertEquals(rtags.get('Societe', 'travaille', '*', 'subject'),
+                          {'key1': 'val1', 'key2': 'val2', 'key3': 'val0', 'key4': 'val4'})
+
 if __name__ == '__main__':
     unittest_main()
--- a/web/uicfg.py	Fri Jul 10 09:44:36 2009 +0200
+++ b/web/uicfg.py	Fri Jul 10 12:15:09 2009 +0200
@@ -68,7 +68,8 @@
 __docformat__ = "restructuredtext en"
 
 from cubicweb import neg_role
-from cubicweb.rtags import RelationTags, RelationTagsBool, RelationTagsSet
+from cubicweb.rtags import (RelationTags, RelationTagsBool,
+                            RelationTagsSet, RelationTagsDict)
 from cubicweb.web import formwidgets
 
 
@@ -118,14 +119,13 @@
     primaryview_section.tag_attribute(('CWRType', attr), 'hidden')
 
 
-class DisplayCtrlRelationTags(RelationTags):
+class DisplayCtrlRelationTags(RelationTagsDict):
     def __init__(self, *args, **kwargs):
         super(DisplayCtrlRelationTags, self).__init__(*args, **kwargs)
         self._counter = 0
 
     def tag_relation(self, key, tag):
-        assert isinstance(tag, dict)
-        super(DisplayCtrlRelationTags, self).tag_relation(key, tag)
+        tag = super(DisplayCtrlRelationTags, self).tag_relation(key, tag)
         self._counter += 1
         tag.setdefault('order', self._counter)
 
@@ -152,11 +152,8 @@
     else:
         sschema = '*'
         label = '%s_%s' % (rschema, role)
-    displayinfo = rtag.get(sschema, rschema, oschema, role)
-    if displayinfo is None:
-        displayinfo = {}
-        rtag.tag_relation((sschema, rschema, oschema, role), displayinfo)
-    displayinfo.setdefault('label', label)
+    rtag.setdefault((sschema, rschema, oschema, role), 'label', label)
+    rtag.setdefault((sschema, rschema, oschema, role), 'order', rtag._counter)
 
 primaryview_display_ctrl = DisplayCtrlRelationTags('primaryview_display_ctrl',
                                                    init_primaryview_display_ctrl)
@@ -239,7 +236,7 @@
 autoform_field = RelationTags('autoform_field')
 
 # relations'field explicit kwargs (given to field's __init__)
-autoform_field_kwargs = RelationTags()
+autoform_field_kwargs = RelationTagsDict()
 autoform_field_kwargs.tag_attribute(('RQLExpression', 'expression'),
                                     {'widget': formwidgets.TextInput})
 autoform_field_kwargs.tag_attribute(('Bookmark', 'path'),