From 64625dcdee7226f73bb405c0778449e8e58c3af6 Mon Sep 17 00:00:00 2001 From: Joost van Zwieten Date: Thu, 21 Nov 2024 11:14:35 +0100 Subject: [PATCH] disallow truncation in types.arraydata If `types.arraydata` is passed a `numpy.array` with dtype `numpy.int64` and the platform default int type is 32 bit, then `types.arraydata` truncates the array to `numpy.int32` without warning. This behavior is inherited from `numpy.astype`. Since this may lead to unexpected behavior, this patch disallows truncation by checking that the casted array is equal to the original array. --- nutils/types.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/nutils/types.py b/nutils/types.py index f69fb8d43..b94dc84f9 100644 --- a/nutils/types.py +++ b/nutils/types.py @@ -387,9 +387,12 @@ class arraydata(Singleton): def __new__(cls, arg): if isinstance(arg, cls): return arg - array = numpy.asarray(arg) - dtype = dict(b=bool, u=int, i=int, f=float, c=complex)[array.dtype.kind] - return super().__new__(cls, dtype, array.shape, array.astype(dtype, copy=False).tobytes()) + orig = numpy.asarray(arg) + dtype = dict(b=bool, u=int, i=int, f=float, c=complex)[orig.dtype.kind] + array = orig.astype(dtype, copy=False) + if array.dtype != orig.dtype and not numpy.equal(array, orig).all(): + raise ValueError('cannot cast array with dtype {orig.dtype} to native dtype {array.dtype} without truncation') + return super().__new__(cls, dtype, array.shape, array.tobytes()) def reshape(self, *shape): if numpy.prod(shape) != numpy.prod(self.shape):