Skip to content

DEP: Deprecate collapsing shape-1 dtype fields to scalars. - #13326

Merged
eric-wieser merged 1 commit into
numpy:masterfrom
anntzer:shape-1-fields
May 26, 2019
Merged

eric-wieser merged 1 commit into
numpy:masterfrom
anntzer:shape-1-fields

Conversation

@anntzer

@anntzer anntzer commented Apr 14, 2019

Copy link
Copy Markdown
Contributor

See discussion at #13112.

Currently, a field specified as [(name, dtype, 1)] is interpreted as
a scalar field (i.e., the same as [(name, dtype)] or [(name, dtype, ()]). This now raises a DeprecationWarning; in a future version, it
will be interpreted as a shape-(1,) field, i.e. the same as [(name, dtype, (1,))] (consistently with [(name, dtype, n)] with n>1, which
is already equivalent to [(name, dtype, (n,)]).

@eric-wieser: This currently fails test_recfunctions::TestRecFunctions::test_structured_to_unstructured (apparently an extra copy is now being made), but it's not clear to me why.

Comment thread numpy/core/src/multiarray/descriptor.c Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a future warning, I believe we have a macro for that too.

@eric-wieser

eric-wieser commented Apr 14, 2019 •

Copy link
Copy Markdown
Member

This currently fails test_recfunctions::TestRecFunctions::test_structured_to_unstructured (apparently an extra copy is now being made), but it's not clear to me why.

Congrats, you found a bug in astype(copy=False): #13327

For the time being, you should probably just replace (c,) with (c,) if c != 1 else () in the failing code paths.

Comment thread numpy/lib/recfunctions.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To work around #13327 you need to special-case c == 1 here

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind - the actual problem is the test is bad - it should be checking ret.base is a or ret is a - or in a shorter form, ret.view().base is a

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switching to either form still fails for me locally.

@eric-wieser

eric-wieser commented Apr 14, 2019 •

Copy link
Copy Markdown
Member

Looking more closely - this is a bug / missing optimization in structured_to_unstructured:

import numpy.lib.recfunctions as rfn
dt = np.dtype([('f', (int, (2, 2)))])
arr = np.zeros(10, dt)
arr2 = rfn.structured_to_unstructured(arr)
assert arr2.base is arr  # fails

@eric-wieser

Copy link
Copy Markdown
Member

Rebasing on #13332 should fix things

@anntzer

anntzer commented Apr 15, 2019

Copy link
Copy Markdown
Contributor Author

I'll wait for it to be merged first? Please ping me when it is :)

@charris charris changed the title Deprecate collapsing shape-1 dtype fields to scalars. DEP: Deprecate collapsing shape-1 dtype fields to scalars. Apr 16, 2019
@mattip

mattip commented May 16, 2019

Copy link
Copy Markdown
Member

#1332 was merged, this needs a rebase

@anntzer

anntzer commented May 16, 2019

Copy link
Copy Markdown
Contributor Author

thanks, rebased.

@mattip

mattip commented May 20, 2019

Copy link
Copy Markdown
Member

Looks good to me. Do we need to pass this by the mailing list?

@charris

charris commented May 20, 2019

Copy link
Copy Markdown
Member

Do we need to pass this by the mailing list?

Probably worth doing that. The proposed changes make sense to me, but it never hurts to see if anyone else has thoughts on the matter.

@eric-wieser eric-wieser left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a test in test_deprecations.py too, I think

Comment thread numpy/core/src/multiarray/descriptor.c Resolved
Comment thread numpy/core/tests/test_dtype.py Resolved
Comment thread numpy/lib/tests/test_recfunctions.py Resolved
Comment thread numpy/core/tests/test_dtype.py Resolved
@anntzer
anntzer force-pushed the shape-1-fields branch 2 times, most recently from b491878 to 783f8d1 Compare May 20, 2019 14:46
@anntzer

anntzer commented May 20, 2019 •

Copy link
Copy Markdown
Contributor Author

added test in test_deprecations

emailed the mailing list

Comment thread numpy/core/tests/test_deprecations.py Resolved
Comment thread numpy/core/src/multiarray/descriptor.c Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on your test changes, it might be worth a remark on the message that this also applies to / is caused by format strings like "1f4". I don't think you need to go to the effort of working out whether the user used tuples or strings though.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And in the release note.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, edited.

Comment thread numpy/core/tests/test_deprecations.py Resolved
@mhvk

mhvk commented May 20, 2019

Copy link
Copy Markdown
Contributor

In response to the mailing list: very much in favour!

@mattip

mattip commented May 24, 2019

Copy link
Copy Markdown
Member

Looks good to me. Can this make 1.17?

Comment thread numpy/ma/mrecords.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to be (len(_mask.dtype),) else it will run into the deprecation warning here when len(_mask.dtype) == 1

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, fixed

Currently, a field specified as `[(name, dtype, 1)]` is interpreted as
a scalar field (i.e., the same as `[(name, dtype)]` or `[(name, dtype,
()]`). This now raises a FutureWarning; in a future version, it will
be interpreted as a shape-(1,) field, i.e. the same as `[(name, dtype,
(1,))]` (consistently with `[(name, dtype, n)]` with `n>1`, which is
already equivalent to `[(name, dtype, (n,)]`).
Comment thread numpy/ma/mrecords.py
pass
hasmasked = _mask.view((bool, (len(_mask.dtype) or 1))).any()
tp_len = len(_mask.dtype)
hasmasked = _mask.view((bool, ((tp_len,) if tp_len else ()))).any()

@eric-wieser eric-wieser May 25, 2019 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if condition should be _mask.dtype.fields is None, else it blows up on structured types with 0 fields. Arguably out of scope, but may as well fix this.

If you're looking for another deprecation for another PR, len(dtype) is looking like a bad idea on non structured dtypes... If not, I'll probably do that myself.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although actually the function is crap anyway and should be using one of the recursive helpers in ma/core that ors together all the fields

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So should I update this PR, or just leave it as it is and let you do a followup? (I would prefer the latter :))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose you could argue that this PR is about fixing things for length-1 subarrays, and you've succeeded even without fixing this. I think fine to put in as is, assuming we can sort out the ci failure by restarting

@mattip

mattip commented May 26, 2019

Copy link
Copy Markdown
Member

CI is passing. Any more comments?

@anntzer

anntzer commented May 26, 2019

Copy link
Copy Markdown
Contributor Author

Not on my side.

@mattip

mattip commented May 26, 2019

Copy link
Copy Markdown
Member

Still needs a test in test_deprecations

@anntzer

anntzer commented May 26, 2019

Copy link
Copy Markdown
Contributor Author

@mattip
mattip requested a review from eric-wieser May 26, 2019 08:02
@eric-wieser

Copy link
Copy Markdown
Member

Let's put this in - more than one core dev in favor of the deprecation, and at worst this will create too much noise. Thanks @anntzer. I look forward to never being bitten by this again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants