122

Is it possible to use type hinting when unpacking a tuple? I want to do this, but it results in a SyntaxError:

from typing import Tuple

t: Tuple[int, int] = (1, 2)
a: int, b: int = t
#     ^ SyntaxError: invalid syntax
Alex Waygood
  • 6,304
  • 3
  • 24
  • 46
Cai
  • 1,726
  • 2
  • 15
  • 24
  • Since the types of the variables are already inferred from the unpacked values, you actually don't need to add type hints to them. – Jeyekomon Sep 02 '22 at 14:11
  • @Jeyekomon If the type inference is correct. Suppose my tuple comes from a function `def f() -> Tuple[int, int]: return 1, 2` and my unpacked `a, b = f()` both want `a: float` and `b: float`. – Cai Sep 02 '22 at 16:09
  • If your function returns a tuple of integers, the variables `a` and `b` will contain integers. No matter which type hints you'll use. – Jeyekomon Sep 05 '22 at 09:08
  • @Jeyekomon Indeed they will immediately after that assignment, but if I know `a` and `b` *should* be floats, and will contain floats later, then I'd like to hint them as floats regardless of what function gives their initial value or what hinting it has. – Cai Sep 06 '22 at 10:24
  • 1
    I understand what you're trying to do. The important point is - if those variables should be floats and you type hint them as floats, you should not assign an integer to them. It is not a good coding practice. Any variable should not change its type during its life. It will confuse other people, it will make linters complain. One of the many solutions to that is `a, b = (float(x) for x in f())`. – Jeyekomon Sep 08 '22 at 07:50
  • @Jeyekomon Ok, yes that is a really good point. Sorry I didn't understand you earlier. – Cai Sep 12 '22 at 08:40

2 Answers2

152

According to PEP-0526, you should annotate the types first, then do the unpacking

a: int
b: int
a, b = t
Patrick Haugh
  • 59,226
  • 13
  • 88
  • 96
  • 8
    Still triggers a warning: Redeclared 'a' defined above without usage – tribbloid Jan 18 '19 at 23:14
  • 1
    @tribbloid I get that when I have indeed already defined `a` earlier, are you certain you haven't done that? – joel Oct 22 '20 at 15:58
  • 1
    @tribbloid This is if the variable is redefined, like `a = int(a)` or other re-assignments. If you work with mypy for static type checking, use `--allow-redefinition` to avoid the warning – normanius Apr 14 '21 at 13:45
  • 6
    this is sad, how on earth : can not use any syntactical context, where variable assignment is legal... – g.pickardou Jun 09 '22 at 05:16
4

In my case i use the typing.cast function to type hint an unpack operation.

t: tuple[int, int] = (1, 2)
a, b = t

# type hint of a -> Literal[1]
# type hint of b -> Literal[2]

By using the cast(new_type, old_type) you can cast those ugly literals into integers.

from typing import cast

a, b = cast(tuple[int, int], t)

# type hint of a -> int
# type hint of b -> int

This can be useful while working with Numpy NDArrays with Unknown types

# type hint of arr -> ndarray[Unknown, Unknown]

a, b = cast(tuple[float, float], arr[i, j, :2]

# type hint of a -> float
# type hint of b -> float