summaryrefslogtreecommitdiff
path: root/Cython/Utility/ImportExport.c
diff options
context:
space:
mode:
Diffstat (limited to 'Cython/Utility/ImportExport.c')
-rw-r--r--Cython/Utility/ImportExport.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/Cython/Utility/ImportExport.c b/Cython/Utility/ImportExport.c
index 6ceba7efb..897657281 100644
--- a/Cython/Utility/ImportExport.c
+++ b/Cython/Utility/ImportExport.c
@@ -498,8 +498,10 @@ static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name,
PyObject *result = 0;
char warning[200];
Py_ssize_t basicsize;
+ Py_ssize_t itemsize;
#if CYTHON_COMPILING_IN_LIMITED_API
PyObject *py_basicsize;
+ PyObject *py_itemsize;
#endif
result = PyObject_GetAttrString(module, class_name);
@@ -513,6 +515,7 @@ static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name,
}
#if !CYTHON_COMPILING_IN_LIMITED_API
basicsize = ((PyTypeObject *)result)->tp_basicsize;
+ itemsize = ((PyTypeObject *)result)->tp_itemsize;
#else
py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
if (!py_basicsize)
@@ -522,19 +525,30 @@ static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name,
py_basicsize = 0;
if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
goto bad;
+ py_itemsize = PyObject_GetAttrString(result, "__itemsize__");
+ if (!py_itemsize)
+ goto bad;
+ itemsize = PyLong_AsSsize_t(py_itemsize);
+ Py_DECREF(py_itemsize);
+ py_itemsize = 0;
+ if (itemsize == (Py_ssize_t)-1 && PyErr_Occurred())
+ goto bad;
#endif
- if ((size_t)basicsize < size) {
+ if ((size_t)(basicsize + itemsize) < size) {
PyErr_Format(PyExc_ValueError,
"%.200s.%.200s size changed, may indicate binary incompatibility. "
"Expected %zd from C header, got %zd from PyObject",
- module_name, class_name, size, basicsize);
+ module_name, class_name, size, basicsize+itemsize);
goto bad;
}
- if (check_size == __Pyx_ImportType_CheckSize_Error && (size_t)basicsize != size) {
+ // varobjects almost have structs between basicsize and basicsize + itemsize
+ // but the struct isn't always one of the two limiting values
+ if (check_size == __Pyx_ImportType_CheckSize_Error &&
+ ((size_t)basicsize > size || (size_t)(basicsize + itemsize) < size)) {
PyErr_Format(PyExc_ValueError,
"%.200s.%.200s size changed, may indicate binary incompatibility. "
- "Expected %zd from C header, got %zd from PyObject",
- module_name, class_name, size, basicsize);
+ "Expected %zd from C header, got %zd-%zd from PyObject",
+ module_name, class_name, size, basicsize, basicsize+itemsize);
goto bad;
}
else if (check_size == __Pyx_ImportType_CheckSize_Warn && (size_t)basicsize > size) {