[CalendarServer-changes] [11903] CalendarServer/trunk/twext/who

source_changes at macosforge.org source_changes at macosforge.org
Wed Mar 12 11:16:52 PDT 2014


Revision: 11903
          http://trac.calendarserver.org//changeset/11903
Author:   wsanchez at apple.com
Date:     2013-11-07 11:10:12 -0800 (Thu, 07 Nov 2013)
Log Message:
-----------
Better type handling:
 * Field values have an expected type.
   * Most are (default is) `unicode`.
   * guid is `UUID`.
 * Be explicit about string types everywhere.

Add CompoundExpression class.

Modified Paths:
--------------
    CalendarServer/trunk/twext/who/directory.py
    CalendarServer/trunk/twext/who/expression.py
    CalendarServer/trunk/twext/who/idirectory.py
    CalendarServer/trunk/twext/who/index.py
    CalendarServer/trunk/twext/who/test/test_aggregate.py
    CalendarServer/trunk/twext/who/test/test_directory.py
    CalendarServer/trunk/twext/who/test/test_expression.py
    CalendarServer/trunk/twext/who/test/test_util.py
    CalendarServer/trunk/twext/who/test/test_xml.py
    CalendarServer/trunk/twext/who/xml.py

Modified: CalendarServer/trunk/twext/who/directory.py
===================================================================
--- CalendarServer/trunk/twext/who/directory.py	2013-11-07 18:24:00 UTC (rev 11902)
+++ CalendarServer/trunk/twext/who/directory.py	2013-11-07 19:10:12 UTC (rev 11903)
@@ -92,7 +92,7 @@
     def __init__(self, realmName):
         """
         @param realmName: a realm name
-        @type realmName: unicode
+        @type realmName: L{unicode}
         """
         self.realmName = realmName
 
@@ -337,25 +337,31 @@
 
 
     def description(self):
-        description = [self.__class__.__name__, ":"]
+        """
+        Generate a string description of this directory record.
 
+        @return: A description.
+        @rtype: L{unicode}
+        """
+        description = [self.__class__.__name__, u":"]
+
         for name, value in self.fields.items():
             if hasattr(name, "description"):
                 name = name.description
             else:
-                name = str(name)
+                name = unicode(name)
 
             if hasattr(value, "description"):
                 value = value.description
             else:
-                value = str(value)
+                value = unicode(value)
 
-            description.append("\n  ")
+            description.append(u"\n  ")
             description.append(name)
-            description.append(" = ")
+            description.append(u" = ")
             description.append(value)
 
-        return "".join(description)
+        return u"".join(description)
 
 
     def members(self):

Modified: CalendarServer/trunk/twext/who/expression.py
===================================================================
--- CalendarServer/trunk/twext/who/expression.py	2013-11-07 18:24:00 UTC (rev 11902)
+++ CalendarServer/trunk/twext/who/expression.py	2013-11-07 19:10:12 UTC (rev 11903)
@@ -20,6 +20,8 @@
 """
 
 __all__ = [
+    "CompoundExpression",
+
     "MatchType",
     "MatchFlags",
     "MatchExpression",
@@ -30,12 +32,28 @@
 
 
 
-##
-# Match expression
-##
+#
+# Compound expression
+#
 
+class CompoundExpression(object):
+    """
+    An expression that groups multiple expressions with an operand.
 
+    @ivar expressions: An iterable of expressions.
 
+    @ivar operand: A L{NamedConstant} specifying an operand.
+    """
+
+    def __init__(self, expressions, operand):
+        self.expressions = expressions
+        self.operand = operand
+
+
+#
+# Match expression
+#
+
 class MatchType(Names):
     """
     Query match types.
@@ -44,9 +62,9 @@
     startsWith = NamedConstant()
     contains   = NamedConstant()
 
-    equals.description     = "equals"
-    startsWith.description = "starts with"
-    contains.description   = "contains"
+    equals.description     = u"equals"
+    startsWith.description = u"starts with"
+    contains.description   = u"contains"
 
 
 
@@ -55,10 +73,10 @@
     Match expression flags.
     """
     NOT = FlagConstant()
-    NOT.description = "not"
+    NOT.description = u"not"
 
     caseInsensitive = FlagConstant()
-    caseInsensitive.description = "case insensitive"
+    caseInsensitive.description = u"case insensitive"
 
 
 
@@ -88,7 +106,7 @@
 
     def __repr__(self):
         def describe(constant):
-            return getattr(constant, "description", str(constant))
+            return getattr(constant, "description", unicode(constant))
 
         if self.flags is None:
             flags = ""

Modified: CalendarServer/trunk/twext/who/idirectory.py
===================================================================
--- CalendarServer/trunk/twext/who/idirectory.py	2013-11-07 18:24:00 UTC (rev 11902)
+++ CalendarServer/trunk/twext/who/idirectory.py	2013-11-07 19:10:12 UTC (rev 11903)
@@ -16,7 +16,7 @@
 ##
 
 """
