[Zope-Checkins] CVS: Packages/ZConfig - info.py:1.1.2.11 loader.py:1.1.2.10 matcher.py:1.1.2.16 schema.py:1.1.2.12

Fred L. Drake, Jr. fred@zope.com
Thu, 12 Dec 2002 17:50:49 -0500


Update of /cvs-repository/Packages/ZConfig
In directory cvs.zope.org:/tmp/cvs-serv9560

Modified Files:
      Tag: zconfig-schema-devel-branch
	info.py loader.py matcher.py schema.py 
Log Message:
Checkpoint:  Get sectiongroup partly implemented (but not yet working).
This does not break any tests.


=== Packages/ZConfig/info.py 1.1.2.10 => 1.1.2.11 ===
--- Packages/ZConfig/info.py:1.1.2.10	Thu Dec 12 15:08:51 2002
+++ Packages/ZConfig/info.py	Thu Dec 12 17:50:48 2002
@@ -22,12 +22,6 @@
     True = 1
     False = 0
 
-    def bool(value):
-        if value:
-            return True
-        else:
-            return False
-
 
 class UnboundedThing:
     def __lt__(self, other):
@@ -71,6 +65,13 @@
         self.handler = handler
         self.attribute = attribute
 
+    def __repr__(self):
+        clsname = self.__class__.__name__
+        return "<%s for %s>" % (clsname, `self.name`)
+
+    def istypegroup(self):
+        return False
+
     def ismulti(self):
         return self.maxOccurs > 1
 
@@ -140,10 +141,19 @@
                 raise ZConfig.ConfigurationError(
                     "sections which can occur more than once must"
                     " specify a target attribute name")
-        BaseInfo.__init__(self, name, sectiontype.datatype,
+        if sectiontype.istypegroup():
+            datatype = None
+        else:
+            datatype = sectiontype.datatype
+        BaseInfo.__init__(self, name, datatype,
                           minOccurs, maxOccurs, handler, attribute)
         self.sectiontype = sectiontype
 
+    def __repr__(self):
+        clsname = self.__class__.__name__
+        return "<%s for %s (%s)>" % (
+            clsname, self.sectiontype.name, `self.name`)
+
     def issection(self):
         return True
 
@@ -154,13 +164,42 @@
         if name == "*" or name == "+":
             return False
         elif self.name == "+":
-            return bool(name)
+            return name and True or False
         elif not name:
             return self.name == "*"
         else:
             return name == self.name
 
 
+class TypeContainer:
+    def __init__(self):
+        self._types = {}
+
+    def addtype(self, typeinfo):
+        if self._types.has_key(typeinfo.name):
+            raise ZConfig.ConfigurationError("type name cannot be redefined: "
+                                             + `typeinfo.name`)
+        self._types[typeinfo.name] = typeinfo
+
+    def gettype(self, name):
+        try:
+            return self._types[name]
+        except KeyError:
+            raise ZConfig.ConfigurationError("unknown type name: " + `name`)
+
+    def gettypenames(self):
+        return self._types.keys()
+
+
+class GroupType(TypeContainer):
+    def __init__(self, name):
+        TypeContainer.__init__(self)
+        self.name = name
+
+    def istypegroup(self):
+        return True
+
+
 class SectionType:
     def __init__(self, name, keytype, valuetype, datatype):
         # name      -
@@ -225,40 +264,55 @@
                     if not info.issection():
                         raise ZConfig.ConfigurationError(
                             "section name %s already in use for key" % key)
-                    if not info.sectiontype.name == type:
+                    st = info.sectiontype
+                    if st.istypegroup():
+                        try:
+                            st = st.gettype(type)
+                        except ZConfig.ConfigurationError:
+                            raise ZConfig.ConfigurationError(
+                                "section type %s not allowed for name %s"
+                                % (`type`, `key`))
+                    if not st.name == type:
                         raise ZConfig.ConfigurationError(
                             "name %s must be used for a %s section"
-                            % (`name`, `info.sectiontype.name`))
+                            % (`name`, `st.name`))
                     return index
+            # else must be a section or a sectiongroup:
             elif info.sectiontype.name == type:
                 if not (name or info.allowUnnamed()):
                     raise ZConfig.ConfigurationError(
                         `type` + " sections must be named")
                 return index
+            elif info.sectiontype.istypegroup():
+                st = info.sectiontype
+                if st.name == type:
+                    raise ZConfig.ConfigurationError(
+                        "cannot define section with a sectiongroup type")
+                try:
+                    st = st.gettype(type)
+                except ZConfig.ConfigurationError:
+                    # not this one; maybe a different one
+                    pass
+                else:
+                    return index
         raise ZConfig.ConfigurationError("no matching section defined")
 
     def getsectioninfo(self, type, name):
         i = self.getsectionindex(type, name)
