Skip to content

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

Closed

Description

@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

Activity

  1. cmarquardt commented on Dec 15, 2012

    @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)
    
  2. charris commented on Feb 21, 2014

    @charris
    Member

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

  3. charris commented on Feb 21, 2014

    @charris
    Member

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

  4. added 10 commits that reference this issue on Jun 4, 2015
    907c541
    b7fece9
    4e3841c
    8171464
    34bdab2
    00a31fe
    432ddcd
    f3903e3
    958bf63
    e2cd6fa
  5. added a commit that references this issue on Oct 19, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions