cython-devel
changeset 1598:7110f62bc826
provide more context on compiler crashes during transforms
| author | Stefan Behnel <scoder@users.berlios.de> |
|---|---|
| date | Sat Jan 10 15:32:22 2009 +0100 (3 years ago) |
| parents | f94a618ed62d |
| children | 3bf246dd7f44 |
| files | Cython/Compiler/Errors.py Cython/Compiler/Visitor.py |
line diff
1.1 --- a/Cython/Compiler/Errors.py Sat Jan 10 12:23:46 2009 +0100
1.2 +++ b/Cython/Compiler/Errors.py Sat Jan 10 15:32:22 2009 +0100
1.3 @@ -63,7 +63,28 @@
1.4 def __init__(self, message):
1.5 Exception.__init__(self, "Internal compiler error: %s"
1.6 % message)
1.7 -
1.8 +
1.9 +
1.10 +class CompilerCrash(CompileError):
1.11 + # raised when an unexpected exception occurs in a transform
1.12 + def __init__(self, pos, context, message, cause, stacktrace=None):
1.13 + if message:
1.14 + message = u'\n' + message
1.15 + else:
1.16 + message = u'\n'
1.17 + if context:
1.18 + message = "Compiler crash in " + context + message
1.19 + if stacktrace:
1.20 + import traceback, sys
1.21 + message += (
1.22 + u'\n\nCompiler crash traceback up to this point:\n' +
1.23 + u''.join(traceback.format_tb(stacktrace)))
1.24 + if cause:
1.25 + if not stacktrace:
1.26 + message += u'\n'
1.27 + message += u'%s: %s' % (cause.__class__.__name__, cause)
1.28 + CompileError.__init__(self, pos, message)
1.29 +
1.30
1.31 listing_file = None
1.32 num_errors = 0
2.1 --- a/Cython/Compiler/Visitor.py Sat Jan 10 12:23:46 2009 +0100
2.2 +++ b/Cython/Compiler/Visitor.py Sat Jan 10 15:32:22 2009 +0100
2.3 @@ -6,6 +6,7 @@
2.4 import Nodes
2.5 import ExprNodes
2.6 import Naming
2.7 +import Errors
2.8 from StringEncoding import EncodedString
2.9
2.10 class BasicVisitor(object):
2.11 @@ -91,9 +92,58 @@
2.12 super(TreeVisitor, self).__init__()
2.13 self.access_path = []
2.14
2.15 + def dump_node(self, node, indent=0):
2.16 + ignored = list(node.child_attrs) + [u'child_attrs', u'pos']
2.17 + values = []
2.18 + pos = node.pos
2.19 + if pos:
2.20 + source = pos[0]
2.21 + if source:
2.22 + import os.path
2.23 + source = os.path.basename(source.get_description())
2.24 + values.append(u'%s:%s:%s' % (source, pos[1], pos[2]))
2.25 + attribute_names = dir(node)
2.26 + attribute_names.sort()
2.27 + for attr in attribute_names:
2.28 + if attr in ignored:
2.29 + continue
2.30 + if attr.startswith(u'_') or attr.endswith(u'_'):
2.31 + continue
2.32 + value = getattr(node, attr, None)
2.33 + if value is None:
2.34 + continue
2.35 + elif isinstance(value, list):
2.36 + value = u'[...]'
2.37 + elif not isinstance(value, (str, unicode, long, int, float)):
2.38 + continue
2.39 + else:
2.40 + value = repr(value)
2.41 + values.append(u'%s = %s' % (attr, value))
2.42 + return u'%s(%s)' % (node.__class__.__name__,
2.43 + u',\n '.join(values))
2.44 +
2.45 def visitchild(self, child, parent, attrname, idx):
2.46 self.access_path.append((parent, attrname, idx))
2.47 - result = self.visit(child)
2.48 + try:
2.49 + result = self.visit(child)
2.50 + except Errors.CompilerCrash:
2.51 + raise
2.52 + except Exception, e:
2.53 + import sys
2.54 + trace = ['']
2.55 + for parent, attribute, index in self.access_path:
2.56 + node = getattr(parent, attribute)
2.57 + if index is None:
2.58 + index = ''
2.59 + else:
2.60 + node = node[index]
2.61 + index = u'[%d]' % index
2.62 + trace.append(u'%s.%s%s = %s' % (
2.63 + parent.__class__.__name__, attribute, index,
2.64 + self.dump_node(node)))
2.65 + raise Errors.CompilerCrash(
2.66 + node.pos, self.__class__.__name__,
2.67 + u'\n'.join(trace), e, sys.exc_info()[2])
2.68 self.access_path.pop()
2.69 return result
2.70
