mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
ifcwrap: accept numpy scalars in aggregate type check #5873
check_aggregate_of_type used an exact type comparison (element->ob_type == type_obj), so a numpy array was rejected because its elements are numpy scalars (numpy.float64) rather than direct float instances. For the numeric types, accept subclasses: PyFloat_Check for double (numpy.float64 subclasses float) and PyLong_Check (excluding bool) for int. The SPF REAL vs INTEGER distinction is kept, so a float is not accepted where an int is expected and vice versa. This replaces the earlier Python-side walk() approach, which the maintainer preferred not to take since walk() is removed in v0.9. Verified with a runtime red-green (built as a shared lib, called via ctypes): the old check rejects np.array([3.0, 4.0]) and the new one accepts it, plain lists still work, an int list is still rejected where a REAL is expected, and bool is rejected for INTEGER. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
committed by
Thomas Krijnen
parent
d2381ad6c6
commit
b1be7d92e6
@@ -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<void*>(&PyFloat_Type)) {
|
||||
b = PyFloat_Check(element);
|
||||
} else if (type_obj == static_cast<void*>(&PyLong_Type)) {
|
||||
b = PyLong_Check(element) && !PyBool_Check(element);
|
||||
} else {
|
||||
b = element->ob_type == type_obj;
|
||||
}
|
||||
Py_DECREF(element);
|
||||
if (!b) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user