I am trying to read a csv file and read the field names (top row of csv file) from it. I used csv.Dictreader to create a reader object and extracted the top row using the reader.fieldnames object. I know that reader.fieldnames will be a list of strings for the kind of csv files I will be using. However, pylance considers the possibility that reader.fieldnames will be None and considers reader.fieldnames to be non-subscriptable.
Here's my code
import sys
import tabulate
import csv
import typing
def main() -> None:
menu: list[list[str]] = list()
try:
file: typing.TextIO
with open(sys.argv[1]) as file:
reader: csv.DictReader = csv.DictReader(file)
headings: list[str] = reader.fieldnames
row: dict[str,str]
for row in reader:
menu.append([row[headings[0]],row[headings[1]],row[headings[2]]])
except IOError:
sys.exit("CSV file does not exist")
else:
print(tabulate.tabulate(menu, headers=headings, tablefmt="grid"))
if __name__ == "__main__":
main()
If I use the list[str] type for headings, pylance complaints that
Expression of type "Sequence[Unknown] | None" cannot be assigned to declared type "list[str]"
However, if I skip the type hint for headings, pylance complaints with headings[0] that
Object of type "None" is not subscriptable
How do I deal with this problem? I could ignore pylance warnings, but I do not want to do so, unless there is no solution to this problem.
I'd say your best bet is to do a simple assert that heading is not None:
If it fails, you'll know to look at the CSV file for any kind of issues.
Sequence[str] | None.Sequence[str].Also, look at Barmar's and Mark Tolonen's comments, you can do what you much more simply by just reading the CSV as a list of strings: