Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mypy error: List or tuple literal expected as the second argument to namedtuple()

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.

like image 501
Yuval Pruss Avatar asked Jun 19 '17 19:06

Yuval Pruss


2 Answers

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).

like image 120
Michael0x2a Avatar answered Nov 12 '22 02:11

Michael0x2a


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).

like image 4
Dimitris Fasarakis Hilliard Avatar answered Nov 12 '22 01:11

Dimitris Fasarakis Hilliard