8000 BUG: np.compress casting fails from narrower to wider type · Issue #21676 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

BUG: np.compress casting fails from narrower to wider type #21676

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
pijyoi opened this issue Jun 6, 2022 · 3 comments
Open

BUG: np.compress casting fails from narrower to wider type #21676

pijyoi opened this issue Jun 6, 2022 · 3 comments

Comments

@pijyoi
Copy link
Contributor
pijyoi commented Jun 6, 2022

Describe the issue:

When the output type is wider than the input type, a TypeError is raised. (Expected no error)
Conversely, when the output type is narrower than the input type, no TypeError is raised. (Expected error)

Reproduce the code example:

import numpy as np 

def test(dtype_in, dtype_out):
    expected = np.can_cast(dtype_in, dtype_out)

    try:
        ain = np.arange(10, dtype=dtype_in)
        mask = ain < 5
        aout = np.empty(np.count_nonzero(mask), dtype=dtype_out)
        np.compress(mask, ain, out=aout)
    except TypeError:
        success = False
    else:
        success = True

    print(f'compress {dtype_in} to {dtype_out}; {expected=}; {success=}')

test('f8', 'i4')
test('i4', 'f8')

Error message:

compress f8 to i4; expected=False; success=True
compress i4 to f8; expected=True; success=False

NumPy/Python version information:

1.22.4 3.10.4 (tags/v3.10.4:9d38120, Mar 23 2022, 23:13:41) [MSC v.1929 64 bit (AMD64)]

@pijyoi pijyoi added the 00 - Bug label Jun 6, 2022
@seberg
Copy link
Member
seberg commented Jun 6, 2022

Thanks for the report! Seems like the check is the wrong way around. Maybe we can just get away with swapping it or maybe we should give a DeprecationWarning where it currently force-casts. Either should be straight forward to implement.
(I honestly would not be surprised if these type of issues exist for other less-used functions. EDIT: IIRC, it may still exist for take which is somewhat similar.)

@pijyoi
Copy link
Contributor Author
pijyoi commented Jun 7, 2022

The implementation seems to be in:
https://github.com/numpy/numpy/blob/main/numpy/core/src/multiarray/item_selection.c
PyArray_Compress eventually calls PyArray_TakeFrom

Also within the same file, the closest resembling function to PyArray_TakeFrom seems to be PyArray_Choose but the latter doesn't seem to have the same issue.

PyArray_TakeFrom calls PyArray_FromArray(out, dtype = input_dtype, flags = NPY_ARRAY_CARRAY | NPY_ARRAY_WRITEBACKIFCOPY)
whereas
PyArray_Choose calls PyArray_FromArray(out, dtype = input_dtype, flags = NPY_ARRAY_CARRAY | NPY_ARRAY_WRITEBACKIFCOPY | NPY_ARRAY_FORCECAST)

Within PyArray_FromArray, there is a casting check to see if "out" can be casted to "input_dtype", which doesn't seem to be right: we want to check the reverse.

@seberg
Copy link
Member
seberg commented Jun 7, 2022

Yeah, in that case, there was a start on this a very long time ago, see gh-16319. Probably just needs a champion to push it a bit (although I don't know if there was any complexity, I suspect the safe way to just deprecate what succeeds currently rather than remove it immediately).

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

No branches or pull requests

2 participants
0