From 1d96b6f80e7dbda3bfec6f3eed45329877502934 Mon Sep 17 00:00:00 2001 From: KaifAhmad1 Date: Sat, 7 Mar 2026 03:03:44 +0530 Subject: [PATCH] fix: address code review issues from PR #358 (#355) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - rdf_exporter.py: add isinstance(format, str) guard before .lower() so non-string inputs (None, int, etc.) raise ValidationError consistently instead of AttributeError; normalize via strip().lower() in one step - 15_Export.ipynb: fix notebook cell using result['valid'] → result['overall_valid'] (validate_rdf() returns overall_valid, not valid); add trailing EOF newline - test_rdf_exporter.py: add tests for non-string format → ValidationError and for overall_valid key presence in validate_rdf() return value Co-Authored-By: Claude Sonnet 4.6 --- cookbook/introduction/15_Export.ipynb | 4 ++-- semantica/export/rdf_exporter.py | 7 ++++++- tests/export/test_rdf_exporter.py | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/cookbook/introduction/15_Export.ipynb b/cookbook/introduction/15_Export.ipynb index 3ccdb37d..3d6a8c10 100644 --- a/cookbook/introduction/15_Export.ipynb +++ b/cookbook/introduction/15_Export.ipynb @@ -180,7 +180,7 @@ }, { "cell_type": "code", - "source": "# TTL alias: format=\"ttl\" is equivalent to format=\"turtle\"\nrdf_data = {\n \"entities\": [\n {\"id\": \"e1\", \"text\": \"Apple Inc.\", \"type\": \"ORG\", \"confidence\": 0.95},\n {\"id\": \"e2\", \"text\": \"Steve Jobs\", \"type\": \"PERSON\", \"confidence\": 0.97},\n ],\n \"relationships\": [\n {\"source_id\": \"e2\", \"target_id\": \"e1\", \"type\": \"founded_by\", \"confidence\": 0.91},\n ],\n}\n\nrdf_exporter.export(rdf_data, \"output.ttl\", format=\"ttl\")\n\nresult = rdf_exporter.validate_rdf(rdf_data)\nprint(f\"Valid: {result['valid']}\")", + "source": "# TTL alias: format=\"ttl\" is equivalent to format=\"turtle\"\nrdf_data = {\n \"entities\": [\n {\"id\": \"e1\", \"text\": \"Apple Inc.\", \"type\": \"ORG\", \"confidence\": 0.95},\n {\"id\": \"e2\", \"text\": \"Steve Jobs\", \"type\": \"PERSON\", \"confidence\": 0.97},\n ],\n \"relationships\": [\n {\"source_id\": \"e2\", \"target_id\": \"e1\", \"type\": \"founded_by\", \"confidence\": 0.91},\n ],\n}\n\nrdf_exporter.export(rdf_data, \"output.ttl\", format=\"ttl\")\n\nresult = rdf_exporter.validate_rdf(rdf_data)\nprint(f\"Valid: {result['overall_valid']}\")", "metadata": {}, "execution_count": null, "outputs": [] @@ -370,4 +370,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} \ No newline at end of file +} diff --git a/semantica/export/rdf_exporter.py b/semantica/export/rdf_exporter.py index 85f33ebb..0c3035ca 100644 --- a/semantica/export/rdf_exporter.py +++ b/semantica/export/rdf_exporter.py @@ -901,7 +901,12 @@ class RDFExporter: ) try: - format = self._format_aliases.get(format.lower(), format.lower()) + if not isinstance(format, str): + raise ValidationError( + f"RDF format must be a string, got: {type(format).__name__}" + ) + fmt = format.strip().lower() + format = self._format_aliases.get(fmt, fmt) if format not in self.supported_formats: raise ValidationError( f"Unsupported RDF format: {format}. " diff --git a/tests/export/test_rdf_exporter.py b/tests/export/test_rdf_exporter.py index 2f662d18..e9d5f0c4 100644 --- a/tests/export/test_rdf_exporter.py +++ b/tests/export/test_rdf_exporter.py @@ -71,3 +71,21 @@ def test_ttl_export_to_file(exporter, tmp_path): exporter.export(RDF_DATA, str(out), format="ttl") assert out.exists() assert out.stat().st_size > 0 + + +def test_non_string_format_raises_validation_error(exporter): + """format=None or non-string must raise ValidationError, not AttributeError.""" + from semantica.utils.exceptions import ValidationError + + with pytest.raises(ValidationError): + exporter.export_to_rdf(RDF_DATA, format=None) + + with pytest.raises(ValidationError): + exporter.export_to_rdf(RDF_DATA, format=123) + + +def test_validate_rdf_returns_overall_valid_key(exporter): + """validate_rdf() must return 'overall_valid' key (used in notebook example).""" + result = exporter.validate_rdf(RDF_DATA) + assert "overall_valid" in result + assert isinstance(result["overall_valid"], bool)