Skip to content

New in NumPy 1.14: failures in PyTables  #10344

Description

@oleksandr-pavlyk

In the following snippet:

import numpy as np
data_proper = [(456, b'dbe', 1.2), (2, b'ded', 1.3)]
data_improper = [[456, b'dbe', 1.2], [2, b'ded', 1.3]]
descr = [('f0', '<i4'), ('f1', 'S3'), ('f2', '<f8')]
dtype = np.dtype((np.record, descr))

np.array(data_improper, dtype=dtype)

Execution of the last line in 1.13 used to raise:

TypeError: a bytes-like object is required, not 'int'

which allowed the logic in numpy/core/records.py#L676 to recover and reinterpret the line as np.array(data_proper, dtype=dtype).

The trouble is that in NumPy 1.14

ValueError: invalid literal for int() with base 10: b'dbe'

is being raised instead, which results in the failure.

This is a gist of the issue behind numerous test failures in pyTables when used with NumPy 1.14.

Activity

  1. added this to the milestone on Jan 8, 2018
  2. charris commented on Jan 8, 2018

    @charris
    Member

    The error comes from cPython, but where it actually originates is hard to tell, the traceback has been truncated too far. I think we will need a bisect on this.

  3. eric-wieser commented on Jan 8, 2018

    @eric-wieser
    Member

    Perhaps the easy fix is to just to catch ValueError in rec.array as well?

  4. charris commented on Jan 8, 2018

    @charris
    Member

    @eric-wieser I'd worry that that might not be the only place affected. I think we need to know just what changed.

  5. eric-wieser commented on Jan 8, 2018

    @eric-wieser
    Member

    I think the simplest reproduction is:

    >>> np.array(456, [('i', int)])
    TypeError: a bytes-like object is required, not 'int'  # 1.13
    array((456,), dtype=[('i', '<i4')])  # 1.14

    However, the new behavior seems kinda consistent, when compared to:

    >>> np.array(456).astype([('i', int)])
    array((456,), dtype=[('i', '<i4')])  # 1.13 and 1.14

    and

    >>> np.array(np.array(456), [('i', int)])
    array((456,), dtype=[('i', '<i4')])  # 1.13 and 1.14
  6. charris commented on Jan 8, 2018

    @charris
    Member

    For reference, the 1.13.3 error is TypeError: expected a readable buffer object.

  7. charris commented on Jan 8, 2018

    @charris
    Member

    I do think the catch in records.py is too narrow, too dependent on underlying implementation details, so that needs a fix.

  8. eric-wieser commented on Jan 8, 2018

    @eric-wieser
    Member

    so that needs a fix.

    Frankly, I think we should deprecate that code path entirely. If you pass malformed data, expecting numpy to guess what you meant seems undesirable

  9. charris commented on Jan 8, 2018

    @charris
    Member

    The change came in with #6053. I don't think this is so much a bug, as a change in behavior.

  10. charris commented on Jan 8, 2018

    @charris
    Member

    I think we need a bigger discussion on the way forward, so pinging @ahaldane . IIRC, h5py was also affected by this change.

  11. ahaldane commented on Jan 8, 2018

    @ahaldane
    Member

    I'm reading along. Following on what @eric-wieser said, the change in behavior was to allow scalars to broadcast to all fields during array creation, not just during assignment. The difference in behavior of these two lines seemed inconsistent in 1.13:

    >>> a = np.zeros(3, dtype='i4,i4') # no scalar assignment problem
    >>> a[:] = 456  # no scalar assignment problem
    >>> np.array([456], dtype='i4,i4')
    TypeError: expected a readable buffer object  # can't initialize to scalar in 1.13

    Furthermore, in 1.13:

    >>> np.array([456, 'dbe'], dtype='i4,S3')
    TypeError: expected a readable buffer object
    >>> np.rec.array([456, 'dbe'], dtype='i4,S3')
    rec.array((456, 'dbe'), 
              dtype=[('f0', '<i4'), ('f1', 'S3')])

    Why should the first line fail, but the second succeed?

    So my feeling is that the special casing in records.py isn't ideal, but maybe there is away to keep things back-compatible, I'm not sure yet.

    By the way, I will be at a conference later this week, so may be away from my computer.

  12. charris commented on Jan 8, 2018

    @charris
    Member

    The problem seems isolated to the record.py module, so for 1.14 adding ValueError to the list of caught errors is probably an adequate fix. @eric-wieser's point about trying to fix up malformed input is the long term problem, and we probably need more time than 1.14 allows to deal with that.

  13. oleksandr-pavlyk commented on Jan 8, 2018

    @oleksandr-pavlyk
    ContributorAuthor

    @charris Thank you. The improper record array object input to numpy.record.array was all coming from hard-coded list of lists in pyTable's test files, so it is easy, albeit tedious, to modify. I am prepping a PR for pyTable now.

  14. 17 remaining items

  15. added 6 commits that reference this issue on Feb 3, 2018
    976dc28
    f1138b1
    188905f
    08469bb
  16. modified the milestones: , 1.15.0 release on Feb 7, 2018
  17. charris commented on Feb 8, 2018

    @charris
    Member

    OK, made the suggested fix in #10543. Note that the @ahaldane reverted the causal changes for 1.14.1, but getting a FutureWarning out there early is probably a good thing.

  18. added a commit that references this issue on Feb 8, 2018
    33c423e
  19. added a commit that references this issue on Feb 9, 2018
    6df6987
  20. added a commit that references this issue on Feb 15, 2018
    3cb40bb
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

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions