]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-138621: Increase test coverage for csv.DictReader and csv.Sniffer (GH-13862...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Wed, 12 Nov 2025 00:58:15 +0000 (01:58 +0100)
committerGitHub <noreply@github.com>
Wed, 12 Nov 2025 00:58:15 +0000 (00:58 +0000)
gh-138621: Increase test coverage for csv.DictReader and csv.Sniffer (GH-138622)

* Increase test coverage for csv.DictReader and csv.Sniffer

Previously there were no tests for the DictReader fieldnames
setter, the case where a StopIteration was encountered when trying
to determine the fieldnames from the content or the case where
Sniffer could not find a delimiter.

* Revert whitespace change to comment

* Add a test that csv.Sniffer.has_header checks up to 20 rows

* Replace name and age with letter and offset

* Address review comment

---------
(cherry picked from commit 0e88be6f55f35ab045e57f9f869b893c15dcc099)

Co-authored-by: Jan-Eric Nitschke <47750513+JanEricNitschke@users.noreply.github.com>
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com>
Lib/test/test_csv.py

index 60feab225a107cdb33fecc2821974594086345c1..98ee0c3cdd7a06f4ed619c41caa2595810dac1da 100644 (file)
@@ -918,6 +918,14 @@ class TestDictFields(unittest.TestCase):
         reader = csv.DictReader(f, fieldnames)
         self.assertEqual(reader.fieldnames, fieldnames)
 
+    def test_dict_reader_set_fieldnames(self):
+        fieldnames = ["a", "b", "c"]
+        f = StringIO()
+        reader = csv.DictReader(f)
+        self.assertIsNone(reader.fieldnames)
+        reader.fieldnames = fieldnames
+        self.assertEqual(reader.fieldnames, fieldnames)
+
     def test_dict_writer_fieldnames_rejects_iter(self):
         fieldnames = ["a", "b", "c"]
         f = StringIO()
@@ -933,6 +941,7 @@ class TestDictFields(unittest.TestCase):
     def test_dict_reader_fieldnames_is_optional(self):
         f = StringIO()
         reader = csv.DictReader(f, fieldnames=None)
+        self.assertIsNone(reader.fieldnames)
 
     def test_read_dict_fields(self):
         with TemporaryFile("w+", encoding="utf-8") as fileobj:
@@ -1353,6 +1362,19 @@ ghijkl\0mno
 ghi\0jkl
 """
 
+    sample15 = "\n\n\n"
+    sample16 = "abc\ndef\nghi"
+
+    sample17 = ["letter,offset"]
+    sample17.extend(f"{chr(ord('a') + i)},{i}" for i in range(20))
+    sample17.append("v,twenty_one")  # 'u' was skipped
+    sample17 = '\n'.join(sample17)
+
+    sample18 = ["letter,offset"]
+    sample18.extend(f"{chr(ord('a') + i)},{i}" for i in range(21))
+    sample18.append("v,twenty_one")  # 'u' was not skipped
+    sample18 = '\n'.join(sample18)
+
     def test_issue43625(self):
         sniffer = csv.Sniffer()
         self.assertTrue(sniffer.has_header(self.sample12))
@@ -1374,6 +1396,11 @@ ghi\0jkl
         self.assertIs(sniffer.has_header(self.sample8), False)
         self.assertIs(sniffer.has_header(self.header2 + self.sample8), True)
 
+    def test_has_header_checks_20_rows(self):
+        sniffer = csv.Sniffer()
+        self.assertFalse(sniffer.has_header(self.sample17))
+        self.assertTrue(sniffer.has_header(self.sample18))
+
     def test_guess_quote_and_delimiter(self):
         sniffer = csv.Sniffer()
         for header in (";'123;4';", "'123;4';", ";'123;4'", "'123;4'"):
@@ -1423,6 +1450,10 @@ ghi\0jkl
         self.assertEqual(dialect.quotechar, "'")
         dialect = sniffer.sniff(self.sample14)
         self.assertEqual(dialect.delimiter, '\0')
+        self.assertRaisesRegex(csv.Error, "Could not determine delimiter",
+                               sniffer.sniff, self.sample15)
+        self.assertRaisesRegex(csv.Error, "Could not determine delimiter",
+                               sniffer.sniff, self.sample16)
 
     def test_doublequote(self):
         sniffer = csv.Sniffer()