Commit 2393e033 authored by Robert Bradshaw's avatar Robert Bradshaw

Less strict type checking on non-subclassed extern types.

parent 31ca96cd
...@@ -1986,18 +1986,19 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1986,18 +1986,19 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
module_name = '__Pyx_BUILTIN_MODULE_NAME' module_name = '__Pyx_BUILTIN_MODULE_NAME'
if type.name in self.py3_type_name_map: if type.name in self.py3_type_name_map:
code.putln("#if PY_MAJOR_VERSION >= 3") 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, type.typeptr_cname,
module_name, module_name,
self.py3_type_name_map[type.name], self.py3_type_name_map[type.name],
objstruct, objstruct,
error_code)) error_code))
code.putln("#else") 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, type.typeptr_cname,
module_name, module_name,
type.name, type.name,
objstruct, objstruct,
not type.is_external or type.is_subclassed,
error_code)) error_code))
if type.name in self.py3_type_name_map: if type.name in self.py3_type_name_map:
code.putln("#endif") code.putln("#endif")
...@@ -2154,17 +2155,18 @@ bad: ...@@ -2154,17 +2155,18 @@ bad:
type_import_utility_code = UtilityCode( type_import_utility_code = UtilityCode(
proto = """ 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 = """ impl = """
#ifndef __PYX_HAVE_RT_ImportType #ifndef __PYX_HAVE_RT_ImportType
#define __PYX_HAVE_RT_ImportType #define __PYX_HAVE_RT_ImportType
static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
long size) long size, int strict)
{ {
PyObject *py_module = 0; PyObject *py_module = 0;
PyObject *result = 0; PyObject *result = 0;
PyObject *py_name = 0; PyObject *py_name = 0;
int size_ok;
py_module = __Pyx_ImportModule(module_name); py_module = __Pyx_ImportModule(module_name);
if (!py_module) if (!py_module)
...@@ -2189,7 +2191,13 @@ static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class ...@@ -2189,7 +2191,13 @@ static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class
module_name, class_name); module_name, class_name);
goto bad; 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, PyErr_Format(PyExc_ValueError,
"%s.%s does not appear to be the correct type object", "%s.%s does not appear to be the correct type object",
module_name, class_name); module_name, class_name);
......
...@@ -345,6 +345,8 @@ class PyObjectType(PyrexType): ...@@ -345,6 +345,8 @@ class PyObjectType(PyrexType):
default_value = "0" default_value = "0"
pymemberdef_typecode = "T_OBJECT" pymemberdef_typecode = "T_OBJECT"
buffer_defaults = None buffer_defaults = None
is_extern = False
is_subclassed = False
def __str__(self): def __str__(self):
return "Python object" return "Python object"
...@@ -472,10 +474,12 @@ class PyExtensionType(PyObjectType): ...@@ -472,10 +474,12 @@ class PyExtensionType(PyObjectType):
objtypedef_cname = None 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.name = name
self.scope = None self.scope = None
self.typedef_flag = typedef_flag self.typedef_flag = typedef_flag
if base_type is not None:
base_type.is_subclassed = True
self.base_type = base_type self.base_type = base_type
self.module_name = None self.module_name = None
self.objstruct_cname = None self.objstruct_cname = None
...@@ -485,6 +489,7 @@ class PyExtensionType(PyObjectType): ...@@ -485,6 +489,7 @@ class PyExtensionType(PyObjectType):
self.vtabstruct_cname = None self.vtabstruct_cname = None
self.vtabptr_cname = None self.vtabptr_cname = None
self.vtable_cname = None self.vtable_cname = None
self.is_external = is_external
def set_scope(self, scope): def set_scope(self, scope):
self.scope = scope self.scope = scope
......
...@@ -887,7 +887,7 @@ class ModuleScope(Scope): ...@@ -887,7 +887,7 @@ class ModuleScope(Scope):
# Make a new entry if needed # Make a new entry if needed
# #
if not entry: 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.pos = pos
type.buffer_defaults = buffer_defaults type.buffer_defaults = buffer_defaults
if objtypedef_cname is not None: if objtypedef_cname is not None:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment