[Zope-Checkins] CVS: Zope3/lib/python/Zope/Configuration - xmlconfig.py:1.1.2.15.8.4

Jim Fulton jim@zope.com
Mon, 3 Jun 2002 13:15:59 -0400


Update of /cvs-repository/Zope3/lib/python/Zope/Configuration
In directory cvs.zope.org:/tmp/cvs-serv12372/lib/python/Zope/Configuration

Modified Files:
      Tag: Zope3InWonderland-branch
	xmlconfig.py 
Log Message:
- Attribute renaming.

  In directives that define things, renamed thing_id to id. For
  example:

    <permission permission_id='xxx' ...

  became:

    <permission id='xxx' ...

  In directives that used things defined in this way, removed the id
  suffix. For example:

     <view permission_id='xxx' ...

  became:

     <view permission='xxx' ...

- Changed the way that exceptions from configuration files are
  reported. Went back to normal Python tracebacks followed by
  "configuration tracebacks". The configuration tracebacks look
  somewhat similar to Python tracebacks, with file location
  information. The most specific configuration file location is at the
  end of the traceback, followed by the original error type and
  value. 

- Added a testxmlconfig function to the xmlconfig module to support
  unit testing. This function suppresses usual configuration error
  generation so that the original error is raised. This is needed so
  that unit tests can detect that proper low-level errors are raised. 

Note that everyone will need to edit their principals.zcml files to
reflect these changes!



=== Zope3/lib/python/Zope/Configuration/xmlconfig.py 1.1.2.15.8.3 => 1.1.2.15.8.4 ===
 
     def __str__(self):
-        return "%s\nat line %s column %s of %s" % (
-            self.mess, self.lno, self.cno, self.sid)
+        return 'File "%s", line %s, column %s\n\t%s' % (
+            self.sid, self.lno, self.cno, self.mess)
 
 class ConfigurationExecutionError(ZopeXMLConfigurationError):
     """An error occurred during execution of a configuration action
@@ -62,11 +62,12 @@
 
     __top_name = 'http://namespaces.zope.org/zope', 'zopeConfigure' 
 
-    def __init__(self, actions, context, directives=None):
+    def __init__(self, actions, context, directives=None, testing=0):
         self.__stack = []
         self.__actions = actions
         self.__directives = directives
         self.__context = context
+        self.__testing = testing
         context.resolve
 
     def setDocumentLocator(self, locator):
@@ -93,17 +94,18 @@
                 aname = str(aname)
                 if iskeyword(aname): aname += '_'
                 kw[aname] = value
-                
+
         if len(stack) == 1:
             try:
                 stack.append(
                     begin(self.__directives, name, self.__context, **kw)
                     )
             except Exception, v:
-                __traceback_supplement__ = (
-                    ConfigurationTracebackSupplement, self.__locator, v
-                    )
-                raise
+                if self.__testing:
+                    raise
+                raise ZopeXMLConfigurationError, (
+                    self.__locator, v), sys.exc_info()[2] 
+                
         else:
             subs = self.__stack[-1]
             if subs is None:
@@ -112,11 +114,11 @@
             try:
                 stack.append(sub(subs, name, self.__context, **kw))
             except Exception, v:
-                __traceback_supplement__ = (
-                    ConfigurationTracebackSupplement, self.__locator, v
-                    )
-                raise
-                
+                if self.__testing:
+                    raise
+                raise ZopeXMLConfigurationError, (
+                    self.__locator, v), sys.exc_info()[2] 
+
     def endElementNS(self, name, qname):
         subs = self.__stack.pop()
         # to fool compiler that thinks actions is used before assignment:
@@ -126,10 +128,10 @@
             try:
                 actions = end(subs)
             except Exception, v:
-                __traceback_supplement__ = (
-                    ConfigurationTracebackSupplement, self.__locator, v
-                    )
-                raise
+                if self.__testing:
+                    raise
+                raise ZopeXMLConfigurationError, (
+                    self.__locator, str(v)), sys.exc_info()[2] 
 
         append = self.__actions.append
 
@@ -186,7 +188,8 @@
             raise TypeError, "Unrecognized config file attribute: %s" % name
 
 
-def xmlconfig(file, actions=None, context=None, directives=None):
+def xmlconfig(file, actions=None, context=None, directives=None,
+              testing=0):
     if context is None:
         context = name
 
@@ -199,10 +202,11 @@
     src.setByteStream(file)
     parser = make_parser()
     parser.setContentHandler(
-        ConfigurationHandler(actions, context,directives)
+        ConfigurationHandler(actions, context,directives,
+                             testing=testing)
         )
     parser.setFeature(feature_namespaces, 1)
-    parser.parse(src) 
+    parser.parse(src)
 
     if call:
         descriptors = {}
@@ -212,6 +216,13 @@
                     descriptors[des], loc, des)
             descriptors[des] = loc
             callable(*args, **kw)
+
+def testxmlconfig(file, actions=None, context=None, directives=None):
+    """xmlconfig that doesn't raise configuration errors
+
+    This is useful for testing, as it doesn't mask exception types.
+    """
+    return xmlconfig(file, actions, context, directives, testing=1)
             
 class ZopeConfigurationConflictError(ZopeXMLConfigurationError):
 
@@ -314,22 +325,3 @@
                 callable(*args, **kw)
             except Exception, v:
                 raise ConfigurationExecutionError(loc, v)
-                
-                
-class ConfigurationTracebackSupplement:
-    """Implementation of Zope.Exceptions.ITracebackSupplement"""
-    def __init__(self, locator, message):
-        self.message = message
-        self.line = locator.getLineNumber()
-        self.column = locator.getColumnNumber()
-        self.source_url  = locator.getSystemId()
-        
-    def getInfo(self, as_html=0):
-        
-        if not as_html:
-            return '   - Message: %s' % self.message
-        else:
-            from cgi import escape
-            return '<b>Message:</b><pre>%s</pre> in %s' % escape(self.message)
-        return None
-