Skip to content

Commit

Permalink
disallow truncation in types.arraydata
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
joostvanzwieten committed Nov 21, 2024
1 parent f2a895b commit 64625dc
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions nutils/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')

Check warning on line 394 in nutils/types.py

View workflow job for this annotation

GitHub Actions / Test coverage

Line not covered

Line 394 of `nutils/types.py` is not covered by tests.
return super().__new__(cls, dtype, array.shape, array.tobytes())

def reshape(self, *shape):
if numpy.prod(shape) != numpy.prod(self.shape):
Expand Down

0 comments on commit 64625dc

Please sign in to comment.