Python Forum

Full Version: mypy unable to analyse types of tuple elements in a list comprehension
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
All presented code samples were tested with Python 3.11, and mypy 1.6.0.

And the problem is: mypy sees no problems in the following code:

MyTupleType = tuple[int, str, bool]
Tuples = list[MyTupleType]

def findAllByInt(values : Tuples, ref : int) -> Tuples:
  return [v for v in values if v[1] == ref]  # here is the bug!

vals : Tuples = [ (1, 'a', True), (2, 'b', False),
                  (3, 'c', True), (1, 'd', False) ]

print( findAllByInt(vals, 1) )
The problem is the tuple element index, which is compared to the referenced value. The element index should be 0, not 1. v[1] is a str, while v[0] is an int.

The only solution I was able to achieve is to use a separate function to extract the tuple element:

MyTupleType = tuple[int, str, bool]
Tuples = list[MyTupleType]

def intOfMyTuple(t : MyTupleType) -> int:
  return t[0]

def findAllByInt(values : Tuples, ref : int) -> Tuples:
  return [v for v in values if intOfMyTuple(v) == ref]

vals : Tuples = [ (1, 'a', True), (2, 'b', False),
                  (3, 'c', True), (1, 'd', False) ]

print( findAllByInt(vals, 1) )
Now, when we change the element index in intOfMyTuple, mypy will complain about the type mismatch, which is exactly what mypy should do.

The solution, though, is cumbersome: is it really neccessary to write separate functions for each tuple and element index I use in my code?

Or, perhaps, I'm doing something wrong, and mypy can be used to properly check the types in the first code sample?
OK, I have found a solution.

The cause of problem is in the return line of this function:

def findAllByInt(values : Tuples, ref : int) -> Tuples:
  return [v for v in values if v[1] == ref]  # here is the bug!
More precisely: the comparison v[1] == ref. The point is, this comparison is fine: there's nothing wrong with comparing apples to oranges. Of course, such comparisons will always be negative, since apples are not oranges (and in Python: ints are not strs).

The solution is to use --strict-equality mypy option, which makes such comparisons an error.

Sorry for bothering you with my problem.