From 63d42405476741b35832ef34364de0d2685708ad Mon Sep 17 00:00:00 2001 From: Shubham Padkonde Date: Mon, 26 Oct 2026 16:06:09 +0530 Subject: [PATCH] fix: accept UTF-8 signatures in tabular input --- databusclient/filehandling/format.py | 4 ++-- tests/test_tabular_bom.py | 33 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 tests/test_tabular_bom.py diff --git a/databusclient/filehandling/format.py b/databusclient/filehandling/format.py index 262f61e..c1cd4ec 100644 --- a/databusclient/filehandling/format.py +++ b/databusclient/filehandling/format.py @@ -411,7 +411,7 @@ def read(self, source: str, input_format: str) -> list: f"Supported: {list(TABULAR_FORMATS)}" ) delimiter = TABULAR_FORMATS[input_format] - with open(source, "r", newline="", encoding="utf-8") as f: + with open(source, "r", newline="", encoding="utf-8-sig") as f: reader = csv.reader(f, delimiter=delimiter) return list(reader) @@ -592,4 +592,4 @@ def convert_file( raise ValueError( f"Conversion from '{input_format}' ({input_class}) to " f"'{convert_format}' ({output_class}) is not supported." - ) \ No newline at end of file + ) diff --git a/tests/test_tabular_bom.py b/tests/test_tabular_bom.py new file mode 100644 index 0000000..6a6ab21 --- /dev/null +++ b/tests/test_tabular_bom.py @@ -0,0 +1,33 @@ +"""UTF-8 signatures must not become part of tabular column names.""" + +import csv + +import pytest +from rdflib import Graph, Literal, URIRef + +from databusclient.filehandling.format import TSDHandler +from databusclient.filehandling.mapping import convert_csv_to_rdf + + +@pytest.mark.parametrize("input_format,delimiter", [("csv", ","), ("tsv", "\t")]) +@pytest.mark.parametrize("encoding", ["utf-8", "utf-8-sig"]) +def test_tabular_conversion_accepts_utf8_bom(tmp_path, input_format, delimiter, encoding): + source = tmp_path / f"input.{input_format}" + rows = [["resource", "https://example.org/name"], ["alice", "Zoë\ufeff Smith"]] + with source.open("w", encoding=encoding, newline="") as stream: + csv.writer(stream, delimiter=delimiter).writerows(rows) + + assert TSDHandler().read(str(source), input_format) == rows + + output = tmp_path / "output.ttl" + convert_csv_to_rdf( + str(source), str(output), input_format, "turtle", "https://example.org" + ) + graph = Graph().parse(output, format="turtle") + assert set(graph) == { + ( + URIRef("https://example.org/alice"), + URIRef("https://example.org/name"), + Literal("Zoë\ufeff Smith"), + ) + }