Rjmcf
Rjmcf

Reputation: 31

mypy: Can you specify that a Python function takes a list of a single type, but that type can be any type?

I'm trying to write a type annotation for the following function (Python 3.9.7):

def first(the_list):
    return the_list[0]

This should accept a list of any single type, and return a member of that type. As I understand it, you'd do that like this:

from typing import TypeVar

T = TypeVar('T')

def first(the_list : list[T]) -> T:
    return the_list[0]

I'm testing this with the following:

print(first([2,3,4]))            # Fine
print(first(["hello", "world"])) # Fine
print(first(["hello", 5]))       # This should error

running mypy (0.910) like this:

mypy --strict .

and the result I get is this:

Success: no issues found in 1 source file

I've made sure that it is running on the correct file, I can definitely get errors, but I'm not getting an error in this case. Am I misunderstanding something?

Upvotes: 2

Views: 617

Answers (1)

Rjmcf
Rjmcf

Reputation: 31

After further investigation (using reveal_type which I forgot existed), of course ["hello", 5] is passed as a list of a single type, that type is object.

I'm new to mypy but have studied typing and types at university, so I had a certain expectation for how it was going to work. When I discovered that this example seemed "broken" I was worried that maybe I shouldn't continue with mypy. On reflection, this is a very contrived example, and doesn't indicate that mypy Generics in general are weak, but just demonstrates how they behave when passed a literal whose most restricted type is list[object].

Upvotes: 1

Related Questions