@@ -1688,6 +1688,60 @@ def test_sniff_skipinitialspace_quoted(self):
16881688 self .assertEqual (dialect .quotechar , "'" )
16891689 self .assertIs (dialect .skipinitialspace , True )
16901690
1691+ def test_sniff_skipinitialspace_quoted_fields (self ):
1692+ # A quote is only a quote at the very start of a field, so not
1693+ # skipping the space splits the quoted field.
1694+ sniffer = csv .Sniffer ()
1695+ sample = 'a, "b,c"\n d,e\n f,g\n '
1696+ dialect = sniffer .sniff (sample )
1697+ self .assertEqual (dialect .delimiter , ',' )
1698+ self .assertEqual (dialect .quotechar , '"' )
1699+ self .assertIs (dialect .skipinitialspace , True )
1700+ self .assertEqual (next (csv .reader (StringIO (sample ), dialect )),
1701+ ['a' , 'b,c' ])
1702+
1703+ # But without a delimiter inside the quotes nothing is split,
1704+ # so only the padding counts.
1705+ sample = 'a, "b"\n d,e\n f,g\n '
1706+ dialect = sniffer .sniff (sample )
1707+ self .assertEqual (dialect .delimiter , ',' )
1708+ self .assertEqual (dialect .quotechar , '"' )
1709+ self .assertIs (dialect .skipinitialspace , False )
1710+ self .assertEqual (next (csv .reader (StringIO (sample ), dialect )),
1711+ ['a' , ' "b"' ])
1712+
1713+ def test_sniff_skipinitialspace_data (self ):
1714+ # The spaces are a part of the data if only some fields
1715+ # are padded.
1716+ sniffer = csv .Sniffer ()
1717+ sample = 'a, b\n c,d\n e, f\n '
1718+ dialect = sniffer .sniff (sample )
1719+ self .assertEqual (dialect .delimiter , ',' )
1720+ self .assertIs (dialect .skipinitialspace , False )
1721+ self .assertEqual (next (csv .reader (StringIO (sample ), dialect )),
1722+ ['a' , ' b' ])
1723+
1724+ def test_sniff_skipinitialspace_not_skipped (self ):
1725+ # A quoted or escaped space is not skipped, so it is not
1726+ # an evidence of the padding.
1727+ sniffer = csv .Sniffer ()
1728+ sample = 'a," b"\n c, d\n '
1729+ dialect = sniffer .sniff (sample )
1730+ self .assertEqual (dialect .delimiter , ',' )
1731+ self .assertEqual (dialect .quotechar , '"' )
1732+ self .assertIs (dialect .skipinitialspace , False )
1733+ self .assertEqual (list (csv .reader (StringIO (sample ), dialect )),
1734+ [['a' , ' b' ], ['c' , ' d' ]])
1735+
1736+ # The escaped delimiter forces the escapechar detection.
1737+ sample = 'a,\\ b\\ ,c\n d, e\n '
1738+ dialect = sniffer .sniff (sample )
1739+ self .assertEqual (dialect .delimiter , ',' )
1740+ self .assertEqual (dialect .escapechar , '\\ ' )
1741+ self .assertIs (dialect .skipinitialspace , False )
1742+ self .assertEqual (list (csv .reader (StringIO (sample ), dialect )),
1743+ [['a' , ' b,c' ], ['d' , ' e' ]])
1744+
16911745 def test_sniff_regex_backtracking (self ):
16921746 # gh-109638: this artificial sample used to take minutes.
16931747 sniffer = csv .Sniffer ()
0 commit comments