zope.exceptions-4.0.6/CHANGES.rst 0000644 0000000 0000000 00000007043 12113650724 014613 0 ustar 0000000 0000000 ``zope.exceptions`` Changelog
=============================
4.0.6 (2013-02-28)
------------------
- Make sure that ``setup.py`` finds all tests. Now tox runs them all as well.
- Fix failing test under Python 3.
- Made buildout work under Python 3 and Buildout 2.
4.0.5 (2012-12-31)
------------------
- Fleshed out PyPI Trove classifiers.
- Fixed a test failure under Python 2.6.
4.0.4 (2012-12-13)
------------------
- Release with a fixed MANIFEST.in (without ``docs/``)
4.0.3 (2012-12-10)
------------------
- Fixed format_exception(..., as_html=True) not to HTML-escape the '
'
it adds to the exception value.
4.0.2 (2012-11-21)
------------------
- Test Python 3.3 support under tox.
4.0.1 (2012-08-20)
------------------
- Fixed optional dependency code for `zope.security` to work under Python 3.3.
4.0.0.1 (2012-05-16)
--------------------
- Fixed rendering of package docs on PyPI.
4.0.0 (2012-05-16)
------------------
- Automated build of Sphinx HTML docs and running doctest snippets via tox.
- Added Sphinx documentation.
- Added support for continuous integration using ``tox`` and ``jenkins``.
- Removed use of '2to3' and associated fixers when installing under Py3k.
The code is now in a "compatible subset" which supports Python 2.6, 2.7,
and 3.2, including PyPy 1.8 (the version compatible with the 2.7 language
spec).
- 100% unit test coverage.
- Dropped explicit support for Python 2.4 / 2.5 / 3.1.
- Added 'setup.py dev' alias (runs ``setup.py develop`` plus installs
``nose`` and ``coverage``).
- Added 'setup.py docs' alias (installs ``Sphinx`` and dependencies).
3.7.1 (2012-03-28)
------------------
- Fix: missed to reverse extractStack entries
3.7.0 (2012-03-28)
------------------
- Added TextExceptionFormatter.extractStack and extract_stack
3.6.2 (2012-03-28)
------------------
- Fallback to traceback.format_tb when the formatter is called recursively.
i.e. Don't let errors in the formatter pass silently.
- Fix deprecated unittest functions: ``assert_`` and ``assertEquals``.
3.6.1 (2010-07-06)
------------------
- Fixed tests to work under Python 2.7.
- PEP8 cleanup and removed obsolete build infrastructure files.
3.6.0 (2010-05-02)
------------------
- Added support to bootstrap on Jython.
- Added Python 3 support.
- The dependency on zope.testing seemed spurious, possibly a rest of a real
dependency that is gone now. I removed it.
3.5.2 (2008-04-30)
------------------
- Updated CHANGES.txt.
3.5.1 (2008-04-28)
------------------
- Reverted changes in 3.5.0.
3.5.0
-----
- Added the capability for exceptions to be formatted line-by-line.
Unfortunately, also introduced a bug cause each line of the exception to be
its own log message.
3.4.0 (2007-10-02)
------------------
- Updated package meta-data.
3.4.0b2 (2007-08-14)
--------------------
- Removed superfluous dependency on ``zope.deprecation``.
3.4.0b1 (2007-07-09)
--------------------
- Corresponds to the version of the ``zope.exceptions`` package shipped as
part of the Zope 3.4.0b1 release.
3.2.0 (2006-01-05)
------------------
- Corresponds to the version of the ``zope.exceptions`` package shipped as part of
the Zope 3.2.0 release.
- Deprecated the ``INotFoundError`` interface and the corresponding
``NotFoundError`` exception class, in favor of "standard" exceptions
``AttributeError``, ``KeyError``). The deprecated items will be removed in
Zope 3.3.
3.0.0 (2004-11-07)
------------------
- Corresponds to the version of the zope.exceptions package shipped as part of
the Zope X3.0.0 release.
zope.exceptions-4.0.6/setup.cfg 0000644 0000000 0000000 00000000414 12113650750 014624 0 ustar 0000000 0000000 [nosetests]
nocapture = 1
cover-package = zope.exceptions
cover-erase = 1
with-doctest = 0
where = src
[aliases]
dev = develop easy_install zope.exceptions[testing]
docs = easy_install zope.exceptions[docs]
[egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0
zope.exceptions-4.0.6/COPYRIGHT.txt 0000644 0000000 0000000 00000000040 12113650724 015110 0 ustar 0000000 0000000 Zope Foundation and Contributors zope.exceptions-4.0.6/setup.py 0000644 0000000 0000000 00000006627 12113650724 014532 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2006 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
# This package is developed by the Zope Toolkit project, documented here:
# http://docs.zope.org/zopetoolkit
# When developing and releasing this package, please follow the documented
# Zope Toolkit policies as described by this documentation.
##############################################################################
"""Setup for zope.exceptions package
"""
import os
from setuptools import setup, find_packages
def read(*rnames):
return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
def alltests():
import os
import sys
import unittest
# use the zope.testrunner machinery to find all the
# test suites we've put under ourselves
import zope.testrunner.find
import zope.testrunner.options
here = os.path.abspath(os.path.join(os.path.dirname(__file__), 'src'))
args = sys.argv[:]
defaults = ["--test-path", here]
options = zope.testrunner.options.get_options(args, defaults)
suites = list(zope.testrunner.find.find_suites(options))
return unittest.TestSuite(suites)
setup(name='zope.exceptions',
version='4.0.6',
author='Zope Foundation and Contributors',
author_email='zope-dev@zope.org',
description='Zope Exceptions',
long_description=(read('README.rst') + '\n\n' +
read('CHANGES.rst')),
keywords = 'zope exceptions',
classifiers = [
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: Zope Public License',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
'Natural Language :: English',
'Operating System :: OS Independent',
'Topic :: Internet :: WWW/HTTP',
'Framework :: Zope3'],
url='http://cheeseshop.python.org/pypi/zope.exceptions',
license='ZPL 2.1',
packages=find_packages('src'),
package_dir = {'': 'src'},
namespace_packages=['zope'],
install_requires=['setuptools',
'zope.interface',
],
tests_require = [
'zope.testrunner',
],
test_suite = '__main__.alltests',
include_package_data = True,
zip_safe = False,
extras_require = {
'docs': ['Sphinx', 'repoze.sphinx.autointerface'],
'testing': ['nose', 'coverage'],
},
)
zope.exceptions-4.0.6/MANIFEST.in 0000644 0000000 0000000 00000000242 12113650724 014541 0 ustar 0000000 0000000 include *.rst
include *.txt
recursive-include docs *
recursive-include src *
global-exclude *.dll
global-exclude *.pyc
global-exclude *.pyo
global-exclude *.so
zope.exceptions-4.0.6/README.rst 0000644 0000000 0000000 00000000433 12113650724 014474 0 ustar 0000000 0000000 ``zope.exceptions`` README
===========================
This package contains exception interfaces and implementations which are so
general purpose that they don't belong in Zope application-specific packages.
Please see http://docs.zope.org/zope.exceptions/ for the documentation.
zope.exceptions-4.0.6/PKG-INFO 0000644 0000000 0000000 00000014517 12113650750 014111 0 ustar 0000000 0000000 Metadata-Version: 1.1
Name: zope.exceptions
Version: 4.0.6
Summary: Zope Exceptions
Home-page: http://cheeseshop.python.org/pypi/zope.exceptions
Author: Zope Foundation and Contributors
Author-email: zope-dev@zope.org
License: ZPL 2.1
Description: ``zope.exceptions`` README
===========================
This package contains exception interfaces and implementations which are so
general purpose that they don't belong in Zope application-specific packages.
Please see http://docs.zope.org/zope.exceptions/ for the documentation.
``zope.exceptions`` Changelog
=============================
4.0.6 (2013-02-28)
------------------
- Make sure that ``setup.py`` finds all tests. Now tox runs them all as well.
- Fix failing test under Python 3.
- Made buildout work under Python 3 and Buildout 2.
4.0.5 (2012-12-31)
------------------
- Fleshed out PyPI Trove classifiers.
- Fixed a test failure under Python 2.6.
4.0.4 (2012-12-13)
------------------
- Release with a fixed MANIFEST.in (without ``docs/``)
4.0.3 (2012-12-10)
------------------
- Fixed format_exception(..., as_html=True) not to HTML-escape the '
'
it adds to the exception value.
4.0.2 (2012-11-21)
------------------
- Test Python 3.3 support under tox.
4.0.1 (2012-08-20)
------------------
- Fixed optional dependency code for `zope.security` to work under Python 3.3.
4.0.0.1 (2012-05-16)
--------------------
- Fixed rendering of package docs on PyPI.
4.0.0 (2012-05-16)
------------------
- Automated build of Sphinx HTML docs and running doctest snippets via tox.
- Added Sphinx documentation.
- Added support for continuous integration using ``tox`` and ``jenkins``.
- Removed use of '2to3' and associated fixers when installing under Py3k.
The code is now in a "compatible subset" which supports Python 2.6, 2.7,
and 3.2, including PyPy 1.8 (the version compatible with the 2.7 language
spec).
- 100% unit test coverage.
- Dropped explicit support for Python 2.4 / 2.5 / 3.1.
- Added 'setup.py dev' alias (runs ``setup.py develop`` plus installs
``nose`` and ``coverage``).
- Added 'setup.py docs' alias (installs ``Sphinx`` and dependencies).
3.7.1 (2012-03-28)
------------------
- Fix: missed to reverse extractStack entries
3.7.0 (2012-03-28)
------------------
- Added TextExceptionFormatter.extractStack and extract_stack
3.6.2 (2012-03-28)
------------------
- Fallback to traceback.format_tb when the formatter is called recursively.
i.e. Don't let errors in the formatter pass silently.
- Fix deprecated unittest functions: ``assert_`` and ``assertEquals``.
3.6.1 (2010-07-06)
------------------
- Fixed tests to work under Python 2.7.
- PEP8 cleanup and removed obsolete build infrastructure files.
3.6.0 (2010-05-02)
------------------
- Added support to bootstrap on Jython.
- Added Python 3 support.
- The dependency on zope.testing seemed spurious, possibly a rest of a real
dependency that is gone now. I removed it.
3.5.2 (2008-04-30)
------------------
- Updated CHANGES.txt.
3.5.1 (2008-04-28)
------------------
- Reverted changes in 3.5.0.
3.5.0
-----
- Added the capability for exceptions to be formatted line-by-line.
Unfortunately, also introduced a bug cause each line of the exception to be
its own log message.
3.4.0 (2007-10-02)
------------------
- Updated package meta-data.
3.4.0b2 (2007-08-14)
--------------------
- Removed superfluous dependency on ``zope.deprecation``.
3.4.0b1 (2007-07-09)
--------------------
- Corresponds to the version of the ``zope.exceptions`` package shipped as
part of the Zope 3.4.0b1 release.
3.2.0 (2006-01-05)
------------------
- Corresponds to the version of the ``zope.exceptions`` package shipped as part of
the Zope 3.2.0 release.
- Deprecated the ``INotFoundError`` interface and the corresponding
``NotFoundError`` exception class, in favor of "standard" exceptions
``AttributeError``, ``KeyError``). The deprecated items will be removed in
Zope 3.3.
3.0.0 (2004-11-07)
------------------
- Corresponds to the version of the zope.exceptions package shipped as part of
the Zope X3.0.0 release.
Keywords: zope exceptions
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Zope Public License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Framework :: Zope3
zope.exceptions-4.0.6/LICENSE.txt 0000644 0000000 0000000 00000004026 12113650724 014632 0 ustar 0000000 0000000 Zope Public License (ZPL) Version 2.1
A copyright notice accompanies this license document that identifies the
copyright holders.
This license has been certified as open source. It has also been designated as
GPL compatible by the Free Software Foundation (FSF).
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions in source code must retain the accompanying copyright
notice, this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the accompanying copyright
notice, this list of conditions, and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Names of the copyright holders must not be used to endorse or promote
products derived from this software without prior written permission from the
copyright holders.
4. The right to distribute this software or to use it for any purpose does not
give you the right to use Servicemarks (sm) or Trademarks (tm) of the
copyright
holders. Use of them is covered by separate agreement with the copyright
holders.
5. If any files are modified, you must cause the modified files to carry
prominent notices stating that you changed the files and the date of any
change.
Disclaimer
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
zope.exceptions-4.0.6/src/zope.exceptions.egg-info/namespace_packages.txt 0000644 0000000 0000000 00000000005 12113650742 024751 0 ustar 0000000 0000000 zope
zope.exceptions-4.0.6/src/zope.exceptions.egg-info/not-zip-safe 0000644 0000000 0000000 00000000001 12113650724 022651 0 ustar 0000000 0000000
zope.exceptions-4.0.6/src/zope.exceptions.egg-info/SOURCES.txt 0000644 0000000 0000000 00000001404 12113650742 022306 0 ustar 0000000 0000000 CHANGES.rst
COPYRIGHT.txt
LICENSE.txt
MANIFEST.in
README.rst
setup.cfg
setup.py
docs/Makefile
docs/api.rst
docs/conf.py
docs/hacking.rst
docs/index.rst
docs/make.bat
docs/narr.rst
src/zope/__init__.py
src/zope.exceptions.egg-info/PKG-INFO
src/zope.exceptions.egg-info/SOURCES.txt
src/zope.exceptions.egg-info/dependency_links.txt
src/zope.exceptions.egg-info/namespace_packages.txt
src/zope.exceptions.egg-info/not-zip-safe
src/zope.exceptions.egg-info/requires.txt
src/zope.exceptions.egg-info/top_level.txt
src/zope/exceptions/__init__.py
src/zope/exceptions/exceptionformatter.py
src/zope/exceptions/interfaces.py
src/zope/exceptions/log.py
src/zope/exceptions/tests/__init__.py
src/zope/exceptions/tests/test_exceptionformatter.py
src/zope/exceptions/tests/test_log.py zope.exceptions-4.0.6/src/zope.exceptions.egg-info/PKG-INFO 0000644 0000000 0000000 00000014517 12113650742 021530 0 ustar 0000000 0000000 Metadata-Version: 1.1
Name: zope.exceptions
Version: 4.0.6
Summary: Zope Exceptions
Home-page: http://cheeseshop.python.org/pypi/zope.exceptions
Author: Zope Foundation and Contributors
Author-email: zope-dev@zope.org
License: ZPL 2.1
Description: ``zope.exceptions`` README
===========================
This package contains exception interfaces and implementations which are so
general purpose that they don't belong in Zope application-specific packages.
Please see http://docs.zope.org/zope.exceptions/ for the documentation.
``zope.exceptions`` Changelog
=============================
4.0.6 (2013-02-28)
------------------
- Make sure that ``setup.py`` finds all tests. Now tox runs them all as well.
- Fix failing test under Python 3.
- Made buildout work under Python 3 and Buildout 2.
4.0.5 (2012-12-31)
------------------
- Fleshed out PyPI Trove classifiers.
- Fixed a test failure under Python 2.6.
4.0.4 (2012-12-13)
------------------
- Release with a fixed MANIFEST.in (without ``docs/``)
4.0.3 (2012-12-10)
------------------
- Fixed format_exception(..., as_html=True) not to HTML-escape the '
'
it adds to the exception value.
4.0.2 (2012-11-21)
------------------
- Test Python 3.3 support under tox.
4.0.1 (2012-08-20)
------------------
- Fixed optional dependency code for `zope.security` to work under Python 3.3.
4.0.0.1 (2012-05-16)
--------------------
- Fixed rendering of package docs on PyPI.
4.0.0 (2012-05-16)
------------------
- Automated build of Sphinx HTML docs and running doctest snippets via tox.
- Added Sphinx documentation.
- Added support for continuous integration using ``tox`` and ``jenkins``.
- Removed use of '2to3' and associated fixers when installing under Py3k.
The code is now in a "compatible subset" which supports Python 2.6, 2.7,
and 3.2, including PyPy 1.8 (the version compatible with the 2.7 language
spec).
- 100% unit test coverage.
- Dropped explicit support for Python 2.4 / 2.5 / 3.1.
- Added 'setup.py dev' alias (runs ``setup.py develop`` plus installs
``nose`` and ``coverage``).
- Added 'setup.py docs' alias (installs ``Sphinx`` and dependencies).
3.7.1 (2012-03-28)
------------------
- Fix: missed to reverse extractStack entries
3.7.0 (2012-03-28)
------------------
- Added TextExceptionFormatter.extractStack and extract_stack
3.6.2 (2012-03-28)
------------------
- Fallback to traceback.format_tb when the formatter is called recursively.
i.e. Don't let errors in the formatter pass silently.
- Fix deprecated unittest functions: ``assert_`` and ``assertEquals``.
3.6.1 (2010-07-06)
------------------
- Fixed tests to work under Python 2.7.
- PEP8 cleanup and removed obsolete build infrastructure files.
3.6.0 (2010-05-02)
------------------
- Added support to bootstrap on Jython.
- Added Python 3 support.
- The dependency on zope.testing seemed spurious, possibly a rest of a real
dependency that is gone now. I removed it.
3.5.2 (2008-04-30)
------------------
- Updated CHANGES.txt.
3.5.1 (2008-04-28)
------------------
- Reverted changes in 3.5.0.
3.5.0
-----
- Added the capability for exceptions to be formatted line-by-line.
Unfortunately, also introduced a bug cause each line of the exception to be
its own log message.
3.4.0 (2007-10-02)
------------------
- Updated package meta-data.
3.4.0b2 (2007-08-14)
--------------------
- Removed superfluous dependency on ``zope.deprecation``.
3.4.0b1 (2007-07-09)
--------------------
- Corresponds to the version of the ``zope.exceptions`` package shipped as
part of the Zope 3.4.0b1 release.
3.2.0 (2006-01-05)
------------------
- Corresponds to the version of the ``zope.exceptions`` package shipped as part of
the Zope 3.2.0 release.
- Deprecated the ``INotFoundError`` interface and the corresponding
``NotFoundError`` exception class, in favor of "standard" exceptions
``AttributeError``, ``KeyError``). The deprecated items will be removed in
Zope 3.3.
3.0.0 (2004-11-07)
------------------
- Corresponds to the version of the zope.exceptions package shipped as part of
the Zope X3.0.0 release.
Keywords: zope exceptions
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Zope Public License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Framework :: Zope3
zope.exceptions-4.0.6/src/zope.exceptions.egg-info/requires.txt 0000644 0000000 0000000 00000000135 12113650742 023022 0 ustar 0000000 0000000 setuptools
zope.interface
[docs]
Sphinx
repoze.sphinx.autointerface
[testing]
nose
coverage zope.exceptions-4.0.6/src/zope.exceptions.egg-info/top_level.txt 0000644 0000000 0000000 00000000005 12113650742 023150 0 ustar 0000000 0000000 zope
zope.exceptions-4.0.6/src/zope.exceptions.egg-info/dependency_links.txt 0000644 0000000 0000000 00000000001 12113650742 024471 0 ustar 0000000 0000000
zope.exceptions-4.0.6/src/zope/__init__.py 0000644 0000000 0000000 00000000070 12113650724 016657 0 ustar 0000000 0000000 __import__('pkg_resources').declare_namespace(__name__)
zope.exceptions-4.0.6/src/zope/exceptions/interfaces.py 0000644 0000000 0000000 00000006557 12113650724 021444 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
When zope.exceptionformatter generates a traceback, it looks for local
variables named __traceback_info__ or __traceback_supplement__. It
includes the information provided by those local variables in the
traceback.
__traceback_info__ is for arbitrary information.
repr(__traceback_info__) gets dumped to the traceback.
__traceback_supplement__ is more structured. It should be a tuple.
The first item of the tuple is a callable that produces an object that
implements ITracebackSupplement, and the rest of the tuple contains
arguments to pass to the factory. The traceback formatter makes an
effort to clearly present the information provided by the
ITracebackSupplement.
"""
from zope.interface import Interface
from zope.interface import Attribute
from zope.interface import implementer
class IDuplicationError(Interface):
pass
@implementer(IDuplicationError)
class DuplicationError(Exception):
"""A duplicate registration was attempted"""
class IUserError(Interface):
"""User error exceptions
"""
@implementer(IUserError)
class UserError(Exception):
"""User errors
These exceptions should generally be displayed to users unless
they are handled.
"""
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():
"""Optional. Returns a string containing any other useful info.
"""
zope.exceptions-4.0.6/src/zope/exceptions/log.py 0000644 0000000 0000000 00000002475 12113650724 020075 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
"""Log formatter that enhances tracebacks with extra information.
"""
import logging
try:
from StringIO import StringIO
except ImportError: #pragma NO COVER Python3
from io import StringIO
from zope.exceptions.exceptionformatter import print_exception
class Formatter(logging.Formatter):
def formatException(self, ei):
"""Format and return the specified exception information as a string.
Uses zope.exceptions.exceptionformatter to generate the traceback.
"""
sio = StringIO()
print_exception(ei[0], ei[1], ei[2], file=sio, with_filenames=True)
s = sio.getvalue()
if s.endswith("\n"):
s = s[:-1]
return s
zope.exceptions-4.0.6/src/zope/exceptions/__init__.py 0000644 0000000 0000000 00000003353 12113650724 021047 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
"""
from zope.exceptions.interfaces import DuplicationError
from zope.exceptions.interfaces import IDuplicationError
from zope.exceptions.interfaces import UserError
from zope.exceptions.interfaces import IUserError
from zope.exceptions.exceptionformatter import format_exception
from zope.exceptions.exceptionformatter import print_exception
from zope.exceptions.exceptionformatter import extract_stack
# avoid dependency on zope.security:
try:
import zope.security
except ImportError as v: #pragma NO COVER
# "ImportError: No module named security"
if 'security' not in str(v):
raise
else: #pragma NO COVER
from zope.security.interfaces import IUnauthorized
from zope.security.interfaces import Unauthorized
from zope.security.interfaces import IForbidden
from zope.security.interfaces import IForbiddenAttribute
from zope.security.interfaces import Forbidden
from zope.security.interfaces import ForbiddenAttribute
zope.exceptions-4.0.6/src/zope/exceptions/exceptionformatter.py 0000644 0000000 0000000 00000022521 12113650724 023230 0 ustar 0000000 0000000 ##############################################################################
#
# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
"""
import sys
import cgi
import linecache
import traceback
DEBUG_EXCEPTION_FORMATTER = 1
class TextExceptionFormatter(object):
line_sep = '\n'
def __init__(self, limit=None, with_filenames=False):
self.limit = limit
self.with_filenames = with_filenames
def escape(self, s):
return s
def getPrefix(self):
return 'Traceback (most recent call last):'
def getLimit(self):
limit = self.limit
if limit is None:
limit = getattr(sys, 'tracebacklimit', 200)
return limit
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(self.formatSupplementInfo(extra))
except: #pragma NO COVER
if DEBUG_EXCEPTION_FORMATTER:
traceback.print_exc()
# else just swallow the exception.
return result
def formatSupplementInfo(self, info):
return self.escape(info)
def formatTracebackInfo(self, tbi):
return self.formatSupplementLine('__traceback_info__: %s' % (tbi, ))
def formatLine(self, tb=None, f=None):
if tb and not f:
f = tb.tb_frame
lineno = tb.tb_lineno
elif not tb and f:
lineno = f.f_lineno
else:
raise ValueError("Pass exactly one of tb or f")
co = f.f_code
filename = co.co_filename
name = co.co_name
locals = f.f_locals # XXX shadowing normal builtins deliberately?
globals = f.f_globals # XXX shadowing normal builtins deliberately?
if self.with_filenames:
s = ' File "%s", line %d' % (filename, lineno)
else:
modname = globals.get('__name__', filename)
s = ' Module %s, line %d' % (modname, lineno)
s = s + ', in %s' % name
result = []
result.append(self.escape(s))
# Append the source line, if available
line = linecache.getline(filename, lineno)
if line:
result.append(" " + self.escape(line.strip()))
# 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: #pragma NO COVER
if DEBUG_EXCEPTION_FORMATTER:
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: #pragma NO COVER
if DEBUG_EXCEPTION_FORMATTER:
traceback.print_exc()
# else just swallow the exception.
return self.line_sep.join(result)
def formatExceptionOnly(self, etype, value):
result = ''.join(traceback.format_exception_only(etype, value))
return result
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, '
'trying traceback.format_tb)\n')
result.extend(traceback.format_tb(tb))
break
line = self.formatLine(tb=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
def extractStack(self, f=None):
if f is None:
try:
raise ZeroDivisionError
except ZeroDivisionError:
f = sys.exc_info()[2].tb_frame.f_back
# The next line provides a way to detect recursion.
__exception_formatter__ = 1
result = []
limit = self.getLimit()
n = 0
while f is not None and (limit is None or n < limit):
line = self.formatLine(f=f)
result.append(line + '\n')
f = f.f_back
n = n + 1
result.reverse()
return result
class HTMLExceptionFormatter(TextExceptionFormatter):
line_sep = '
\r\n'
def escape(self, s):
return cgi.escape(s)
def getPrefix(self):
return '
Traceback (most recent call last):
\r\n%s
' % self.escape(exc_line) return line.replace('\n', self.line_sep) def format_exception(t, v, tb, limit=None, as_html=False, with_filenames=False): """Format a stack trace and the exception information. Similar to 'traceback.format_exception', but adds supplemental information to the traceback and accepts two options, 'as_html' and 'with_filenames'. """ if as_html: fmt = HTMLExceptionFormatter(limit, with_filenames) else: fmt = TextExceptionFormatter(limit, with_filenames) return fmt.formatException(t, v, tb) def print_exception(t, v, tb, limit=None, file=None, as_html=False, with_filenames=True): """Print exception up to 'limit' stack trace entries from 'tb' to 'file'. Similar to 'traceback.print_exception', but adds supplemental information to the traceback and accepts two options, 'as_html' and 'with_filenames'. """ if file is None: #pragma NO COVER file = sys.stderr lines = format_exception(t, v, tb, limit, as_html, with_filenames) for line in lines: file.write(line) def extract_stack(f, limit=None, as_html=False, with_filenames=True): """Format a stack trace and the exception information. Similar to 'traceback.format_exception', but adds supplemental information to the traceback and accepts two options, 'as_html' and 'with_filenames'. """ if as_html: fmt = HTMLExceptionFormatter(limit, with_filenames) else: fmt = TextExceptionFormatter(limit, with_filenames) return fmt.extractStack(f) zope.exceptions-4.0.6/src/zope/exceptions/tests/test_log.py 0000644 0000000 0000000 00000003641 12113650724 022272 0 ustar 0000000 0000000 ############################################################################## # # Copyright (c) 2012 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (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. # ############################################################################## """log.Formatter tests. """ import unittest class FormatterTests(unittest.TestCase): def _getTargetClass(self): from zope.exceptions.log import Formatter return Formatter def _makeOne(self, *args, **kw): return self._getTargetClass()(*args, **kw) def test_simple_exception(self): import traceback tb = DummyTB() tb.tb_frame = DummyFrame() exc = ValueError('testing') fmt = self._makeOne() result = fmt.formatException((ValueError, exc, tb)) lines = result.splitlines() self.assertEqual(len(lines), 3) self.assertEqual(lines[0], 'Traceback (most recent call last):') self.assertEqual(lines[1], ' File "dummy/filename.py", line 14, ' 'in dummy_function') self.assertEqual(lines[2], traceback.format_exception_only( ValueError, exc)[0][:-1]) #trailing \n class DummyTB(object): tb_lineno = 14 tb_next = None class DummyFrame(object): f_lineno = 137 f_back = None def __init__(self): self.f_locals = {} self.f_globals = {} self.f_code = DummyCode() class DummyCode(object): co_filename = 'dummy/filename.py' co_name = 'dummy_function' zope.exceptions-4.0.6/src/zope/exceptions/tests/test_exceptionformatter.py 0000644 0000000 0000000 00000072657 12113650724 025450 0 ustar 0000000 0000000 ############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (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. # ############################################################################## """ExceptionFormatter tests. """ import unittest import doctest import sys class TextExceptionFormatterTests(unittest.TestCase): def _getTargetClass(self): from zope.exceptions.exceptionformatter import TextExceptionFormatter return TextExceptionFormatter def _makeOne(self, *args, **kw): return self._getTargetClass()(*args, **kw) def test_ctor_defaults(self): fmt = self._makeOne() self.assertEqual(fmt.line_sep, '\n') self.assertEqual(fmt.limit, None) self.assertEqual(fmt.with_filenames, False) def test_ctor_explicit(self): fmt = self._makeOne(limit=20, with_filenames=True) self.assertEqual(fmt.line_sep, '\n') self.assertEqual(fmt.limit, 20) self.assertEqual(fmt.with_filenames, True) def test_escape(self): fmt = self._makeOne() self.assertEqual(fmt.escape('XXX'), 'XXX') def test_getPrefix(self): fmt = self._makeOne() self.assertEqual(fmt.getPrefix(), 'Traceback (most recent call last):') def test_getLimit_default(self): fmt = self._makeOne() self.assertEqual(fmt.getLimit(), 200) def test_getLimit_sys_has_limit(self): import sys fmt = self._makeOne() with _Monkey(sys, tracebacklimit=15): self.assertEqual(fmt.getLimit(), 15) def test_getLimit_explicit(self): fmt = self._makeOne(limit=10) self.assertEqual(fmt.getLimit(), 10) def test_formatSupplementLine(self): fmt = self._makeOne() self.assertEqual(fmt.formatSupplementLine('XXX'), ' - XXX') def test_formatSourceURL(self): fmt = self._makeOne() self.assertEqual(fmt.formatSourceURL('http://example.com/'), [' - http://example.com/']) def test_formatSupplement_no_info(self): fmt = self._makeOne() supplement = DummySupplement() self.assertEqual(fmt.formatSupplement(supplement, tb=None), []) def test_formatSupplement_w_source_url(self): fmt = self._makeOne() supplement = DummySupplement() supplement.source_url = 'http://example.com/' self.assertEqual(fmt.formatSupplement(supplement, tb=None), [' - http://example.com/']) def test_formatSupplement_w_line_as_marker(self): fmt = self._makeOne() supplement = DummySupplement() supplement.line = -1 tb = DummyTB() self.assertEqual(fmt.formatSupplement(supplement, tb=tb), [' - Line 14']) def test_formatSupplement_w_line_no_column(self): fmt = self._makeOne() supplement = DummySupplement() supplement.line = 23 self.assertEqual(fmt.formatSupplement(supplement, tb=None), [' - Line 23']) def test_formatSupplement_w_column_no_line(self): fmt = self._makeOne() supplement = DummySupplement() supplement.column = 47 self.assertEqual(fmt.formatSupplement(supplement, tb=None), [' - Column 47']) def test_formatSupplement_w_line_and_column(self): fmt = self._makeOne() supplement = DummySupplement() supplement.line = 23 supplement.column = 47 self.assertEqual(fmt.formatSupplement(supplement, tb=None), [' - Line 23, Column 47']) def test_formatSupplement_w_expression(self): fmt = self._makeOne() supplement = DummySupplement() supplement.expression = 'a*x^2 + b*x + c' self.assertEqual(fmt.formatSupplement(supplement, tb=None), [' - Expression: a*x^2 + b*x + c']) def test_formatSupplement_w_warnings(self): fmt = self._makeOne() supplement = DummySupplement() supplement.warnings = ['Beware the ides of March!', 'You\'re gonna get wasted.', ] self.assertEqual(fmt.formatSupplement(supplement, tb=None), [' - Warning: Beware the ides of March!', ' - Warning: You\'re gonna get wasted.', ]) def test_formatSupplement_w_getInfo_empty(self): fmt = self._makeOne() supplement = DummySupplement() self.assertEqual(fmt.formatSupplement(supplement, tb=None), []) def test_formatSupplement_w_getInfo_text(self): INFO = 'Some days\nI wish I had stayed in bed.' fmt = self._makeOne() supplement = DummySupplement(INFO) self.assertEqual(fmt.formatSupplement(supplement, tb=None), [INFO]) def test_formatSupplementInfo(self): INFO = 'Some days\nI wish I had stayed in bed.' fmt = self._makeOne() self.assertEqual(fmt.formatSupplementInfo(INFO), INFO) def test_formatTracebackInfo(self): fmt = self._makeOne() self.assertEqual(fmt.formatTracebackInfo('XYZZY'), ' - __traceback_info__: XYZZY') def test_formatLine_no_tb_no_f(self): fmt = self._makeOne() self.assertRaises(ValueError, fmt.formatLine, None, None) def test_formatLine_w_tb_and_f(self): fmt = self._makeOne() tb = DummyTB() f = DummyFrame() self.assertRaises(ValueError, fmt.formatLine, tb, f) def test_formatLine_w_tb_bogus_linecache_w_filenames(self): fmt = self._makeOne(with_filenames=True) tb = DummyTB() tb.tb_frame = f = DummyFrame() lines = fmt.formatLine(tb).splitlines() self.assertEqual(len(lines), 1) self.assertEqual(lines[0], ' File "%s", line %d, in %s' % (f.f_code.co_filename, tb.tb_lineno, f.f_code.co_name, )) def test_formatLine_w_f_bogus_linecache_w_filenames(self): fmt = self._makeOne(with_filenames=True) f = DummyFrame() lines = fmt.formatLine(f=f).splitlines() self.assertEqual(len(lines), 1) self.assertEqual(lines[0], ' File "%s", line %d, in %s' % (f.f_code.co_filename, f.f_lineno, f.f_code.co_name, )) def test_formatLine_w_tb_bogus_linecache_wo_filenames(self): fmt = self._makeOne(with_filenames=False) tb = DummyTB() tb.tb_frame = f = DummyFrame() f.f_globals['__name__'] = 'dummy.filename' lines = fmt.formatLine(tb).splitlines() self.assertEqual(len(lines), 1) self.assertEqual(lines[0], ' Module dummy.filename, line %d, in %s' % (tb.tb_lineno, f.f_code.co_name, )) def test_formatLine_w_f_real_linecache_w_filenames(self): import sys fmt = self._makeOne(with_filenames=True) f = sys._getframe(); lineno = f.f_lineno result = fmt.formatLine(f=f) lines = result.splitlines() self.assertEqual(len(lines), 2) self.assertEqual(lines[0], ' File "%s", line %d, in %s' % (f.f_code.co_filename, lineno + 1, f.f_code.co_name, )) self.assertEqual(lines[1], ' result = fmt.formatLine(f=f)') def test_formatLine_w_supplement_in_locals(self): INFO_L = 'I wish I had stayed in bed.' INFO_G = 'I would rather soak my head.' fmt = self._makeOne(with_filenames=False) tb = DummyTB() tb.tb_frame = f = DummyFrame() f.f_globals['__name__'] = 'dummy.filename' f.f_locals['__traceback_supplement__'] = (DummySupplement, INFO_L) f.f_globals['__traceback_supplement__'] = (DummySupplement, INFO_G) lines = fmt.formatLine(tb).splitlines() self.assertEqual(len(lines), 2) self.assertEqual(lines[1], INFO_L) def test_formatLine_w_supplement_in_globals(self): INFO_G = 'I would rather soak my head.' fmt = self._makeOne(with_filenames=False) tb = DummyTB() tb.tb_frame = f = DummyFrame() f.f_globals['__name__'] = 'dummy.filename' f.f_globals['__traceback_supplement__'] = (DummySupplement, INFO_G) lines = fmt.formatLine(tb).splitlines() self.assertEqual(len(lines), 2) self.assertEqual(lines[1], INFO_G) def test_formatLine_w_traceback_info(self): INFO_T = 'I would rather soak my head.' fmt = self._makeOne(with_filenames=False) tb = DummyTB() tb.tb_frame = f = DummyFrame() f.f_globals['__name__'] = 'dummy.filename' f.f_locals['__traceback_info__'] = INFO_T lines = fmt.formatLine(tb).splitlines() self.assertEqual(len(lines), 2) self.assertEqual(lines[1], ' - __traceback_info__: %s' % INFO_T) def test_formatExceptionOnly(self): import traceback fmt = self._makeOne() err = ValueError('testing') self.assertEqual(fmt.formatExceptionOnly(ValueError, err), ''.join( traceback.format_exception_only(ValueError, err))) def test_formatLastLine(self): fmt = self._makeOne() self.assertEqual(fmt.formatLastLine('XXX'), 'XXX') def test_formatException_empty_tb_stack(self): import traceback fmt = self._makeOne() err = ValueError('testing') lines = fmt.formatException(ValueError, err, None) self.assertEqual(len(lines), 2) self.assertEqual(lines[0], 'Traceback (most recent call last):\n') self.assertEqual(lines[1], ''.join( traceback.format_exception_only(ValueError, err))) def test_formatException_non_empty_tb_stack(self): import traceback fmt = self._makeOne() err = ValueError('testing') tb = DummyTB() tb.tb_frame = DummyFrame() lines = fmt.formatException(ValueError, err, tb) self.assertEqual(len(lines), 3) self.assertEqual(lines[0], 'Traceback (most recent call last):\n') self.assertEqual(lines[1], ' Module dummy/filename.py, line 14, ' 'in dummy_function\n') self.assertEqual(lines[2], ''.join( traceback.format_exception_only(ValueError, err))) def test_formatException_deep_tb_stack_with_limit(self): import traceback fmt = self._makeOne(limit=1) err = ValueError('testing') tb0 = DummyTB() tb0.tb_lineno = 27 tb0.tb_frame = DummyFrame() tb = DummyTB() tb.tb_frame = DummyFrame() tb.tb_next = tb0 lines = fmt.formatException(ValueError, err, tb) self.assertEqual(len(lines), 3) self.assertEqual(lines[0], 'Traceback (most recent call last):\n') self.assertEqual(lines[1], ' Module dummy/filename.py, line 14, ' 'in dummy_function\n') self.assertEqual(lines[2], ''.join( traceback.format_exception_only(ValueError, err))) def test_formatException_recursion_in_tb_stack(self): import traceback fmt = self._makeOne() err = ValueError('testing') tb_recurse = DummyTB() tb_recurse.tb_lineno = 27 r_f = tb_recurse.tb_frame = DummyFrame() r_f.f_lineno = 27 r_f.f_locals['__exception_formatter__'] = 1 tb = DummyTB() tb.tb_frame = DummyFrame() tb.tb_next = tb_recurse lines = fmt.formatException(ValueError, err, tb) self.assertEqual(len(lines), 5) self.assertEqual(lines[0], 'Traceback (most recent call last):\n') self.assertEqual(lines[1], ' Module dummy/filename.py, line 14, ' 'in dummy_function\n') self.assertEqual(lines[2], '(Recursive formatException() stopped, ' 'trying traceback.format_tb)\n') self.assertEqual(lines[3], ' File "dummy/filename.py", line 27, ' 'in dummy_function\n') self.assertEqual(lines[4], ''.join( traceback.format_exception_only(ValueError, err))) def test_extractStack_wo_frame(self): import sys fmt = self._makeOne(limit=1) f = sys._getframe(); lineno = f.f_lineno lines = fmt.extractStack() self.assertEqual(len(lines), 1) self.assertEqual(lines[0], ' Module ' 'zope.exceptions.tests.test_exceptionformatter, ' 'line %d, in test_extractStack_wo_frame\n' ' lines = fmt.extractStack()\n' % (lineno + 1)) def test_extractStack_w_single_frame(self): fmt = self._makeOne() f = DummyFrame() lines = fmt.extractStack(f) self.assertEqual(len(lines), 1) self.assertEqual(lines[0], ' Module dummy/filename.py, line 137, ' 'in dummy_function\n') def test_extractStack_w_multiple_frames_and_limit(self): fmt = self._makeOne(limit=1) f0 = DummyFrame() f0.f_lineno = 213 f = DummyFrame() f.f_back = f0 lines = fmt.extractStack(f) self.assertEqual(len(lines), 1) self.assertEqual(lines[0], ' Module dummy/filename.py, line 137, ' 'in dummy_function\n') def test_extractStack_w_recursive_frames_and_limit(self): fmt = self._makeOne(limit=1) f = DummyFrame() f.f_back = f lines = fmt.extractStack(f) self.assertEqual(len(lines), 1) self.assertEqual(lines[0], ' Module dummy/filename.py, line 137, ' 'in dummy_function\n') class HTMLExceptionFormatterTests(unittest.TestCase): def _getTargetClass(self): from zope.exceptions.exceptionformatter import HTMLExceptionFormatter return HTMLExceptionFormatter def _makeOne(self, *args, **kw): return self._getTargetClass()(*args, **kw) def test_ctor_defaults(self): fmt = self._makeOne() self.assertEqual(fmt.line_sep, 'Traceback (most recent call last):
\r\nXXX
') class Test_format_exception(unittest.TestCase): def _callFUT(self, as_html=False): import sys from zope.exceptions.exceptionformatter import format_exception t, v, b = sys.exc_info() try: return ''.join(format_exception(t, v, b, as_html=as_html)) finally: del b def test_basic_names_text(self): try: raise ExceptionForTesting except ExceptionForTesting: s = self._callFUT(False) # The traceback should include the name of this function. self.assertTrue(s.find('test_basic_names_text') >= 0) # The traceback should include the name of the exception. self.assertTrue(s.find('ExceptionForTesting') >= 0) def test_basic_names_html(self): try: raise ExceptionForTesting except ExceptionForTesting: s = self._callFUT(True) # The traceback should include the name of this function. self.assertTrue(s.find('test_basic_names_html') >= 0) # The traceback should include the name of the exception. self.assertTrue(s.find('ExceptionForTesting') >= 0) def test_traceback_info_text(self): try: __traceback_info__ = "Adam & Eve" raise ExceptionForTesting except ExceptionForTesting: s = self._callFUT(False) self.assertTrue(s.find('Adam & Eve') >= 0, s) def test_traceback_info_html(self): try: __traceback_info__ = "Adam & Eve" raise ExceptionForTesting except ExceptionForTesting: s = self._callFUT(True) # Be sure quoting is happening. self.assertTrue(s.find('Adam & Eve') >= 0, s) def test_traceback_info_is_tuple(self): try: __traceback_info__ = ("Adam", "Eve") raise ExceptionForTesting except ExceptionForTesting: s = self._callFUT(False) self.assertTrue(s.find('Adam') >= 0, s) self.assertTrue(s.find('Eve') >= 0, s) def test_supplement_text(self, as_html=0): try: __traceback_supplement__ = (TestingTracebackSupplement, "You're one in a million") raise ExceptionForTesting except ExceptionForTesting: s = self._callFUT(as_html) # The source URL self.assertTrue(s.find('/somepath') >= 0, s) # The line number self.assertTrue(s.find('634') >= 0, s) # The column number self.assertTrue(s.find('57') >= 0, s) # The expression self.assertTrue(s.find("You're one in a million") >= 0, s) # The warning self.assertTrue(s.find("Repent, for the end is nigh") >= 0, s) def test_supplement_html(self): try: __traceback_supplement__ = (TestingTracebackSupplement, "You're one in a million") raise ExceptionForTesting except ExceptionForTesting: s = self._callFUT(True) # The source URL self.assertTrue(s.find('/somepath') >= 0, s) # The line number self.assertTrue(s.find('634') >= 0, s) # The column number self.assertTrue(s.find('57') >= 0, s) # The expression self.assertTrue(s.find("You're one in a million") >= 0, s) # The warning self.assertTrue(s.find("Repent, for the end is nigh") >= 0, s) def test_multiple_levels(self): # Ensure many levels are shown in a traceback. HOW_MANY = 10 def f(n): """Produces a (n + 1)-level traceback.""" __traceback_info__ = 'level%d' % n if n > 0: f(n - 1) else: raise ExceptionForTesting try: f(HOW_MANY) except ExceptionForTesting: s = self._callFUT(False) for n in range(HOW_MANY+1): self.assertTrue(s.find('level%d' % n) >= 0, s) def test_quote_last_line(self): class C(object): pass try: raise TypeError(C()) except: s = self._callFUT(True) self.assertTrue(s.find('<') >= 0, s) self.assertTrue(s.find('>') >= 0, s) def test_multiline_exception(self): try: exec('syntax error\n') except Exception: s = self._callFUT(False) lines = s.splitlines()[-3:] self.assertEqual(lines[0], ' syntax error') self.assertTrue(lines[1].endswith(' ^')) #PyPy has a shorter prefix self.assertEqual(lines[2], 'SyntaxError: invalid syntax') def test_recursion_failure(self): import sys from zope.exceptions.exceptionformatter import TextExceptionFormatter class FormatterException(Exception): pass class FailingFormatter(TextExceptionFormatter): def formatLine(self, tb=None, f=None): raise FormatterException("Formatter failed") fmt = FailingFormatter() try: raise ExceptionForTesting except ExceptionForTesting: try: fmt.formatException(*sys.exc_info()) except FormatterException: s = self._callFUT(False) # Recursion was detected self.assertTrue('(Recursive formatException() stopped, ' 'trying traceback.format_tb)' in s, s) # and we fellback to the stdlib rather than hid the real error self.assertEqual(s.splitlines()[-2], ' raise FormatterException("Formatter failed")') self.assertTrue('FormatterException: Formatter failed' in s.splitlines()[-1]) class Test_print_exception(unittest.TestCase): def _callFUT(self, as_html=False): try: from StringIO import StringIO except ImportError: from io import StringIO buf = StringIO() import sys from zope.exceptions.exceptionformatter import print_exception t, v, b = sys.exc_info() try: print_exception(t, v, b, file=buf, as_html=as_html) return buf.getvalue() finally: del b def test_basic_names_text(self): try: raise ExceptionForTesting except ExceptionForTesting: s = self._callFUT(False) # The traceback should include the name of this function. self.assertTrue(s.find('test_basic_names_text') >= 0) # The traceback should include the name of the exception. self.assertTrue(s.find('ExceptionForTesting') >= 0) def test_basic_names_html(self): try: raise ExceptionForTesting except ExceptionForTesting: s = self._callFUT(True) # The traceback should include the name of this function. self.assertTrue(s.find('test_basic_names_html') >= 0) # The traceback should include the name of the exception. self.assertTrue(s.find('ExceptionForTesting') >= 0) class Test_extract_stack(unittest.TestCase): def _callFUT(self, as_html=False): import sys from zope.exceptions.exceptionformatter import extract_stack f = sys.exc_info()[2].tb_frame try: return ''.join(extract_stack(f, as_html=as_html)) finally: del f def test_basic_names_as_text(self, as_html=0): try: raise ExceptionForTesting except ExceptionForTesting: s = self._callFUT(False) # The stack trace should include the name of this function. self.assertTrue(s.find('test_basic_names_as_text') >= 0) def test_basic_names_as_html(self): try: raise ExceptionForTesting except ExceptionForTesting: s = self._callFUT(True) # The stack trace should include the name of this function. self.assertTrue(s.find('test_basic_names_as_html') >= 0) def test_traceback_info_text(self): try: __traceback_info__ = "Adam & Eve" raise ExceptionForTesting except ExceptionForTesting: s = self._callFUT(False) self.assertTrue(s.find('Adam & Eve') >= 0, s) def test_traceback_info_html(self): try: __traceback_info__ = "Adam & Eve" raise ExceptionForTesting except ExceptionForTesting: s = self._callFUT(True) self.assertTrue(s.find('Adam & Eve') >= 0, s) def test_traceback_supplement_text(self): try: __traceback_supplement__ = (TestingTracebackSupplement, "You're one in a million") raise ExceptionForTesting except ExceptionForTesting: s = self._callFUT(False) # The source URL self.assertTrue(s.find('/somepath') >= 0, s) # The line number self.assertTrue(s.find('634') >= 0, s) # The column number self.assertTrue(s.find('57') >= 0, s) # The expression self.assertTrue(s.find("You're one in a million") >= 0, s) # The warning self.assertTrue(s.find("Repent, for the end is nigh") >= 0, s) def test_traceback_supplement_html(self): try: __traceback_supplement__ = (TestingTracebackSupplement, "You're one in a million") raise ExceptionForTesting except ExceptionForTesting: s = self._callFUT(True) # The source URL self.assertTrue(s.find('/somepath') >= 0, s) # The line number self.assertTrue(s.find('634') >= 0, s) # The column number self.assertTrue(s.find('57') >= 0, s) # The expression self.assertTrue(s.find("You're one in a million") >= 0, s) # The warning self.assertTrue(s.find("Repent, for the end is nigh") >= 0, s) class ExceptionForTesting (Exception): pass class TestingTracebackSupplement(object): source_url = '/somepath' line = 634 column = 57 warnings = ['Repent, for the end is nigh'] def __init__(self, expression): self.expression = expression class DummySupplement(object): def __init__(self, info=''): self._info = info def getInfo(self): return self._info class DummyTB(object): tb_lineno = 14 tb_next = None class DummyFrame(object): f_lineno = 137 f_back = None def __init__(self): self.f_locals = {} self.f_globals = {} self.f_code = DummyCode() class DummyCode(object): co_filename = 'dummy/filename.py' co_name = 'dummy_function' class _Monkey(object): # context-manager for replacing module names in the scope of a test. def __init__(self, module, **kw): self.module = module self.to_restore = dict([(key, getattr(module, key, self)) for key in kw]) for key, value in kw.items(): setattr(module, key, value) def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): for key, value in self.to_restore.items(): if value is not self: setattr(self.module, key, value) else: delattr(self.module, key) def doctest_format_exception_as_html(): """Test for format_exception (as_html=True) >>> from zope.exceptions.exceptionformatter import format_exception >>> try: ... exec('import 2 + 2') ... except: ... print(''.join(format_exception(*sys.exc_info(), as_html=True)))Traceback (most recent call last):
File "<string>", line 1
import 2 + 2
^
SyntaxError: invalid syntax