You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Dtype descr inconsistency with invisible fields #3176
Declaring a dtype with the dict 'name','format','offset' format could result in invisible fields. The same dtype however is not reproduced by its own descr that uses the list of tuples format. The invisibility does matter especially at comparisons/sorting. In the following case e.g. B and C should behave the same way:
This seems to be a bug or quirk of the Array Interface, and of dtype.descr.
The problem is that dtype.descr keeps the 'unseen' padding, apparently in order to conform to the Array Interface requirements (since dtype.descr is the "Array-interface compliant full description of the data-type."). Note that B.dtype.descr is [('A', '<i8'), ('', '|V8'), ('C', '<i8')], but repr(B.dtype) is not. Also note that C = A.view(B.dtype) works properly.
As noted in the OP, if you use np.save and np.load you will end up with extra 'padding fields' in your file, which leads to errors. This is not limited to the code above. For example, most "aligned" structs cannot be save/loaded properly because of their padding:
>>> a = np.zeros(2, np.dtype('i4,u1,i8', align=True))
>>> a.dtype.descr
[('f0', '<i4'), ('f1', '|u1'), ('', '|V3'), ('f2', '<i8')]
>>> np.save('file', a)
>>> np.load('file.npy')
ValueError: two fields with the same name
I'd have to learn more about the array interface to figure any more out.
My instinct for a solution is that dtype.descr is behaving properly, and should simply not be used unless you are doing something with the array interface. The code in the OP should be replaced with C = A.view(B.dtype). However, np.load needs a fix. Maybe it should notice when the field name is '' and interpret that as padding.
Activity
ahaldane commentedon Jul 28, 2015
This seems to be a bug or quirk of the Array Interface, and of
dtype.descr.The problem is that
dtype.descrkeeps the 'unseen' padding, apparently in order to conform to the Array Interface requirements (sincedtype.descris the "Array-interface compliant full description of the data-type."). Note thatB.dtype.descris[('A', '<i8'), ('', '|V8'), ('C', '<i8')], butrepr(B.dtype)is not. Also note thatC = A.view(B.dtype)works properly.As noted in the OP, if you use
np.saveandnp.loadyou will end up with extra 'padding fields' in your file, which leads to errors. This is not limited to the code above. For example, most "aligned" structs cannot be save/loaded properly because of their padding:I'd have to learn more about the array interface to figure any more out.
My instinct for a solution is that
dtype.descris behaving properly, and should simply not be used unless you are doing something with the array interface. The code in the OP should be replaced withC = A.view(B.dtype). However,np.loadneeds a fix. Maybe it should notice when the field name is''and interpret that as padding.ahaldane commentedon Jul 28, 2015
Oh, just found that #2215 is the same problem.
charris commentedon Aug 2, 2015
I think I'll leave both this and #2215 open, this because it is new, and the other because of the useful discussion.
embray commentedon Oct 7, 2015
I've run afoul of this as well. Thanks for raising the issue.
mattip commentedon Nov 9, 2018
PR #12358 removes the hidden fields while loading. I think we should disallow empty field names.
ahaldane commentedon Nov 18, 2018
#12358 fixed this, by my reading.
np.load/savenow work.You just shouldn't use code like
A.view(dtype=B.dtype.descr)now: Thedtype.descrattribute should only be used in special situations, see #8174.