[Zope3-checkins] CVS: Zope3/src/zope/exceptions - __init__.py:1.2 _duplicate.py:1.2 _forbidden.py:1.2 _notfounderror.py:1.2 _zope_error.py:1.2 exceptionformatter.py:1.2 interfaces.py:1.2 unauthorized.py:1.2
Jim Fulton
jim@zope.com
Wed, 25 Dec 2002 09:14:10 -0500
Update of /cvs-repository/Zope3/src/zope/exceptions
In directory cvs.zope.org:/tmp/cvs-serv15352/src/zope/exceptions
Added Files:
__init__.py _duplicate.py _forbidden.py _notfounderror.py
_zope_error.py exceptionformatter.py interfaces.py
unauthorized.py
Log Message:
Grand renaming:
- Renamed most files (especially python modules) to lower case.
- Moved views and interfaces into separate hierarchies within each
project, where each top-level directory under the zope package
is a separate project.
- Moved everything to src from lib/python.
lib/python will eventually go away. I need access to the cvs
repository to make this happen, however.
There are probably some bits that are broken. All tests pass
and zope runs, but I haven't tried everything. There are a number
of cleanups I'll work on tomorrow.
=== Zope3/src/zope/exceptions/__init__.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:09 2002
+++ Zope3/src/zope/exceptions/__init__.py Wed Dec 25 09:13:38 2002
@@ -0,0 +1,26 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""General exceptions that wish they were standard exceptions
+
+These exceptions are so general purpose that they don't belong in Zope
+application-specific packages.
+
+$Id$
+"""
+
+from zope.exceptions._zope_error import ZopeError
+from zope.exceptions.unauthorized import Unauthorized
+from zope.exceptions._notfounderror import NotFoundError
+from zope.exceptions._forbidden import Forbidden, ForbiddenAttribute
+from zope.exceptions._duplicate import DuplicationError
=== Zope3/src/zope/exceptions/_duplicate.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:09 2002
+++ Zope3/src/zope/exceptions/_duplicate.py Wed Dec 25 09:13:38 2002
@@ -0,0 +1,20 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+from zope.exceptions import ZopeError
+
+class DuplicationError(ZopeError):
+ """A duplicate registration was attempted"""
=== Zope3/src/zope/exceptions/_forbidden.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:09 2002
+++ Zope3/src/zope/exceptions/_forbidden.py Wed Dec 25 09:13:38 2002
@@ -0,0 +1,25 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+from zope.exceptions import ZopeError
+
+class Forbidden(ZopeError):
+ """A resource cannot be accessed under any circumstances
+ """
+
+class ForbiddenAttribute(Forbidden, AttributeError):
+ """An attribute is unavailable because it is forbidden (private)
+ """
=== Zope3/src/zope/exceptions/_notfounderror.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:09 2002
+++ Zope3/src/zope/exceptions/_notfounderror.py Wed Dec 25 09:13:38 2002
@@ -0,0 +1,21 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+from zope.exceptions import ZopeError
+
+class NotFoundError(ZopeError, KeyError):
+ """A resource could not be found.
+ """
=== Zope3/src/zope/exceptions/_zope_error.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:09 2002
+++ Zope3/src/zope/exceptions/_zope_error.py Wed Dec 25 09:13:38 2002
@@ -0,0 +1,20 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Base class for Zope application errors.
+
+$Id$
+"""
+
+class ZopeError( Exception ):
+ """ Generic base class for Zope errors."""
=== Zope3/src/zope/exceptions/exceptionformatter.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:09 2002
+++ Zope3/src/zope/exceptions/exceptionformatter.py Wed Dec 25 09:13:38 2002
@@ -0,0 +1,239 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""An exception formatter that shows traceback supplements and traceback info,
+optionally in HTML.
+
+$Id$
+"""
+
+import sys
+import cgi
+
+
+DEBUG_EXCEPTION_FORMATTER = 1
+
+
+class TextExceptionFormatter:
+
+ line_sep = '\n'
+ show_revisions = 0
+
+ def __init__(self, limit=None):
+ self.limit = limit
+
+ def escape(self, s):
+ return s
+
+ def getPrefix(self):
+ return 'Traceback (innermost last):'
+
+ def getLimit(self):
+ limit = self.limit
+ if limit is None:
+ limit = getattr(sys, 'tracebacklimit', None)
+ return limit
+
+ def getRevision(self, globals):
+ if not self.show_revisions:
+ return None
+ revision = globals.get('__revision__', None)
+ if revision is None:
+ # Incorrect but commonly used spelling
+ revision = globals.get('__version__', None)
+
+ if revision is not None:
+ try:
+ revision = str(revision).strip()
+ except:
+ revision = '???'
+ return revision
+
+ def formatSupplementLine(self, line):
+ return ' - %s' % line
+
+ def formatSourceURL(self, url):
+ return [self.formatSupplementLine(url)]
+
+ def formatSupplement(self, supplement, tb):
+ result = []
+ fmtLine = self.formatSupplementLine
+
+ url = getattr(supplement, 'source_url', None)
+ if url is not None:
+ result.extend(self.formatSourceURL(url))
+
+ line = getattr(supplement, 'line', 0)
+ if line == -1:
+ line = tb.tb_lineno
+ col = getattr(supplement, 'column', -1)
+ if line:
+ if col is not None and col >= 0:
+ result.append(fmtLine('Line %s, Column %s' % (
+ line, col)))
+ else:
+ result.append(fmtLine('Line %s' % line))
+ elif col is not None and col >= 0:
+ result.append(fmtLine('Column %s' % col))
+
+ expr = getattr(supplement, 'expression', None)
+ if expr:
+ result.append(fmtLine('Expression: %s' % expr))
+
+ warnings = getattr(supplement, 'warnings', None)
+ if warnings:
+ for warning in warnings:
+ result.append(fmtLine('Warning: %s' % warning))
+
+ getInfo = getattr(supplement, 'getInfo', None)
+ if getInfo is not None:
+ try:
+ extra = getInfo()
+ if extra:
+ result.append(extra)
+ except:
+ if DEBUG_EXCEPTION_FORMATTER:
+ import traceback
+ traceback.print_exc()
+ # else just swallow the exception.
+ return result
+
+ def formatTracebackInfo(self, tbi):
+ return self.formatSupplementLine('__traceback_info__: %s' % tbi)
+
+ def formatLine(self, tb):
+ f = tb.tb_frame
+ lineno = tb.tb_lineno
+ co = f.f_code
+ filename = co.co_filename
+ name = co.co_name
+ locals = f.f_locals
+ globals = f.f_globals
+ modname = globals.get('__name__', filename)
+
+ s = ' Module %s, line %d' % (modname, lineno)
+
+ revision = self.getRevision(globals)
+ if revision:
+ s = s + ', rev. %s' % revision
+
+ s = s + ', in %s' % name
+
+ result = []
+ result.append(self.escape(s))
+
+ # Output a traceback supplement, if any.
+ if '__traceback_supplement__' in locals:
+ # Use the supplement defined in the function.
+ tbs = locals['__traceback_supplement__']
+ elif '__traceback_supplement__' in globals:
+ # Use the supplement defined in the module.
+ # This is used by Scripts (Python).
+ tbs = globals['__traceback_supplement__']
+ else:
+ tbs = None
+ if tbs is not None:
+ factory = tbs[0]
+ args = tbs[1:]
+ try:
+ supp = factory(*args)
+ result.extend(self.formatSupplement(supp, tb))
+ except:
+ if DEBUG_EXCEPTION_FORMATTER:
+ import traceback
+ traceback.print_exc()
+ # else just swallow the exception.
+
+ try:
+ tbi = locals.get('__traceback_info__', None)
+ if tbi is not None:
+ result.append(self.formatTracebackInfo(tbi))
+ except:
+ if DEBUG_EXCEPTION_FORMATTER:
+ import traceback
+ traceback.print_exc()
+ # else just swallow the exception.
+
+ return self.line_sep.join(result)
+
+ def formatExceptionOnly(self, etype, value):
+ import traceback
+ return self.line_sep.join(
+ traceback.format_exception_only(etype, value))
+
+ def formatLastLine(self, exc_line):
+ return self.escape(exc_line)
+
+ def formatException(self, etype, value, tb):
+ # The next line provides a way to detect recursion.
+ __exception_formatter__ = 1
+ result = [self.getPrefix() + '\n']
+ limit = self.getLimit()
+ n = 0
+ while tb is not None and (limit is None or n < limit):
+ if tb.tb_frame.f_locals.get('__exception_formatter__'):
+ # Stop recursion.
+ result.append('(Recursive formatException() stopped)\n')
+ break
+ line = self.formatLine(tb)
+ result.append(line + '\n')
+ tb = tb.tb_next
+ n = n + 1
+ exc_line = self.formatExceptionOnly(etype, value)
+ result.append(self.formatLastLine(exc_line))
+ return result
+
+
+
+class HTMLExceptionFormatter (TextExceptionFormatter):
+
+ line_sep = '<br />\r\n'
+
+ def escape(self, s):
+ return cgi.escape(s)
+
+ def getPrefix(self):
+ return '<p>Traceback (innermost last):\r\n<ul>'
+
+ def formatSupplementLine(self, line):
+ return '<b>%s</b>' % self.escape(str(line))
+
+ def formatTracebackInfo(self, tbi):
+ s = self.escape(str(tbi))
+ s = s.replace('\n', self.line_sep)
+ return '__traceback_info__: %s' % s
+
+ def formatLine(self, tb):
+ line = TextExceptionFormatter.formatLine(self, tb)
+ return '<li>%s</li>' % line
+
+ def formatLastLine(self, exc_line):
+ return '</ul>%s</p>' % self.escape(exc_line)
+
+
+
+limit = 200
+
+if hasattr(sys, 'tracebacklimit'):
+ limit = min(limit, sys.tracebacklimit)
+
+text_formatter = TextExceptionFormatter(limit)
+html_formatter = HTMLExceptionFormatter(limit)
+
+
+def format_exception(t, v, tb, limit=None, as_html=0):
+ if as_html:
+ fmt = html_formatter
+ else:
+ fmt = text_formatter
+ return fmt.formatException(t, v, tb)
=== Zope3/src/zope/exceptions/interfaces.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:09 2002
+++ Zope3/src/zope/exceptions/interfaces.py Wed Dec 25 09:13:38 2002
@@ -0,0 +1,82 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""ITracebackSupplement interface definition.
+
+$Id$
+"""
+
+
+from zope.interface import Interface, Attribute
+
+class ITracebackSupplement(Interface):
+ """Provides valuable information to supplement an exception traceback.
+
+ The interface is geared toward providing meaningful feedback when
+ exceptions occur in user code written in mini-languages like
+ Zope page templates and restricted Python scripts.
+ """
+
+ source_url = Attribute(
+ 'source_url',
+ """Optional. Set to URL of the script where the exception occurred.
+
+ Normally this generates a URL in the traceback that the user
+ can visit to manage the object. Set to None if unknown or
+ not available.
+ """
+ )
+
+ line = Attribute(
+ 'line',
+ """Optional. Set to the line number (>=1) where the exception
+ occurred.
+
+ Set to 0 or None if the line number is unknown.
+ """
+ )
+
+ column = Attribute(
+ 'column',
+ """Optional. Set to the column offset (>=0) where the exception
+ occurred.
+
+ Set to None if the column number is unknown.
+ """
+ )
+
+ expression = Attribute(
+ 'expression',
+ """Optional. Set to the expression that was being evaluated.
+
+ Set to None if not available or not applicable.
+ """
+ )
+
+ warnings = Attribute(
+ 'warnings',
+ """Optional. Set to a sequence of warning messages.
+
+ Set to None if not available, not applicable, or if the exception
+ itself provides enough information.
+ """
+ )
+
+
+ def getInfo(as_html=0):
+ """Optional. Returns a string containing any other useful info.
+
+ If as_html is set, the implementation must HTML-quote the result
+ (normally using cgi.escape()). Returns None to provide no
+ extra info.
+ """
=== Zope3/src/zope/exceptions/unauthorized.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:10 2002
+++ Zope3/src/zope/exceptions/unauthorized.py Wed Dec 25 09:13:38 2002
@@ -0,0 +1,70 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+
+from types import StringType
+from zope.exceptions import ZopeError
+
+class Unauthorized(ZopeError):
+ """Some user wasn't allowed to access a resource"""
+
+ def __init__(self, message=None, value=None, needed=None, name=None, **kw):
+ """Possible signatures:
+
+ Unauthorized()
+ Unauthorized(message) # Note that message includes a space
+ Unauthorized(name)
+ Unauthorized(name, value)
+ Unauthorized(name, value, needed)
+ Unauthorized(message, value, needed, name)
+
+ Where needed is a mapping objects with items represnting requirements
+ (e.g. {'permission': 'add spam'}). Any extra keyword arguments
+ provides are added to needed.
+ """
+ if name is None and (
+ not isinstance(message, StringType) or len(message.split()) <= 1):
+ # First arg is a name, not a message
+ name=message
+ message=None
+
+ self.name=name
+ self.message=message
+ self.value=value
+
+ if kw:
+ if needed: needed.update(kw)
+ else: needed=kw
+
+ self.needed=needed
+
+ def __str__(self):
+ if self.message is not None: return self.message
+ if self.name is not None:
+ return ("You are not allowed to access %s in this context"
+ % self.name)
+ elif self.value is not None:
+ return ("You are not allowed to access %s in this context"
+ % self.getValueName())
+
+
+ def getValueName(self):
+ v=self.value
+ vname=getattr(v, '__name__', None)
+ if vname: return vname
+ c = getattr(v, '__class__', type(v))
+ c = getattr(c, '__name__', 'object')
+ return "a particular %s" % c