Less strict type checking on non-subclassed extern types.
authorRobert Bradshaw <robertwb@math.washington.edu>
Wed, 9 Dec 2009 07:10:36 +0000 (23:10 -0800)
committerRobert Bradshaw <robertwb@math.washington.edu>
Wed, 9 Dec 2009 07:10:36 +0000 (23:10 -0800)
Cython/Compiler/ModuleNode.py
Cython/Compiler/PyrexTypes.py
Cython/Compiler/Symtab.py

index 346ace0c3c81d21a890908b543fb49f6c2eada72..4770d47dd09777992a31c453ae525bcee509244d 100644 (file)
@@ -1986,18 +1986,19 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
             module_name = '__Pyx_BUILTIN_MODULE_NAME'
         if type.name in self.py3_type_name_map:
             code.putln("#if PY_MAJOR_VERSION >= 3")
-            code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s)); %s' % (
+            code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s), 1); %s' % (
                     type.typeptr_cname,
                     module_name,
                     self.py3_type_name_map[type.name],
                     objstruct,
                     error_code))
             code.putln("#else")
-        code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s)); %s' % (
+        code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s), %i); %s' % (
                 type.typeptr_cname,
                 module_name,
                 type.name,
                 objstruct,
+                not type.is_external or type.is_subclassed,
                 error_code))
         if type.name in self.py3_type_name_map:
             code.putln("#endif")
@@ -2154,17 +2155,18 @@ bad:
 
 type_import_utility_code = UtilityCode(
 proto = """
-static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, long size);  /*proto*/
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, long size, int strict);  /*proto*/
 """,
 impl = """
 #ifndef __PYX_HAVE_RT_ImportType
 #define __PYX_HAVE_RT_ImportType
 static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
-    long size)
+    long size, int strict)
 {
     PyObject *py_module = 0;
     PyObject *result = 0;
     PyObject *py_name = 0;
+    int size_ok;
 
     py_module = __Pyx_ImportModule(module_name);
     if (!py_module)
@@ -2189,7 +2191,13 @@ static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class
             module_name, class_name);
         goto bad;
     }
-    if (((PyTypeObject *)result)->tp_basicsize != size) {
+    if (strict) {
+        size_ok = ((PyTypeObject *)result)->tp_basicsize == size;
+    }
+    else {
+        size_ok = ((PyTypeObject *)result)->tp_basicsize >= size;
+    }
+    if (!size_ok) {
         PyErr_Format(PyExc_ValueError, 
             "%s.%s does not appear to be the correct type object",
             module_name, class_name);
index b319a4d815f45fc6e753133e1c5d601a312e5927..6d7d608aa8041f1aea325bf662f7e2f2b4b291e2 100644 (file)
@@ -345,6 +345,8 @@ class PyObjectType(PyrexType):
     default_value = "0"
     pymemberdef_typecode = "T_OBJECT"
     buffer_defaults = None
+    is_extern = False
+    is_subclassed = False
     
     def __str__(self):
         return "Python object"
@@ -472,10 +474,12 @@ class PyExtensionType(PyObjectType):
     
     objtypedef_cname = None
     
-    def __init__(self, name, typedef_flag, base_type):
+    def __init__(self, name, typedef_flag, base_type, is_external=0):
         self.name = name
         self.scope = None
         self.typedef_flag = typedef_flag
+        if base_type is not None:
+            base_type.is_subclassed = True
         self.base_type = base_type
         self.module_name = None
         self.objstruct_cname = None
@@ -485,6 +489,7 @@ class PyExtensionType(PyObjectType):
         self.vtabstruct_cname = None
         self.vtabptr_cname = None
         self.vtable_cname = None
+        self.is_external = is_external
     
     def set_scope(self, scope):
         self.scope = scope
index 00371aaa2a66f39618c7d64080262a332decaa94..c8fb01c7f1c2d5695a7de3234668894afab10d89 100644 (file)
@@ -887,7 +887,7 @@ class ModuleScope(Scope):
         #  Make a new entry if needed
         #
         if not entry:
-            type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type)
+            type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type, visibility == 'extern')
             type.pos = pos
             type.buffer_defaults = buffer_defaults
             if objtypedef_cname is not None: