Make Cython report errors during load, and fix several bugs this uncovered
authorCraig Citro <craigcitro@gmail.com>
Sat, 13 Mar 2010 05:19:56 +0000 (21:19 -0800)
committerCraig Citro <craigcitro@gmail.com>
Sat, 13 Mar 2010 05:19:56 +0000 (21:19 -0800)
Cython/Compiler/Builtin.py
Cython/Compiler/Errors.py
Cython/Compiler/Main.py
Cython/Compiler/PyrexTypes.py
Cython/Compiler/Symtab.py

index 61bc1786411fc713b72cb146131e8b473ddcb1ed..a090ecfd2e100eb0d24b3eba58481aa0444e2ed7 100644 (file)
@@ -404,8 +404,8 @@ def init_builtin_structs():
     for name, cname, attribute_types in builtin_structs_table:
         scope = StructOrUnionScope(name)
         for attribute_name, attribute_type in attribute_types:
-            scope.declare_var(
-                attribute_name, attribute_type, None, attribute_name)
+            scope.declare_var(attribute_name, attribute_type, None,
+                              attribute_name, allow_pyobject=True)
         builtin_scope.declare_struct_or_union(
             name, "struct", scope, 1, None, cname = cname)
 
index d35a43274a56a60b3351f428c89abbcc746ba84e..bf99017ce46596d0238bddf3e6706a97f041dd6f 100644 (file)
@@ -43,8 +43,12 @@ class CompileError(PyrexError):
         else:
             pos_str = u""
             cont = u''
-        Exception.__init__(self, u'\nError converting Pyrex file to C:\n%s\n%s%s' % (
-            cont, pos_str, message))
+        if position is None:
+            Exception.__init__(self, message)
+        else:
+            Exception.__init__(
+                self, u'\nError converting Pyrex file to C:\n%s\n%s%s' % (
+                cont, pos_str, message))
 
 class CompileWarning(PyrexWarning):
     
@@ -133,7 +137,9 @@ def report_error(err):
 
 def error(position, message):
     #print "Errors.error:", repr(position), repr(message) ###
-    err = CompileError(position, message)
+    if position is None:
+        raise InternalError(message)
+    err = CompileError(position, message)    
     #if position is not None: raise Exception(err) # debug
     report_error(err)
     return err
index 736d81472a777be2c579ae994a6bfeebe841b83e..49ff61ade82f2da8ff9922b5ec335acc83c09f47 100644 (file)
@@ -493,13 +493,14 @@ class Context(object):
         names.reverse()
         return ".".join(names)
 
-    def setup_errors(self, options):
+    def setup_errors(self, options, result):
         if options.use_listing_file:
             result.listing_file = Utils.replace_suffix(source, ".lis")
-            Errors.open_listing_file(result.listing_file,
-                echo_to_stderr = options.errors_to_stderr)
+            path = result.listing_file
         else:
-            Errors.open_listing_file(None)
+            path = None
+        Errors.open_listing_file(path=path,
+                                 echo_to_stderr=options.errors_to_stderr)
 
     def teardown_errors(self, err, options, result):
         source_desc = result.compilation_source.source_desc
@@ -563,7 +564,7 @@ def run_pipeline(source, options, full_module_name = None):
     else:
         pipeline = context.create_pyx_pipeline(options, result)
 
-    context.setup_errors(options)
+    context.setup_errors(options, result)
     err, enddata = context.run_pipeline(pipeline, source)
     context.teardown_errors(err, options, result)
     return result
index 3d6a011f0b3db764ebe835b660d31a7ede8d0c02..fab502caf32d511527fb8553bd7c70b595462e1a 100755 (executable)
@@ -518,6 +518,14 @@ class PyExtensionType(PyObjectType):
         # know which module it's defined in, it will be imported.
         return self.typeobj_cname is None and self.module_name is not None
     
+    def assignable_from(self, src_type):
+        if self == src_type:
+            return True
+        if isinstance(src_type, PyExtensionType):
+            if src_type.base_type is not None:
+                return self.assignable_from(src_type.base_type)
+        return False
+
     def declaration_code(self, entity_code, 
             for_display = 0, dll_linkage = None, pyrex = 0, deref = 0):
         if pyrex or for_display:
index 3427b93e1b23a7af9bc253b105aaf11f93d029af..464fab90d9540000482778ae2bdce9b4ff8ade82 100644 (file)
@@ -1440,7 +1440,7 @@ class CClassScope(ClassScope):
         args = type.args
         if not args:
             error(pos, "C method has no self argument")
-        elif not args[0].type.same_as(self.parent_type):
+        elif not self.parent_type.assignable_from(args[0].type):
             error(pos, "Self argument (%s) of C method '%s' does not match parent type (%s)" %
                   (args[0].type, name, self.parent_type))
         entry = self.lookup_here(name)