Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Why does recarray assignment fail: "cannot call setfield on an object array"? (Trac #2006) #2599

Open
numpy-gitbot opened this Issue · 3 comments

3 participants

@numpy-gitbot

Original ticket http://projects.scipy.org/numpy/ticket/2006 on 2011-12-23 by trac user kevin000, assigned to unknown.

Using a recarray with member assignment fails if any column uses the object data type. I don't understand why this fails, especially since the dictionary style assignment works.

Brief example showing what recarray assignments succeed or fail

import numpy as np

recarray with integer datatypes

dt = np.dtype([('foo', 'i8'), ('bar', 'i8')])
r = np.zeros((1,3), dtype=dt).view(np.recarray)
r['foo'] = np.array([1, 2, 3]) # OK
r.foo = np.array([1, 2, 3]) # OK

recarray with an object datatype

dt = np.dtype([('foo', 'i8'), ('bar', 'O8')])
r = np.zeros((1,3), dtype=dt).view(np.recarray)
r['foo'] = np.array([1, 2, 3]) # OK
r.foo = np.array([1, 2, 3]) # RuntimeError

For the relevant C code search for "cannot call setfield on an object array" in this file:

https://github.com/numpy/numpy/blob/master/numpy/core/src/multiarray/methods.c

Thanks!

Kevin

@cmarquardt

The same problem occurs in 1.6.2 and 1.7.0b2.

The (big) change that introduced this behavior is 2635398 and apparently has introduced the error condition on purpose; there's even a test checking that using the setfield() method on an (ordinary) object array throws a RuntimeError.

As modifying object sub-arrays using the dictionary approach works fine, the easiest solution seems to be to replace the setfield() method in the setattr() method of recarray with ndarray's setitem() method; I just attached a patch against the 1.7.0b2 distribution of numpy which runns successfully through the same tests as the original distribution does.

I know way too little about numpy internals to judge if this patch is consistent with the numpy conventions etc.; but keeping this bug in recarrays somehow make the whole recarray class superfluous if not fixed IMHO.

Thanks for considering the patch (which is below),

Christian.

*** numpy-1.7.0b2.orig/numpy/core//records.py   2012-09-04 23:31:31.000000000 +0200
--- numpy-1.7.0b2/numpy/core//records.py        2012-12-02 23:20:00.757234770 +0100
***************
*** 451,457 ****
              res = fielddict[attr][:2]
          except (TypeError, KeyError):
              raise AttributeError("record array has no attribute %s" % attr)
!         return self.setfield(val, *res)
  
      def __getitem__(self, indx):
          obj = ndarray.__getitem__(self, indx)
--- 451,457 ----
              res = fielddict[attr][:2]
          except (TypeError, KeyError):
              raise AttributeError("record array has no attribute %s" % attr)
!         return ndarray.__setitem__(self, attr, val)
  
      def __getitem__(self, indx):
          obj = ndarray.__getitem__(self, indx)

@charris
Owner

There are a bunch of tickets that look related to this. The patch has not been applied as of 1.9-devel.

@charris
Owner

Easy fix if the patch is good and we want that behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.