-Directory service interface.
+Directory service interfaces.
 """
 
 __all__ = [
@@ -111,8 +111,8 @@
     user  = NamedConstant()
     group = NamedConstant()
 
-    user.description  = "user"
-    group.description = "group"
+    user.description  = u"user"
+    group.description = u"group"
 
 
 
@@ -152,13 +152,13 @@
     emailAddresses = NamedConstant()
     password       = NamedConstant()
 
-    uid.description            = "UID"
-    guid.description           = "GUID"
-    recordType.description     = "record type"
-    shortNames.description     = "short names"
-    fullNames.description      = "full names"
-    emailAddresses.description = "email addresses"
-    password.description       = "password"
+    uid.description            = u"UID"
+    guid.description           = u"GUID"
+    recordType.description     = u"record type"
+    shortNames.description     = u"short names"
+    fullNames.description      = u"full names"
+    emailAddresses.description = u"email addresses"
+    password.description       = u"password"
 
     guid.valueType = UUID
 
@@ -203,8 +203,8 @@
     OR  = NamedConstant()
     AND = NamedConstant()
 
-    OR.description  = "or"
-    AND.description = "and"
+    OR.description  = u"or"
+    AND.description = u"and"
 
 
 

Modified: CalendarServer/trunk/twext/who/index.py
===================================================================
--- CalendarServer/trunk/twext/who/index.py	2013-11-07 18:24:00 UTC (rev 11902)
+++ CalendarServer/trunk/twext/who/index.py	2013-11-07 19:10:12 UTC (rev 11903)
@@ -44,7 +44,7 @@
 
 class FieldName(Names):
     memberUIDs = NamedConstant()
-    memberUIDs.description = "member UIDs"
+    memberUIDs.description = u"member UIDs"
     memberUIDs.multiValue = True
 
 

Modified: CalendarServer/trunk/twext/who/test/test_aggregate.py
===================================================================
--- CalendarServer/trunk/twext/who/test/test_aggregate.py	2013-11-07 18:24:00 UTC (rev 11902)
+++ CalendarServer/trunk/twext/who/test/test_aggregate.py	2013-11-07 19:10:12 UTC (rev 11903)
@@ -49,7 +49,7 @@
         class TestService(DirectoryService, QueryMixIn):
             pass
 
-        return TestService("xyzzy", services)
+        return TestService(u"xyzzy", services)
 
 
     def xmlService(self, xmlData=None, serviceClass=None):
@@ -60,7 +60,7 @@
 class DirectoryServiceBaseTest(BaseTest, test_xml.DirectoryServiceBaseTest):
     def test_repr(self):
         service = self.service()
-        self.assertEquals(repr(service), "<TestService 'xyzzy'>")
+        self.assertEquals(repr(service), "<TestService u'xyzzy'>")
 
 
 

Modified: CalendarServer/trunk/twext/who/test/test_directory.py
===================================================================
--- CalendarServer/trunk/twext/who/test/test_directory.py	2013-11-07 18:24:00 UTC (rev 11902)
+++ CalendarServer/trunk/twext/who/test/test_directory.py	2013-11-07 19:10:12 UTC (rev 11903)
@@ -32,7 +32,7 @@
 
 
 class ServiceMixIn(object):
-    realmName = "xyzzy"
+    realmName = u"xyzzy"
 
 
     def service(self):
@@ -58,7 +58,7 @@
 
     def test_repr(self):
         service = self.service()
-        self.assertEquals(repr(service), "<DirectoryService 'xyzzy'>")
+        self.assertEquals(repr(service), "<DirectoryService u'xyzzy'>")
 
 
     def test_recordTypes(self):
@@ -161,9 +161,9 @@
         newRecord = DirectoryRecord(
             service,
             fields={
-                service.fieldName.uid:        "__plugh__",
+                service.fieldName.uid:        u"__plugh__",
                 service.fieldName.recordType: service.recordType.user,
-                service.fieldName.shortNames: ("plugh",),
+                service.fieldName.shortNames: (u"plugh",),
             }
         )
 
@@ -183,7 +183,7 @@
 
         service.removeRecords(())
         self.assertFailure(
-            service.removeRecords(("foo",)),
+            service.removeRecords((u"foo",)),
             NotAllowedError,
         )
 
@@ -199,41 +199,41 @@
 
 class BaseDirectoryRecordTest(ServiceMixIn):
     fields_wsanchez = {
-        FieldName.uid: "UID:wsanchez",
+        FieldName.uid: u"UID:wsanchez",
         FieldName.recordType: RecordType.user,
-        FieldName.shortNames: ("wsanchez", "wilfredo_sanchez"),
+        FieldName.shortNames: (u"wsanchez", u"wilfredo_sanchez"),
         FieldName.fullNames: (
-            "Wilfredo Sanchez",
-            "Wilfredo Sanchez Vega",
+            u"Wilfredo Sanchez",
+            u"Wilfredo Sanchez Vega",
         ),
         FieldName.emailAddresses: (
-            "wsanchez at calendarserver.org",
-            "wsanchez at example.com",
+            u"wsanchez at calendarserver.org",
+            u"wsanchez at example.com",
         )
     }
 
     fields_glyph = {
-        FieldName.uid: "UID:glyph",
+        FieldName.uid: u"UID:glyph",
         FieldName.recordType: RecordType.user,
-        FieldName.shortNames: ("glyph",),
-        FieldName.fullNames: ("Glyph Lefkowitz",),
-        FieldName.emailAddresses: ("glyph at calendarserver.org",)
+        FieldName.shortNames: (u"glyph",),
+        FieldName.fullNames: (u"Glyph Lefkowitz",),
+        FieldName.emailAddresses: (u"glyph at calendarserver.org",)
     }
 
     fields_sagen = {
-        FieldName.uid: "UID:sagen",
+        FieldName.uid: u"UID:sagen",
         FieldName.recordType: RecordType.user,
-        FieldName.shortNames: ("sagen",),
-        FieldName.fullNames: ("Morgen Sagen",),
-        FieldName.emailAddresses: ("sagen at CalendarServer.org",)
+        FieldName.shortNames: (u"sagen",),
+        FieldName.fullNames: (u"Morgen Sagen",),
+        FieldName.emailAddresses: (u"sagen at CalendarServer.org",)
     }
 
     fields_staff = {
-        FieldName.uid: "UID:staff",
+        FieldName.uid: u"UID:staff",
         FieldName.recordType: RecordType.group,
-        FieldName.shortNames: ("staff",),
-        FieldName.fullNames: ("Staff",),
-        FieldName.emailAddresses: ("staff at CalendarServer.org",)
+        FieldName.shortNames: (u"staff",),
+        FieldName.fullNames: (u"Staff",),
+        FieldName.emailAddresses: (u"staff at CalendarServer.org",)
     }
 
 
@@ -267,7 +267,7 @@
         self.assertRaises(ValueError, self.makeRecord, fields)
 
         fields = self.fields_wsanchez.copy()
-        fields[FieldName.uid] = ""
+        fields[FieldName.uid] = u""
         self.assertRaises(ValueError, self.makeRecord, fields)
 
 
@@ -277,7 +277,7 @@
         self.assertRaises(ValueError, self.makeRecord, fields)
 
         fields = self.fields_wsanchez.copy()
-        fields[FieldName.recordType] = ""
+        fields[FieldName.recordType] = None
         self.assertRaises(ValueError, self.makeRecord, fields)
 
 
@@ -291,11 +291,11 @@
         self.assertRaises(ValueError, self.makeRecord, fields)
 
         fields = self.fields_wsanchez.copy()
-        fields[FieldName.shortNames] = ("",)
+        fields[FieldName.shortNames] = (u"",)
         self.assertRaises(ValueError, self.makeRecord, fields)
 
         fields = self.fields_wsanchez.copy()
-        fields[FieldName.shortNames] = ("wsanchez", "")
+        fields[FieldName.shortNames] = (u"wsanchez", u"")
         self.assertRaises(ValueError, self.makeRecord, fields)
 
 
@@ -310,7 +310,7 @@
 
         self.assertEquals(
             sagen.fields[FieldName.emailAddresses],
-            ("sagen at calendarserver.org",)
+            (u"sagen at calendarserver.org",)
         )
 
 
@@ -318,7 +318,7 @@
         fields_glyphmod = self.fields_glyph.copy()
         del fields_glyphmod[FieldName.emailAddresses]
 
-        plugh = DirectoryService("plugh")
+        plugh = DirectoryService(u"plugh")
 
         wsanchez    = self.makeRecord(self.fields_wsanchez)
         wsanchezmod = self.makeRecord(self.fields_wsanchez, plugh)

Modified: CalendarServer/trunk/twext/who/test/test_expression.py
===================================================================
--- CalendarServer/trunk/twext/who/test/test_expression.py	2013-11-07 18:24:00 UTC (rev 11902)
+++ CalendarServer/trunk/twext/who/test/test_expression.py	2013-11-07 19:10:12 UTC (rev 11903)
@@ -26,29 +26,31 @@
 
 
 class MatchExpressionTest(unittest.TestCase):
-    def test_repr(self):
+    def test_repr_name(self):
         self.assertEquals(
-            "<MatchExpression: 'full names' equals 'Wilfredo Sanchez'>",
+            "<MatchExpression: u'full names' equals u'Wilfredo Sanchez'>",
             repr(MatchExpression(
                 FieldName.fullNames,
-                "Wilfredo Sanchez",
+                u"Wilfredo Sanchez",
             )),
         )
 
+    def test_repr_type(self):
         self.assertEquals(
-            "<MatchExpression: 'full names' contains 'Sanchez'>",
+            "<MatchExpression: u'full names' contains u'Sanchez'>",
             repr(MatchExpression(
                 FieldName.fullNames,
-                "Sanchez",
+                u"Sanchez",
                 matchType=MatchType.contains,
             )),
         )
 
+    def test_repr_flags(self):
         self.assertEquals(
-            "<MatchExpression: 'full names' starts with 'Wilfredo' (not)>",
+            "<MatchExpression: u'full names' starts with u'Wilfredo' (not)>",
             repr(MatchExpression(
                 FieldName.fullNames,
-                "Wilfredo",
+                u"Wilfredo",
                 matchType=MatchType.startsWith,
                 flags=MatchFlags.NOT,
             )),

Modified: CalendarServer/trunk/twext/who/test/test_util.py
===================================================================
--- CalendarServer/trunk/twext/who/test/test_util.py	2013-11-07 18:24:00 UTC (rev 11902)
+++ CalendarServer/trunk/twext/who/test/test_util.py	2013-11-07 19:10:12 UTC (rev 11903)
@@ -29,11 +29,11 @@
 
 
 class Tools(Names):
-    hammer      = NamedConstant()
+    hammer = NamedConstant()
     screwdriver = NamedConstant()
 
-    hammer.description      = "nail pounder"
-    screwdriver.description = "screw twister"
+    hammer.description = u"nail pounder"
+    screwdriver.description = u"screw twister"
 
 
 
@@ -48,9 +48,9 @@
     g = FlagConstant()
     b = FlagConstant()
 
-    r.description = "red"
-    g.description = "green"
-    b.description = "blue"
+    r.description = u"red"
+    g.description = u"green"
+    b.description = u"blue"
 
     black = FlagConstant()
 
@@ -115,10 +115,10 @@
         self.assertRaises(DirectoryServiceError, uniqueResult, (1, 2, 3))
 
     def test_describe(self):
-        self.assertEquals("nail pounder", describe(Tools.hammer))
-        self.assertEquals("hammer", describe(Instruments.hammer))
+        self.assertEquals(u"nail pounder", describe(Tools.hammer))
+        self.assertEquals(u"hammer", describe(Instruments.hammer))
 
     def test_describeFlags(self):
-        self.assertEquals("blue", describe(Switches.b))
-        self.assertEquals("red|green", describe(Switches.r | Switches.g))
-        self.assertEquals("blue|black", describe(Switches.b | Switches.black))
+        self.assertEquals(u"blue", describe(Switches.b))
+        self.assertEquals(u"red|green", describe(Switches.r | Switches.g))
+        self.assertEquals(u"blue|black", describe(Switches.b | Switches.black))

Modified: CalendarServer/trunk/twext/who/test/test_xml.py
===================================================================
--- CalendarServer/trunk/twext/who/test/test_xml.py	2013-11-07 18:24:00 UTC (rev 11902)
+++ CalendarServer/trunk/twext/who/test/test_xml.py	2013-11-07 19:10:12 UTC (rev 11903)
@@ -57,7 +57,7 @@
 
         self.assertEquals(repr(service), "<TestService (not loaded)>")
         service.loadRecords()
-        self.assertEquals(repr(service), "<TestService 'xyzzy'>")
+        self.assertEquals(repr(service), "<TestService u'xyzzy'>")
 
 
     @inlineCallbacks

Modified: CalendarServer/trunk/twext/who/xml.py
===================================================================
--- CalendarServer/trunk/twext/who/xml.py	2013-11-07 18:24:00 UTC (rev 11902)
+++ CalendarServer/trunk/twext/who/xml.py	2013-11-07 19:10:12 UTC (rev 11903)
@@ -235,9 +235,9 @@
                 "Incorrect root element: {0}".format(directoryNode.tag)
             )
 
-        realmName = directoryNode.get(
+        realmName = unicode(directoryNode.get(
             self.attribute.realm.value, u""
-        )
+        ))
 
         if not realmName:
             raise ParseError("No realm name.")
@@ -321,7 +321,7 @@
             vType = BaseFieldName.valueType(fieldName)
 
             if vType in (unicode, UUID):
-                value = unicode(fieldNode.text)
+                value = vType(fieldNode.text)
             else:
                 raise AssertionError(
                     "Unknown value type {0} for field {1}",
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140312/bfc362c1/attachment.html>


More information about the calendarserver-changes mailing list