##// END OF EJS Templates
Merging -r 1196 from lp:ipython....
Merging -r 1196 from lp:ipython. A couple of issues came up: * Some tests in testing and frontend rely on twisted, but are being tested with nose. This is bad! We currently have hackish logic in iptest to skip these if twisted is not installed, but if it is we are testing them with nose! * Some modules (engineservice, kernel/error, newserialized) have nose skip logic even though they should never be tested with nose. * When trial is run on testStrictDict we get an uncaught error. testStrictDict ... ERROR: An unexpected error occurred while tokenizing input The following traceback may be corrupted or invalid The error message is: ('EOF in multi-line statement', (37, 0))

File last commit:

r2133:fcf58986
r2150:b44b6920 merge
Show More
error.py
205 lines | 5.6 KiB | text/x-python | PythonLexer
# encoding: utf-8
"""Classes and functions for kernel related errors and exceptions."""
__docformat__ = "restructuredtext en"
# Tell nose to skip this module
__test__ = {}
#-------------------------------------------------------------------------------
# Copyright (C) 2008 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# Imports
#-------------------------------------------------------------------------------
from twisted.python import failure
from IPython.kernel.core import error
#-------------------------------------------------------------------------------
# Error classes
#-------------------------------------------------------------------------------
class KernelError(error.IPythonError):
pass
class NotDefined(KernelError):
def __init__(self, name):
self.name = name
self.args = (name,)
def __repr__(self):
return '<NotDefined: %s>' % self.name
__str__ = __repr__
class QueueCleared(KernelError):
pass
class IdInUse(KernelError):
pass
class ProtocolError(KernelError):
pass
class ConnectionError(KernelError):
pass
class InvalidEngineID(KernelError):
pass
class NoEnginesRegistered(KernelError):
pass
class InvalidClientID(KernelError):
pass
class InvalidDeferredID(KernelError):
pass
class SerializationError(KernelError):
pass
class MessageSizeError(KernelError):
pass
class PBMessageSizeError(MessageSizeError):
pass
class ResultNotCompleted(KernelError):
pass
class ResultAlreadyRetrieved(KernelError):
pass
class ClientError(KernelError):
pass
class TaskAborted(KernelError):
pass
class TaskTimeout(KernelError):
pass
class NotAPendingResult(KernelError):
pass
class UnpickleableException(KernelError):
pass
class AbortedPendingDeferredError(KernelError):
pass
class InvalidProperty(KernelError):
pass
class MissingBlockArgument(KernelError):
pass
class StopLocalExecution(KernelError):
pass
class SecurityError(KernelError):
pass
class FileTimeoutError(KernelError):
pass
class TaskRejectError(KernelError):
"""Exception to raise when a task should be rejected by an engine.
This exception can be used to allow a task running on an engine to test
if the engine (or the user's namespace on the engine) has the needed
task dependencies. If not, the task should raise this exception. For
the task to be retried on another engine, the task should be created
with the `retries` argument > 1.
The advantage of this approach over our older properties system is that
tasks have full access to the user's namespace on the engines and the
properties don't have to be managed or tested by the controller.
"""
class CompositeError(KernelError):
def __init__(self, message, elist):
Exception.__init__(self, *(message, elist))
self.message = message
self.elist = elist
def _get_engine_str(self, ev):
try:
ei = ev._ipython_engine_info
except AttributeError:
return '[Engine Exception]'
else:
return '[%i:%s]: ' % (ei['engineid'], ei['method'])
def _get_traceback(self, ev):
try:
tb = ev._ipython_traceback_text
except AttributeError:
return 'No traceback available'
else:
return tb
def __str__(self):
s = str(self.message)
for et, ev, etb in self.elist:
engine_str = self._get_engine_str(ev)
s = s + '\n' + engine_str + str(et.__name__) + ': ' + str(ev)
return s
def print_tracebacks(self, excid=None):
if excid is None:
for (et,ev,etb) in self.elist:
print self._get_engine_str(ev)
print self._get_traceback(ev)
print
else:
try:
et,ev,etb = self.elist[excid]
except:
raise IndexError("an exception with index %i does not exist"%excid)
else:
print self._get_engine_str(ev)
print self._get_traceback(ev)
def raise_exception(self, excid=0):
try:
et,ev,etb = self.elist[excid]
except:
raise IndexError("an exception with index %i does not exist"%excid)
else:
raise et, ev, etb
def collect_exceptions(rlist, method):
elist = []
for r in rlist:
if isinstance(r, failure.Failure):
r.cleanFailure()
et, ev, etb = r.type, r.value, r.tb
# Sometimes we could have CompositeError in our list. Just take
# the errors out of them and put them in our new list. This
# has the effect of flattening lists of CompositeErrors into one
# CompositeError
if et==CompositeError:
for e in ev.elist:
elist.append(e)
else:
elist.append((et, ev, etb))
if len(elist)==0:
return rlist
else:
msg = "one or more exceptions from call to method: %s" % (method)
# This silliness is needed so the debugger has access to the exception
# instance (e in this case)
try:
raise CompositeError(msg, elist)
except CompositeError, e:
raise e