E5E7 MAINT: Make the refactor suggested in prepare_index by eric-wieser · Pull Request #8278 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
fixup! MAINT: Improve comments, simplify handling of tuple subclasses
  • Loading branch information
eric-wieser committed Jul 16, 2017
commit 105e0b4939a02ceda46ceb92f2978383cdc2b377
2 changes: 1 addition & 1 deletion numpy/core/src/multiarray/mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ unpack_indices(PyObject *index, PyObject **result, npy_intp result_n)
* allocation, but doesn't need to be a fast path anyway
*/
if (PyTuple_Check(index)) {
Copy link
Member Author
@eric-wieser eric-wieser Apr 9, 2017

Choose a reason for hiding this comment

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

The code here is subtly different to what we had before.

Calling PySequence_Tuple(index) invokes __iter__, whereas this invokes __getitem__.

So tuple subclasses that implement those methods inconsistently now behave differently. For instance:

class Plus1Tuple(tuple):
    def __getitem__(self, i):
        return super().__getitem__(i) + 1
    # oops, we forgot `__iter__`, and inherited `tuple.__iter__`, which
    # does not fall back on __getitem__

gives:

  • Before: a[PlusOneTuple([1, 2, 3])]a[1, 2, 3] (!)
  • After: a[PlusOneTuple([1, 2, 3])]a[2, 3, 4]

Copy link
Member

Choose a reason for hiding this comment

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

Can't you just remove this whole block and replace it with commit_to_unpack=1?

Copy link
Member

Choose a reason for hiding this comment

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

OK, plus a check for too many indices.

Copy link
Member

Choose a reason for hiding this comment

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

I am fine with the changed behaviour I think, a tuple subclass should really be OK even with just using PyTuple_GET_ITEM to be honest, otherwise it should be considered badly broken.

Copy link
Member Author
@eric-wieser eric-wieser Jul 16, 2017

Choose a reason for hiding this comment

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

Perhaps we should just bite the bullet here and call tuple(tuplesubclass), since efficiency isn't important for this weird case

Copy link
Member

Choose a reason for hiding this comment

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

Yea, I suppose we might just as well put whatever was there before, it won't make the code any uglier and speed really does not matter. But I no need to add a test or so (or if, put a comment that it is fine to break it). This is too strange to really worry about.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, changed to call tuple(tuplesubclass), which makes our life a lot easier

PyTupleObject *tup = PySequence_Tuple(index);
PyTupleObject *tup = (PyTupleObject *) PySequence_Tuple(index);
if (tup == NULL) {
return -1;
}
Expand Down
0