I wrote this code in Python 3.5:
from collections import namedtuple
attributes = ('content', 'status')
Response = namedtuple('Response', attributes)
When I run the Mypy type checker to analyze this code it raised the error:
error: List or tuple literal expected as the second argument to
namedtuple()
I tried to add a type annotation to the attributes
variable:
from typing import Tuple
attributes = ('content', 'status') # type: Tuple[str, str]
But it didn't fix the raised error.
If you want mypy to understand what your namedtuples look like, you should import NamedTuple
from the typing
module, like so:
from typing import NamedTuple
Response = NamedTuple('Response', [('content', str), ('status', str)])
Then, you can use Response
just like any other namedtuple, except that mypy now understands the types of each individual field. If you're using Python 3.6, you can also use the alternative class-based syntax:
from typing import NamedTuple
class Response(NamedTuple):
content: str
status: str
If you were hoping to dynamically vary the fields and write something that can "build" different namedtuples at runtime, that's unfortunately not possible within Python's type ecosystem. PEP 484 currently doesn't any provisions for propagating or extracting the actual values of any given variable during the type-checking phase.
It's actually pretty challenging to implement this in a fully general way, so it's unlikely this feature will be added any time soon (and if it is, it'll likely be in a much more limited form).
According to issue 848 on mypy
's issue tracker, this will just never be implemented (see last message by GvR).
Though # type: ignore
does actually silence this warning it then creates other issues, so, if you can, don't depend on dynamically specifying the field names of the namedtuple (i.e provide the literal in the ways Michael's answer provides).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With