-        return self._children[i][1]
+        st = self._children[i][1]
+        if st.istypegroup():
+            st = st.gettype(type)
+        return st
+
+    def istypegroup(self):
+        return False
 
 
-class SchemaType(SectionType):
+class SchemaType(TypeContainer, SectionType):
     def __init__(self, keytype, valuetype, datatype, handler):
         SectionType.__init__(self, None, keytype, valuetype, datatype)
+        TypeContainer.__init__(self)
         self.handler = handler
-        self._types = {}
-
-    def addtype(self, typeinfo):
-        if self._types.has_key(typeinfo.name):
-            raise ZConfig.ConfigurationError("type name cannot be redefined: "
-                                             + `typeinfo.name`)
-        self._types[typeinfo.name] = typeinfo
-
-    def gettype(self, name):
-        try:
-            return self._types[name]
-        except KeyError:
-            raise ZConfig.ConfigurationError("unknown type name: " + `name`)
 
     def allowUnnamed(self):
         return True


=== Packages/ZConfig/loader.py 1.1.2.9 => 1.1.2.10 ===
--- Packages/ZConfig/loader.py:1.1.2.9	Thu Dec 12 13:11:20 2002
+++ Packages/ZConfig/loader.py	Thu Dec 12 17:50:48 2002
@@ -101,6 +101,7 @@
         info = parent.info
         info = getattr(info, "sectiontype", info)
         ci = info.getsectioninfo(type, name)
+        assert not ci.istypegroup()
         if not ci.isAllowedName(name):
             raise ZConfig.ConfigurationError(
                 "%s is not an allowed name for %s sections"


=== Packages/ZConfig/matcher.py 1.1.2.15 => 1.1.2.16 ===
--- Packages/ZConfig/matcher.py:1.1.2.15	Thu Dec 12 15:12:54 2002
+++ Packages/ZConfig/matcher.py	Thu Dec 12 17:50:48 2002
@@ -25,6 +25,10 @@
         self._values = [None] * len(type)
         self._sectionnames = {}
 
+    def __repr__(self):
+        clsname = self.__class__.__name__
+        return "<%s for >" % (clsname, )
+
     def addSection(self, type, name, sectvalue):
         if name:
             if self._sectionnames.has_key(name):


=== Packages/ZConfig/schema.py 1.1.2.11 => 1.1.2.12 ===
--- Packages/ZConfig/schema.py:1.1.2.11	Thu Dec 12 15:10:41 2002
+++ Packages/ZConfig/schema.py	Thu Dec 12 17:50:48 2002
@@ -50,6 +50,7 @@
         self._prefixes = []
         self._schema = None
         self._stack = []
+        self._group = None
 
     def parseStream(self, stream):
         xml.sax.parse(stream, self)
@@ -114,7 +115,7 @@
         name = attrs.get("prefix", "")
         prefix = self.get_classname(name)
         if prefix[:1] == ".":
-            raise ZConfig.ConfigurationError("prefix may not begin with '.'")
+            self.doSchemaError("prefix may not begin with '.'")
         self._prefixes.append(prefix)
 
     def get_datatype(self, attrs, key, default):
@@ -144,12 +145,14 @@
     def start_sectiontype(self, attrs):
         name = attrs.get("name")
         if not name:
-            raise ZConfig.ConfigurationError(
+            self.doSchemaError(
                 "sectiontype name must not be omitted or empty")
         name = _identifier(name)
         keytype, valuetype, datatype = self.get_sect_typeinfo(attrs)
         sectinfo = info.SectionType(name, keytype, valuetype, datatype)
         self._schema.addtype(sectinfo)
+        if self._group is not None:
+            self._group.addtype(sectinfo)
         self._stack.append(sectinfo)
 
     def end_sectiontype(self):
@@ -171,14 +174,20 @@
         self._stack.pop()
 
     def start_sectiongroup(self, attrs):
+        if self._group is not None:
+            self.doSchemaError("sectiongroup elements cannot be nested")
         self.push_prefix(attrs)
         name = attrs.get("name")
         if not name:
-            self.doSchemaError("section group must be named")
-        raise NotImpementedError("sectiongroup support not yet implemented")
+            self.doSchemaError("sectiongroup must be named")
+        self._group = info.GroupType(name)
+        self._schema.addtype(self._group)
+        self._stack.append(self._group)
 
     def end_sectiongroup(self):
         del self._prefixes[-1]
+        self._group = None
+        self._stack.pop()
 
     def start_key(self, attrs):
         name = attrs.get("name")