DictReader should error on wrong column count

Viewed 167

Should Dialect.strict on a DictReader make it raise an exception if the number of columns in a line doesn't match the number of header columns?

The docs (emphasis mine):

To make it easier to specify the format of input and output records, specific formatting parameters are grouped together into dialects. A dialect is a subclass of the Dialect class having a set of specific methods and a single validate() method. When creating reader or writer objects, the programmer can specify a string or a subclass of the Dialect class as the dialect parameter. In addition to, or instead of, the dialect parameter, the programmer can also specify individual formatting parameters, which have the same names as the attributes defined below for the Dialect class.

Dialect.strict
When True, raise exception Error on bad CSV input. The default is False.

I interpret that as saying I can set strict=True on a DictReader and have it raise an Error if the number of fields in any line doesn't match the number of fields in the header row.

My code: test.py

import csv
from pathlib import Path

path = Path('mal.csv')
with path.open(newline="") as f:
    csv_reader = csv.DictReader(f, strict=True)
    for line in csv_reader:
        print(line)

My csv: mal.csv

This,Has,many,columns,of,text
This,misses,some
This,has,the,right,number,here
And,here,there,are,too,many,columns,sure,

python ./test.py doesn't raise an error and prints out the lines correctly. How can I make it error?

1 Answers

Given @juanpa.arrivillaga's comment, I guess strict doesn't do what I expected, and I altered my code to manually raise an error if there are any missing values by checking for None in .values() (since an empty item like ,, or ,\r\n is encoded as the empty string):

import csv
from pathlib import Path

path = Path('mal.csv')
with path.open(newline="") as f:
    csv_reader = csv.DictReader(f, strict=True)
    for line in csv_reader:
        if None in line.values() or None in line.keys():
            raise csv.Error(f"Missing or extra values on line {line}")
        print(line)

I also tried changing DictReader.restval to be a function or lambda that raises an exception, but this didn't work the way I wanted.

Related