Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Lib/csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,8 @@ def _detect_skipinitialspace(self, lines, delimiter, quotechar,
counts = [[len(row) for row in rows] for rows in results]
if counts[0] != counts[1]:
# Prefer the more consistent row widths.
return len(set(counts[1])) <= len(set(counts[0]))
return (self._modal_share(counts[1])[1] >=
self._modal_share(counts[0])[1])
# Only some spaces are stripped. A field differs only if
# a space was skipped at its start, which tells the padding
# apart from the spaces inside quoted or escaped fields.
Expand Down
18 changes: 18 additions & 0 deletions Lib/test/test_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -1828,6 +1828,24 @@ def test_sniff_skipinitialspace_data(self):
self.assertEqual(next(csv.reader(StringIO(sample), dialect)),
['a', ' b'])

def test_sniff_skipinitialspace_empty_field(self):
# Skipping the spaces loses the empty field, which makes the row
# widths less consistent, also when the sample has another short
# row or is cut off in the middle of the last row.
sniffer = csv.Sniffer()
sample = ('name age city\n'
'alice 30 paris\n'
'bob london\n'
'carol 25 "new york"\n'
'dave 40 berlin\n')
for last in ('erin 35\n', 'erin 35'):
with self.subTest(last=last):
dialect = sniffer.sniff(sample + last)
self.assertEqual(dialect.delimiter, ' ')
self.assertIs(dialect.skipinitialspace, False)
rows = list(csv.reader(StringIO(sample), dialect))
self.assertEqual(rows[2], ['bob', '', 'london'])

def test_sniff_skipinitialspace_not_skipped(self):
# A quoted or escaped space is not skipped, so it is not
# an evidence of the padding.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fix :meth:`csv.Sniffer.sniff` returning ``skipinitialspace=True``
for a space-delimited sample with an unquoted empty field,
which made the sniffed dialect lose the field.
Loading