cleanup
[cython.git] / Cython / Compiler / Errors.py
index a8ad03aff4dfeb8d89abcec68802fb2a4988a473..1e7a44a3a2bd2f1635ed36115090eafcab8e553f 100644 (file)
@@ -63,7 +63,28 @@ class InternalError(Exception):
     def __init__(self, message):
         Exception.__init__(self, "Internal compiler error: %s"
             % message)
-            
+
+
+class CompilerCrash(CompileError):
+    # raised when an unexpected exception occurs in a transform
+    def __init__(self, pos, context, message, cause, stacktrace=None):
+        if message:
+            message = u'\n' + message
+        else:
+            message = u'\n'
+        if context:
+            message = "Compiler crash in " + context + message
+        if stacktrace:
+            import traceback
+            message += (
+                u'\n\nCompiler crash traceback from this point on:\n' +
+                u''.join(traceback.format_tb(stacktrace)))
+        if cause:
+            if not stacktrace:
+                message += u'\n'
+            message += u'%s: %s' % (cause.__class__.__name__, cause)
+        CompileError.__init__(self, pos, message)
+
 
 listing_file = None
 num_errors = 0
@@ -90,16 +111,19 @@ def close_listing_file():
         listing_file = None
 
 def report_error(err):
-    global num_errors
-    # See Main.py for why dual reporting occurs. Quick fix for now.
-    if err.reported: return
-    err.reported = True
-    line = "%s\n" % err
-    if listing_file:
-        listing_file.write(line)
-    if echo_file:
-        echo_file.write(line)
-    num_errors = num_errors + 1
+    if error_stack:
+        error_stack[-1].append(err)
+    else:
+        global num_errors
+        # See Main.py for why dual reporting occurs. Quick fix for now.
+        if err.reported: return
+        err.reported = True
+        line = "%s\n" % err
+        if listing_file:
+            listing_file.write(line)
+        if echo_file:
+            echo_file.write(line)
+        num_errors = num_errors + 1
 
 def error(position, message):
     #print "Errors.error:", repr(position), repr(message) ###
@@ -120,3 +144,19 @@ def warning(position, message, level=0):
     if echo_file:
         echo_file.write(line)
     return warn
+
+# These functions can be used to momentarily suppress errors. 
+
+error_stack = []
+
+def hold_errors():
+    error_stack.append([])
+
+def release_errors(ignore=False):
+    held_errors = error_stack.pop()
+    if not ignore:
+        for err in held_errors:
+            report_error(err)
+
+def held_errors():
+    return error_stack[-1]