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

Concatenation of tuples #224

Closed
JukkaL opened this issue Jul 14, 2013 · 6 comments · Fixed by #7409
Closed

Concatenation of tuples #224

JukkaL opened this issue Jul 14, 2013 · 6 comments · Fixed by #7409
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal

Comments

@JukkaL
Copy link
Collaborator

JukkaL commented Jul 14, 2013

Concatenation of fixed-length tuples should be supported by the type checker.

Arbitrary tuples could be concatenated. Tuple[int, str] + Tuple[bool] results in Tuple[int, str, bool].

Concatenating two homogeneous tuples (Tuple[T, ...]) already works.

@bertrand-caron
Copy link

Hi @JukkaL, any update on this feature ? Currently, concatenating two fixed-lengths tuples results in a Unsupported operand types for + error and a messed up type as demonstrated by the example below:

a = (1,) # Tuple[int]
b = ('bob',) # Tuple[str]
c = a + b # Tuple[int, str]
reveal_type(a)
reveal_type(b)
reveal_type(c)
$ mypy a.py 
a.py:5: error: Unsupported operand types for + ("Tuple[int]" and "Tuple[str]")
a.py:13: error: Revealed type is 'Tuple[builtins.int]'
a.py:14: error: Revealed type is 'Tuple[builtins.str]'
a.py:15: error: Revealed type is 'builtins.tuple[builtins.int*]'

@JukkaL
Copy link
Collaborator Author

JukkaL commented May 3, 2017

Unfortunately nobody is working on this and this is not in our near-term roadmap. Adding a priority label so that contributors may be more likely to pick this up.

@JukkaL
Copy link
Collaborator Author

JukkaL commented Feb 21, 2018

Currently the concatenation of two tuples is accepted by mypy but the result has type Tuple[Any, ...].

@ilevkivskyi
Copy link
Member

This still give an error when mixing fixed length and homogeneous, see #6337

@doerwalter
Copy link

I would like to have support for that feature too. The following code:

from typing import *

def d2(x: int, y: int) -> Tuple[int, int]:
    return (x, y)

def d3(x: int, y: int, z: int) -> Tuple[int, int, int]:
    return d2(x, y) + (z,)

results in the mypy error: Incompatible return value type (got "Tuple[Any, ...]", expected "Tuple[int, int, int]")

@finite-state-machine
Copy link

finite-state-machine commented Apr 22, 2024

Is it reasonable to hope to extend this to Unions of Tuples?

from __future__ import annotations
from enum import Enum, auto
from typing import Literal, Tuple, Union

class AlignScope(Enum):
    TABLE = auto()
    ROW = auto()
    COL = auto()
    CELL = auto()

class AlignVert(Enum):
    TOP = auto()
    BOTTOM = auto()

class AlignHorz(Enum):
    LEFT = auto()
    RIGHT = auto()

AlignWhat = Union[
        Tuple[Literal[AlignScope.TABLE]],               # no address
        Tuple[Literal[AlignScope.ROW], int],            # row index
        Tuple[Literal[AlignScope.COL], int],            # col index
        Tuple[Literal[AlignScope.CELL], int, int],      # (row, col)
        ]

AlignHow = Union[
        # align vertically and/or horizontally (non-empty, max. 1× each):
        Tuple[AlignVert],
        Tuple[AlignHorz],
        Tuple[AlignVert, AlignHorz],
        Tuple[AlignHorz, AlignVert],
        ]

# PROPOSAL:
# AlignDirective = AlignWhat + AlignHow
# ...would be equivalent to...
AlignDirective = Union[
        Tuple[Literal[AlignScope.TABLE],          AlignVert],
        Tuple[Literal[AlignScope.TABLE],          AlignHorz],
        Tuple[Literal[AlignScope.TABLE],          AlignVert, AlignHorz],
        Tuple[Literal[AlignScope.TABLE],          AlignHorz, AlignVert],
        Tuple[Literal[AlignScope.ROW], int,       AlignVert],
        Tuple[Literal[AlignScope.ROW], int,       AlignHorz],
        Tuple[Literal[AlignScope.ROW], int,       AlignVert, AlignHorz],
        Tuple[Literal[AlignScope.ROW], int,       AlignHorz, AlignVert],
        Tuple[Literal[AlignScope.COL], int,       AlignVert],
        Tuple[Literal[AlignScope.COL], int,       AlignHorz],
        Tuple[Literal[AlignScope.COL], int,       AlignVert, AlignHorz],
        Tuple[Literal[AlignScope.COL], int,       AlignHorz, AlignVert],
        Tuple[Literal[AlignScope.CELL], int, int, AlignVert],
        Tuple[Literal[AlignScope.CELL], int, int, AlignHorz],
        Tuple[Literal[AlignScope.CELL], int, int, AlignVert, AlignHorz],
        Tuple[Literal[AlignScope.CELL], int, int, AlignHorz, AlignVert],
        ]

EDIT: I see now that #224 allows the type of two concatenated tuples to be understood, but does not allow concatenating the types themselves.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants