From 23202e91a59a81d954ed28f10638c2a199f4fa9f Mon Sep 17 00:00:00 2001 From: fhgffy <102001626+fhgffy@users.noreply.github.com> Date: Sun, 11 Oct 2026 04:04:06 +0800 Subject: [PATCH] Preserve CSV record endings while decoding --- benedict/serializers/csv.py | 3 ++- tests/serializers/test_csv_serializer.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/benedict/serializers/csv.py b/benedict/serializers/csv.py index af59bd03..eae1a08f 100644 --- a/benedict/serializers/csv.py +++ b/benedict/serializers/csv.py @@ -27,7 +27,8 @@ def decode(self, s: str, **kwargs: Any) -> list[dict[str, Any]]: kwargs.setdefault("quoting", csv.QUOTE_ALL) columns = kwargs.pop("columns", None) columns_row = kwargs.pop("columns_row", True) - f = StringIO(s) + # 2026-10-11: Let csv handle record endings and preserve quoted newlines. + f = StringIO(s, newline="") r = csv.reader(f, **kwargs) ln = 0 data = [] diff --git a/tests/serializers/test_csv_serializer.py b/tests/serializers/test_csv_serializer.py index 5b8bef14..1e97ecf7 100644 --- a/tests/serializers/test_csv_serializer.py +++ b/tests/serializers/test_csv_serializer.py @@ -12,6 +12,19 @@ def test_decode_csv(self) -> None: # TODO pass + # 2026-10-11: CSV readers accept CR, LF and CRLF without rewriting quoted data. + def test_decode_csv_newlines(self) -> None: + from benedict.serializers import CSVSerializer + + serializer = CSVSerializer() + for newline in ("\r", "\n", "\r\n"): + with self.subTest(newline=newline): + text = f'name,note{newline}Alice,"first\r\nsecond"{newline}' + self.assertEqual( + serializer.decode(text), + [{"name": "Alice", "note": "first\r\nsecond"}], + ) + def test_encode_csv(self) -> None: # TODO pass