diff --git a/Lib/csv.py b/Lib/csv.py index 77f30c8d2b1f61..3801be9cd4249f 100644 --- a/Lib/csv.py +++ b/Lib/csv.py @@ -221,10 +221,10 @@ def _guess_quote_and_delimiter(self, data, delimiters): """ matches = [] - for restr in (r'(?P[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?P=delim)', # ,".*?", - r'(?:^|\n)(?P["\']).*?(?P=quote)(?P[^\w\n"\'])(?P ?)', # ".*?", - r'(?P[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?:$|\n)', # ,".*?" - r'(?:^|\n)(?P["\']).*?(?P=quote)(?:$|\n)'): # ".*?" (no delim, no space) + for restr in (r'(?P[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?P=delim)', # ,".*?", + r'(?:^|\n)(?P["\']).*?(?P=quote)(?P[^\w\n"\'])(?P ?)', # ".*?", + r'(?P[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?:$|\r|\n)', # ,".*?" + r'(?:^|\n)(?P["\']).*?(?P=quote)(?:$|\r|\n)'): # ".*?" (no delim, no space) regexp = re.compile(restr, re.DOTALL | re.MULTILINE) matches = regexp.findall(data) if matches: diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py index 6a4180e6d1b0a1..e8ecc4aa112709 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -1189,6 +1189,8 @@ class TestSniffer(unittest.TestCase): ghijkl\0mno ghi\0jkl """ + sample15 = 'time,title\r\n2020-10-01,"Pocket - Save news, videos, stories and more"\r\n' + def test_issue43625(self): sniffer = csv.Sniffer() @@ -1260,6 +1262,9 @@ def test_delimiters(self): self.assertEqual(dialect.quotechar, "'") dialect = sniffer.sniff(self.sample14) self.assertEqual(dialect.delimiter, '\0') + dialect = sniffer.sniff(self.sample15) + self.assertEqual(dialect.delimiter, ',') + self.assertEqual(dialect.quotechar, '"') def test_doublequote(self): sniffer = csv.Sniffer() diff --git a/Misc/NEWS.d/next/Library/2023-04-27-14-50-03.gh-issue-103925.khC-El.rst b/Misc/NEWS.d/next/Library/2023-04-27-14-50-03.gh-issue-103925.khC-El.rst new file mode 100644 index 00000000000000..30ae46588f99d2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-04-27-14-50-03.gh-issue-103925.khC-El.rst @@ -0,0 +1 @@ +support "\\r" in :func:`_guess_quote_and_delimiter`