diff --git a/src/ifcwrap/utils/type_conversion.i b/src/ifcwrap/utils/type_conversion.i index 4b47cac55b..9c3cf82e7f 100644 --- a/src/ifcwrap/utils/type_conversion.i +++ b/src/ifcwrap/utils/type_conversion.i @@ -34,9 +34,19 @@ if (PySequence_Size(aggregate) == -1) return false; for(Py_ssize_t i = 0; i < PySequence_Size(aggregate); ++i) { PyObject* element = PySequence_GetItem(aggregate, i); - // This is equivalent to the PyFloat_CheckExact macro. This means - // that direct instances of int, float, str, etc. need to be used. - bool b = element->ob_type == type_obj; + // Accept the exact type or, for the numeric types, a subclass such + // as a numpy scalar (numpy.float64 subclasses float), so that numpy + // arrays can be assigned. The REAL vs INTEGER distinction is kept: a + // float is not accepted where an int is expected and vice versa, and + // bool (a subclass of int) is still rejected for INTEGER. See #5873. + bool b; + if (type_obj == static_cast(&PyFloat_Type)) { + b = PyFloat_Check(element); + } else if (type_obj == static_cast(&PyLong_Type)) { + b = PyLong_Check(element) && !PyBool_Check(element); + } else { + b = element->ob_type == type_obj; + } Py_DECREF(element); if (!b) { return false;