Thanks to visit codestin.com
Credit goes to github.com

Skip to content

API: Forbid Q<->m safe casting#14718

Merged
mattip merged 2 commits into
numpy:masterfrom
eric-wieser:disable-Q_-_m_casting
Nov 25, 2019
Merged

API: Forbid Q<->m safe casting#14718
mattip merged 2 commits into
numpy:masterfrom
eric-wieser:disable-Q_-_m_casting

Conversation

@eric-wieser
Copy link
Copy Markdown
Member

@eric-wieser eric-wieser commented Oct 15, 2019

A lighter-weight alternative to gh-13061, fixes #12927

@eric-wieser eric-wieser added this to the 1.18.0 release milestone Oct 15, 2019
@eric-wieser eric-wieser force-pushed the disable-Q_-_m_casting branch from a322678 to ce2c865 Compare October 15, 2019 22:04
@seberg seberg changed the title Forbid Q<->m safe casting API: Forbid Q<->m safe casting Oct 15, 2019
@eric-wieser eric-wieser force-pushed the disable-Q_-_m_casting branch from ce2c865 to 63efb2d Compare October 15, 2019 22:13
seberg
seberg previously approved these changes Oct 15, 2019
Copy link
Copy Markdown
Member

@seberg seberg left a comment

Choose a reason for hiding this comment

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

Looks good to me (lets see if anything else needs fixing up). As a note for others: This is the minimal fix, since it solves the biggest/new issue while modifying only the strangest part of casting timedelta to ints.

Casting timedelta64 to ints could be disabled more generally at some point. Although that general cast might be best to synchronize to any thoughts about removing the timedelta64 without a unit (base).

Comment thread doc/release/upcoming_changes/14718.compatibility.rst Outdated
@seberg
Copy link
Copy Markdown
Member

seberg commented Oct 15, 2019

I just realized this does add a small inconsistency, since we also disable "same_kind" casting as is. And "same_kind" casiting does work for Q->q. We could probably enable/hack the same kind casting without affecting the behaviour w.r.t. to ufuncs though.

@seberg
Copy link
Copy Markdown
Member

seberg commented Oct 16, 2019

I pushed a commit to make same kind casting possible np.can_cast("uint64", "timedelta64") (arr.astype() also works, should add tests for both still probably).

I do not quite love this, but I am not sure if there is much of an option if we want consistency. I am also a bit scared that there may be some corner case missing somewhere...

@seberg seberg dismissed their stale review October 16, 2019 04:01

outdated

eric-wieser and others added 2 commits October 16, 2019 09:31
That is, uint64 <-> timedelta64.

Allowing this casting was weird, because Q<->q is forbidden, yet q and m are both int64.

This fixes numpygh-12927
@eric-wieser
Copy link
Copy Markdown
Member Author

eric-wieser commented Oct 16, 2019

@seberg: I rebased your commit on top of my local changes to add some more tests. I think your change looks reasonable, but I'd be tempted to pursue it as a separate PR.

@eric-wieser eric-wieser force-pushed the disable-Q_-_m_casting branch from 4496add to ac757b5 Compare October 16, 2019 08:36
@seberg
Copy link
Copy Markdown
Member

seberg commented Oct 16, 2019

Oh, nice, you added some tests. I think I am about ±0 on defining the "same kind" casting. It did seem like a slight inconsistency to not allow it, since by definition same kind casting should be allowed to demote the integer before attempting to "safe" cast to the timedelta.

I am OK with living with that inconsistency or splitting it out though.

@eric-wieser
Copy link
Copy Markdown
Member Author

I think this would be fine to put in - if nothing else, np.can_cast('u8', 'm8', casting='same_kind') is True on master, so is probably ok to leave that way.

Copy link
Copy Markdown
Contributor

@tylerjereddy tylerjereddy left a comment

Choose a reason for hiding this comment

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

In the recent review of my PR you indicate

Also a little worried that issubclass(np.timedelta64, numbers.Number) appears to still be true.

I don't see a test enforcing that this is no longer the case? Is that just a separate concern then?

This does look a lot less invasive than my hard blocking of all integer -> m8 conversions. Actually, I thought that was motivated by concerns about unit sloppiness, but maybe that discussion evolved in my absence (I'm 700 emails behind on NumPy now, I think :/).

Overall, looks like you and Sebastian are happier with this & you haven't modified any old unit tests, which is always nice for NumPy.

So I think I'm +1, though I'd say at least good to ping @jbrockmendel on whether this will empower the favorable refactoring inside pandas that was discussed in the context of the original/more invasive change. Perhaps a step in that direction, anyway?

# issue gh-12927
# this only applies to in-place floordiv //=, because the output type
# promotes to float which does not fit
a = np.array([1, 2], np.int64)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Any reason you changed the original regression test, based on the case originally reported in the issue? It looks like it should have no effect, but then why bother to change it from the original report /my PR?

Perhaps a larger array is more likely to detect problems, I suppose.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think I wanted to avoid any weird special cases caused by scalar casting rules. I suppose I should have tested both.

Comment thread numpy/core/src/multiarray/scalartypes.c.src
# Cannot cast safely from unsigned integer of the same size, which
# could overflow
assert_(np.can_cast('u8', 'm8', casting='same_kind'))
assert_(not np.can_cast('u8', 'm8', casting='safe'))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, these tests are very clean/nice. Seems pretty clear that this is type-size, not value-size.

@jbrockmendel
Copy link
Copy Markdown
Contributor

whether this will empower the favorable refactoring inside pandas that was discussed in the context of the original/more invasive change. Perhaps a step in that direction, anyway?

I don't know the numpy code well enough to infer from the diff how this will effect downstream behavior. Two candidates come to mind. Will it affect isinstance(td64, np.integer)? how about td64 + 1?

@eric-wieser
Copy link
Copy Markdown
Member Author

It might affect d64 + np.uint64(1) I suppose, but it won't affect anything that uses the signed int64.

@eric-wieser
Copy link
Copy Markdown
Member Author

eric-wieser commented Oct 29, 2019

@jbrockmendel

All this affects the behavior of outside the existing tests is code like

d = np.datetime64('now')
np.add(d, np.uint64([1, 2]), casting='safe')

td = np.timedelta64(1, 'D')
np.add(td, np.uint64([1, 2]), casting='safe')

that is:

  • Explicit safe casting
  • uint64 addition
  • Non-scalar operands

I doubt this will impact anything

@seberg
Copy link
Copy Markdown
Member

seberg commented Nov 17, 2019

Should we go forward with this, I think I am in favor, although it is now pretty close to 1.18 as a small downside (although the real test is usually the rc release in any case).

@mattip
Copy link
Copy Markdown
Member

mattip commented Nov 24, 2019

@seberg please check the release notes reflect the second commit.

@eric-wieser
Copy link
Copy Markdown
Member Author

Since this fixes a regression, I think we should go ahead with it.

@seberg
Copy link
Copy Markdown
Member

seberg commented Nov 25, 2019

OK, I think we can just squash-merge. The release notes are fine, without the second commit, same_kind also slightly changes, with the second commit, the same kind logic does not change.

@mattip mattip merged commit 4de3997 into numpy:master Nov 25, 2019
@mattip
Copy link
Copy Markdown
Member

mattip commented Nov 25, 2019

Thanks @eric-wieser, @seberg

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.

int64 //= uint64 succeeds in 1.16.1

5 participants