Skip to content
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

TYP: concatenate typing produces unexpected errors #20901

Closed
bashtage opened this issue Jan 26, 2022 · 6 comments · Fixed by #21102
Closed

TYP: concatenate typing produces unexpected errors #20901

bashtage opened this issue Jan 26, 2022 · 6 comments · Fixed by #21102

Comments

@bashtage
Copy link
Contributor

Describe the issue:

Running mypy against 1.22.1 on correct code produces an error.

I think _SupportsArray seems to be wrong, and it should be _ArrayLike

Reproduce the code example:

import numpy as np

a = np.array([1.0])
b = [1.0]
np.concatenate((a,b))


### Error message:

```shell
error: Argument 1 to "concatenate" has incompatible type "Tuple[ndarray[Any, dtype[Any]], List[float]]"; expected "Union[_SupportsArray[dtype[<nothing>]], Sequence[_SupportsArray[dtype[<nothing>]]], Sequence[Sequence[_SupportsArray[dtype[<nothing>]]]], Sequence[Sequence[Sequence[_SupportsArray[dtype[<nothing>]]]]], Sequence[Sequence[Sequence[Sequence[_SupportsArray[dtype[<nothing>]]]]]]]"


### NumPy/Python version information:

`1.22.1 3.9.7 (default, Sep 16 2021, 16:59:28) [MSC v.1916 64 bit (AMD64)]`
@BvB93
Copy link
Member

BvB93 commented Jan 26, 2022

I think you may have stumbled upon a mypy bug related to the special casing of tuples. The first three cases succesfully pick the appropriate overload, but the last one somehow ends up at one that's meant for array-likes implementing __array__ (which list[int] does not, hence the appearance of <nothing>).

import numpy as np

np.concatenate((np.array(1), np.array(1)))  # No error
np.concatenate(([1], [1]))                  # No error
np.concatenate([[1], np.array(1)])          # No error
np.concatenate(([1], np.array(1)))          # Argument 1 to "concatenate" has incompatible type

@bashtage
Copy link
Contributor Author

bashtage commented Jan 26, 2022

Thanks @BvB93 . Is there a workaround, other than copying to a new array? I tried using list instead of tuple for input but it didn't have it. It seems to me having the array first is hitting the issue (this I can't change).

np.concatenate([np.array(1), [1]])

@BvB93
Copy link
Member

BvB93 commented Jan 26, 2022

I tried using list instead of tuple for input but it didn't have it.

I'm not sure if I'm following, does the example you provided in #20901 (comment) work or does it not? If it does, then I'd recommend replacing the outermost tuple with a list as a stopgap measure.

@bashtage
Copy link
Contributor Author

bashtage commented Jan 26, 2022

No, two errors.

np.concatenate([[1], np.array(1)])          #  Argument 1 to "concatenate" has incompatible type "List[object]"; expected "Union[_SupportsArray[dtype[<nothing>]], Sequence[_SupportsArray[dtype[<nothing>]]], Sequence[Sequence[_SupportsArray[dtype[<nothing>]]]], Sequence[Sequence[Sequence[_SupportsArray[dtype[<nothing>]]]]], Sequence[Sequence[Sequence[Sequence[_SupportsArray[dtype[<nothing>]]]]]]]"
np.concatenate(([1], np.array(1)))          # Argument 1 to "concatenate" has incompatible type "Tuple[List[int], ndarray[Any, dtype[Any]]]"; expected "Union[_SupportsArray[dtype[<nothing>]], Sequence[_SupportsArray[dtype[<nothing>]]], Sequence[Sequence[_SupportsArray[dtype[<nothing>]]]], Sequence[Sequence[Sequence[_SupportsArray[dtype[<nothing>]]]]], Sequence[Sequence[Sequence[Sequence[_SupportsArray[dtype[<nothing>]]]]]]]"

FWIW

mypy --version
mypy 0.931

@BvB93
Copy link
Member

BvB93 commented Jan 26, 2022

Weird, the error for the first one seems to disappear when using the numpy main branch (and I honestly have no idea why...).

I do think I've found the culprit though. ArrayLike consists four components, but it seems the last two are considered mutually exclusive. Should be easy to fix though by shuffeling the union around a bit:

  • Builtin scalar types
  • __array__ implementation
  • Nested sequences of builtins scalar types
  • Nested sequences of __array__ implementation

@JMMarchant
Copy link

I think you may have stumbled upon a mypy bug related to the special casing of tuples. The first three cases succesfully pick the appropriate overload, but the last one somehow ends up at one that's meant for array-likes implementing __array__ (which list[int] does not, hence the appearance of <nothing>).

If it's a mypy bug, has it been raised with them? I linked them to this issue here python/mypy#12144 but they've pushed back that it's a numpy bug and I don't have the context to know what the explicit bug is in mypy.

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

Successfully merging a pull request may close this issue.

3 participants