From 4f4ea45aa468cf49dff7bc98fbc5840c8b40766e Mon Sep 17 00:00:00 2001 From: Zhou Date: Thu, 27 Apr 2023 22:45:04 +0800 Subject: [PATCH 1/4] fix #103925 --- Lib/csv.py | 8 ++++---- Lib/test/test_csv.py | 5 +++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Lib/csv.py b/Lib/csv.py index 77f30c8d2b1f61d..b79c989db21d405 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 8fb97bc0c1a1a7e..aef0be0aab3b74d 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 = 'Timestamp,URL,Title\r\n2020-10-01 17:17:37+08:00,https://www.mozilla.org/en-US/firefox/welcome/2/,"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() From 80994d626cc0d5bdce5293944205341e83457518 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 27 Apr 2023 14:50:04 +0000 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2023-04-27-14-50-03.gh-issue-103925.khC-El.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2023-04-27-14-50-03.gh-issue-103925.khC-El.rst 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 000000000000000..70aad4bcbd7ed62 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-04-27-14-50-03.gh-issue-103925.khC-El.rst @@ -0,0 +1 @@ +_guess_quote_and_delimiter should be able to handle windows \r From b27806cf1f82c955a3045b07e92151c8aec48093 Mon Sep 17 00:00:00 2001 From: Zhou Wei Date: Thu, 27 Apr 2023 23:40:51 +0800 Subject: [PATCH 3/4] Update 2023-04-27-14-50-03.gh-issue-103925.khC-El.rst --- .../next/Library/2023-04-27-14-50-03.gh-issue-103925.khC-El.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 70aad4bcbd7ed62..30ae46588f99d2d 100644 --- 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 @@ -1 +1 @@ -_guess_quote_and_delimiter should be able to handle windows \r +support "\\r" in :func:`_guess_quote_and_delimiter` From bd808da93f234c686aa003275bee0868ed548a59 Mon Sep 17 00:00:00 2001 From: Zhou Date: Thu, 27 Apr 2023 23:52:24 +0800 Subject: [PATCH 4/4] fix #103925 --- Lib/csv.py | 8 ++++---- Lib/test/test_csv.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Lib/csv.py b/Lib/csv.py index b79c989db21d405..3801be9cd4249f1 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)(?:$|\r|\n)', # ,".*?" - r'(?:^|\n)(?P["\']).*?(?P=quote)(?:$|\r|\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 aef0be0aab3b74d..17ec4552aaa10d0 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -1189,7 +1189,7 @@ class TestSniffer(unittest.TestCase): ghijkl\0mno ghi\0jkl """ - sample15 = 'Timestamp,URL,Title\r\n2020-10-01 17:17:37+08:00,https://www.mozilla.org/en-US/firefox/welcome/2/,"Pocket - Save news, videos, stories and more"\r\n' + sample15 = 'time,title\r\n2020-10-01,"Pocket - Save news, videos, stories and more"\r\n' def test_issue43625(self):