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