thouis / numpy-trac-migration

numpy Trac to github issues migration
2 stars 3 forks source link

Make the dtype object immutable and not coerce other types when compared (hashable requirements) (migrated from Trac #1127) #2680

Open thouis opened 12 years ago

thouis commented 12 years ago

Original ticket http://projects.scipy.org/numpy/ticket/1127 Reported 2009-06-05 by atmention:FrancescAlted, assigned to unknown.

The dtype object seems to be shared after a copy of a structured array is done. This is inconvenient when you change properties in one of arrays and these are propagated to the other.

The next snippet exposes the problem:

In [21]: dt = np.dtype('f4,f8')

In [22]: ra = np.empty(1, dt)

In [23]: ra.dtype
Out[23]: dtype([('f0', '<f4'), ('f1', '<f8')])

In [24]: rb = ra[:]

In [25]: ra.dtype.names = ('float', 'double')

In [26]: ra.dtype
Out[26]: dtype([('float', '<f4'), ('double', '<f8')])

In [27]: rb.dtype
Out[27]: dtype([('float', '<f4'), ('double', '<f8')])  # not the original!
thouis commented 12 years ago

Comment in Trac by atmention:cournape, 2009-11-25

thouis commented 12 years ago

Comment in Trac by atmention:pv, 2010-07-18

thouis commented 12 years ago

Comment in Trac by atmention:pv, 2010-10-10

thouis commented 12 years ago

Comment in Trac by atmention:mwiebe, 2011-03-24

This is the PyArray_Descr object, which implements the hash method. From http://docs.python.org/glossary.html, below is the definition of hashable. To be correct, the dtype object should be made immutable and should not coerce other types to dtype during comparisons.

==hashable== An object is hashable if it has a hash value which never changes during its lifetime (it needs a hash() method), and can be compared to other objects (it needs an eq() or cmp() method). Hashable objects which compare equal must have the same hash value.

Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.

All of Python’s immutable built-in objects are hashable, while no mutable containers (such as lists or dictionaries) are. Objects which are instances of user-defined classes are hashable by default; they all compare unequal, and their hash value is their id().

thouis commented 12 years ago

Comment in Trac by atmention:mwiebe, 2011-05-23

The dtype pickling also needs to change, because you can't have a setstate function on an immutable object.