From a5ca6327abc6834b5f63fc7efe3c9ec7ef8a1f39 Mon Sep 17 00:00:00 2001 From: Marlon Costa Date: Sat, 26 Sep 2026 20:14:00 -0300 Subject: [PATCH] feat(files): csv_dumps mirrors csv_loads at the csv boundary Consumers that render CSV (ArtifactPack binding) reached for the raw csv module because the boundary exposed only the parse side. csv_dumps serializes rows with LF terminators so csv_loads round-trips exactly. --- .../_files_parts/flextcliutilitiesfiles_part_04.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/flext_cli/_utilities/_files_parts/flextcliutilitiesfiles_part_04.py b/src/flext_cli/_utilities/_files_parts/flextcliutilitiesfiles_part_04.py index a66ddcd4a..86e77c7e7 100644 --- a/src/flext_cli/_utilities/_files_parts/flextcliutilitiesfiles_part_04.py +++ b/src/flext_cli/_utilities/_files_parts/flextcliutilitiesfiles_part_04.py @@ -3,6 +3,7 @@ from __future__ import annotations import csv +import io import shutil import tempfile from collections.abc import Mapping @@ -109,6 +110,13 @@ def csv_loads(text: str, *, delimiter: str = ",") -> p.Result[list[list[str]]]: return r[list[list[str]]].fail(f"csv_loads: {exc}", exception=exc) return r[list[list[str]]].ok(rows) + @staticmethod + def csv_dumps(rows: list[list[str]], *, delimiter: str = ",") -> str: + """Serialize rows into a CSV-encoded string with LF terminators.""" + buffer = io.StringIO() + csv.writer(buffer, delimiter=delimiter, lineterminator="\n").writerows(rows) + return buffer.getvalue() + @staticmethod def files_copy_directory( source_path: t.Cli.TextPath,