Index: Lib/csv.py =================================================================== --- Lib/csv.py (revision 87151) +++ Lib/csv.py (working copy) @@ -181,11 +181,11 @@ quotechar, doublequote, delimiter, skipinitialspace = \ self._guess_quote_and_delimiter(sample, delimiters) - if not delimiter: + if delimiter is None: delimiter, skipinitialspace = self._guess_delimiter(sample, delimiters) - if not delimiter: + if delimiter is None: raise Error("Could not determine delimiter") class dialect(Dialect): @@ -218,7 +218,7 @@ matches = [] for restr in ('(?P[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?P=delim)', # ,".*?", '(?:^|\n)(?P["\']).*?(?P=quote)(?P[^\w\n"\'])(?P ?)', # ".*?", - '(?P>[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?:$|\n)', # ,".*?" + '(?P[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?:$|\n)', # ,".*?" '(?:^|\n)(?P["\']).*?(?P=quote)(?:$|\n)'): # ".*?" (no delim, no space) regexp = re.compile(restr, re.DOTALL | re.MULTILINE) matches = regexp.findall(data) Index: Lib/test/test_csv.py =================================================================== --- Lib/test/test_csv.py (revision 87151) +++ Lib/test/test_csv.py (working copy) @@ -833,6 +833,29 @@ self.assertEqual(dialect.delimiter, "|") self.assertEqual(dialect.quotechar, "'") + # Issue 10515. + for i, (sample, expected_delimiter) in enumerate(( + # XXX: I'm not sure if first two make sense but they are + # the existing behavior. + ('abcde', 'e'), + ('a', 'a'), + ('a,"b,c",d\ne,f,g', ','), + ('"a,b",c,d\ne,f,g', ','), + ('a,b,"c,d"\ne,f,g', ','), + ('a,b,"c,d"\r\ne,f,g', ','), + # XXX: I don't know what the correct behavior should be for these. + # Currently the first one raises an error that the delimiter can't + # be determined while the second one returns '\r'. The second + # is obviously. + ('"a,b,c,d"\ne', ''), + ('"a,b,c,d"\r\ne', ''), + )): + def f(self, sample=sample, expected_delimiter=expected_delimiter): + dialect = csv.Sniffer().sniff(sample) + self.assertEqual(dialect.delimiter, expected_delimiter, + msg="sample was: {!r}".format(sample)) + locals()['test_delimiters_extended_{}'.format(i)] = f + def test_doublequote(self): sniffer = csv.Sniffer() dialect = sniffer.sniff(self.header)