mypy unable to analyse types of tuple elements in a list comprehension - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: mypy unable to analyse types of tuple elements in a list comprehension (/thread-40937.html) |
mypy unable to analyse types of tuple elements in a list comprehension - tomciodev - Oct-17-2023 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? RE: mypy unable to analyse types of tuple elements in a list comprehension - tomciodev - Oct-17-2023 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. |