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

Incompatible types for fixed-length list/tuple creation #10606

Closed
headtr1ck opened this issue Jun 9, 2021 · 5 comments
Closed

Incompatible types for fixed-length list/tuple creation #10606

headtr1ck opened this issue Jun 9, 2021 · 5 comments
Labels
bug mypy got something wrong

Comments

@headtr1ck
Copy link

Bug Report

When creating lists or tuples of a fixed (initial) length using multiplication with a constant (i.e. 3*[1]) mypy evaluates the type as "Tuple[XXX, ...]", even though the length of the list/tuple is known.
This leads to incompatibilities when assigning values to existing variables that were constructed "classically" (i.e. [1, 1, 1]).

I don't know if this is intentional or actually a bug.
If the type will be changed to "Tuple[XXX, XXX, XXX]" this could lead to long expressions for long lists (i.e. 1e4*[1]).
Is it possible to remove the incompatibility or will this lead to other inconsistencies?

To Reproduce

Here is a minimal example on how to reproduce the problem:

var = (1, 2, 3)
var = 3 * (1,)

I know, that this is quite useless code, but a more often encountered code example with the same problem would be:

if cond:
  var = (1, 2, 3)
else:
  var = 3 * (1,)

Expected Behavior

Both expressions should evaluate to Tuple[int, int, int] OR be compatible.

Actual Behavior

This raises:
Incompatible types in assignment (expression has type "Tuple[int, ...]", variable has type "Tuple[int, int, int]")

Your Environment

  • Mypy version used: 0.812
  • Mypy command-line flags: /
  • Mypy configuration options from mypy.ini (and other config files): /
  • Python version used: 3.9.1
  • Operating system and version: redhat enterprise linux 7

Comment

I have no idea what the operation 5*(1,) is called, so I could not find anything about this problem. Sorry, if this was asked/resolved before.

@headtr1ck headtr1ck added the bug mypy got something wrong label Jun 9, 2021
@Akuli
Copy link
Contributor

Akuli commented Jun 9, 2021

This should be a typeshed issue. We can improve this by adding overloads for tuple.__mul__ in typeshed/stdlib/builtins.pyi.

@headtr1ck
Copy link
Author

I think currently it is not possible to add this feature since fixed length tuples with integer generics are still a problem, see the open discussion #3345.
So an overload of the type

    def __mul__(self, n: SupportsIndex) -> Tuple[n *(_T_co, )]: ...

is not possible yet.
Any other suggestions?

@Akuli
Copy link
Contributor

Akuli commented Oct 12, 2021

You're right. This isn't possible, not even with Literal, because apparently typeshed only defines arbitrary-length tuples.

@Akuli
Copy link
Contributor

Akuli commented Oct 25, 2021

This now works correctly on master, and the resulting type is a tuple of 3 ints.

(env310) akuli@akuli-desktop:~/mypy$ cat a.py
var = (1, 2, 3)
var = 3 * (1,)
(env310) akuli@akuli-desktop:~/mypy$ python3 -m mypy a.py
Success: no issues found in 1 source file
(env310) akuli@akuli-desktop:~/mypy$ echo 'reveal_type(var)' >> a.py
(env310) akuli@akuli-desktop:~/mypy$ python3 -m mypy a.py
a.py:3: note: Revealed type is "Tuple[builtins.int, builtins.int, builtins.int]"

@ethanhs
Copy link
Collaborator

ethanhs commented Oct 25, 2021

Confirmed as fixed in master.

@ethanhs ethanhs closed this as completed Oct 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

3 participants