From 429747f318e9e922e22e6e078423b2c558080481 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Mon, 25 Apr 2022 09:56:20 +0100 Subject: [PATCH 01/14] resolve issue1869, add a method to expand qname to URI --- rdflib/namespace/__init__.py | 20 +++++++++++++++ test/test_namespace/test_namespace.py | 37 +++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/rdflib/namespace/__init__.py b/rdflib/namespace/__init__.py index d1f158e59..f61fe4cff 100644 --- a/rdflib/namespace/__init__.py +++ b/rdflib/namespace/__init__.py @@ -590,6 +590,26 @@ def compute_qname_strict( return self.__cache_strict[uri] + def expand_qname(self, curie): + """ + Expand a qname (aka CURIE) of the form , e.g. "rdf:type" + into its full expression: + + >>> g = Graph() + >>> g.namespace_manager.expand_qname("rdf:type") + http://www.w3.org/1999/02/22-rdf-syntax-ns#type + + Returns None if a namespace is not bound to the prefix or the prefix + is malformed. + + """ + if ( + isinstance(curie, str) + and (prefix := curie.split(":")[0]) + and (ns := self.store.namespace(prefix)) + ): + return str(ns) + curie.split(":")[1] + def bind( self, prefix: Optional[str], diff --git a/test/test_namespace/test_namespace.py b/test/test_namespace/test_namespace.py index c1c2cb744..c43b74035 100644 --- a/test/test_namespace/test_namespace.py +++ b/test/test_namespace/test_namespace.py @@ -260,3 +260,40 @@ def test_contains_method(self): ref = URIRef("http://www.w3.org/2002/07/owl#real") assert ref in OWL, "OWL does not include owl:real" + + def test_expand_qname(self): + """Test sequential assignment of unknown prefixes""" + g = Graph() + + assert ( + g.namespace_manager.expand_qname("rdf:type") + == "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" + ) + + assert ( + g.namespace_manager.expand_qname("rdf:") + == "http://www.w3.org/1999/02/22-rdf-syntax-ns#" + ) + + g.bind("ex", Namespace("urn:example:")) + + assert g.namespace_manager.expand_qname("ex:tarek") == "urn:example:tarek" + + @pytest.mark.parametrize( + "invalid_curie", + [ + ("em:tarek"), + ("em:"), + ("em"), + (":"), + (":type"), + ("í"), + (" :"), + (""), + ("\n"), + (None), + ], + ) + def test_expand_qname_invalid_curie(self, invalid_curie: str) -> None: + g = Graph() + assert g.namespace_manager.expand_qname(invalid_curie) is None From 521e4dcfac36d7bca576a8fa0276960d348cb3e4 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Mon, 25 Apr 2022 10:08:55 +0100 Subject: [PATCH 02/14] meh, 3.7 still supported, no walruses :( --- rdflib/namespace/__init__.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/rdflib/namespace/__init__.py b/rdflib/namespace/__init__.py index f61fe4cff..9c0125f9b 100644 --- a/rdflib/namespace/__init__.py +++ b/rdflib/namespace/__init__.py @@ -603,12 +603,20 @@ def expand_qname(self, curie): is malformed. """ - if ( - isinstance(curie, str) - and (prefix := curie.split(":")[0]) - and (ns := self.store.namespace(prefix)) - ): - return str(ns) + curie.split(":")[1] + # TODO: When we drop support for 3.7 ... + # if ( + # isinstance(curie, str) + # and (prefix := curie.split(":")[0]) + # and (ns := self.store.namespace(prefix)) + # ): + # return str(ns) + curie.split(":")[1] + + if isinstance(curie, str) and ":" in curie: + ns = self.store.namespace(curie.split(":")[0]) + if ns is not None: + return ( + str(self.store.namespace(curie.split(":")[0])) + curie.split(":")[1] + ) def bind( self, From c930e3ea5495010a5564373edc3e932f2831a14f Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Mon, 25 Apr 2022 10:12:52 +0100 Subject: [PATCH 03/14] doh! --- rdflib/namespace/__init__.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/rdflib/namespace/__init__.py b/rdflib/namespace/__init__.py index 9c0125f9b..6623caf64 100644 --- a/rdflib/namespace/__init__.py +++ b/rdflib/namespace/__init__.py @@ -614,9 +614,7 @@ def expand_qname(self, curie): if isinstance(curie, str) and ":" in curie: ns = self.store.namespace(curie.split(":")[0]) if ns is not None: - return ( - str(self.store.namespace(curie.split(":")[0])) + curie.split(":")[1] - ) + return str(ns) + curie.split(":")[1] def bind( self, From 7e91fb6554c7866878067e2fa7a6dc41f164ba44 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Mon, 25 Apr 2022 10:16:29 +0100 Subject: [PATCH 04/14] attend to test docstring accuracy --- test/test_namespace/test_namespace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_namespace/test_namespace.py b/test/test_namespace/test_namespace.py index c43b74035..ab281f506 100644 --- a/test/test_namespace/test_namespace.py +++ b/test/test_namespace/test_namespace.py @@ -262,7 +262,6 @@ def test_contains_method(self): assert ref in OWL, "OWL does not include owl:real" def test_expand_qname(self): - """Test sequential assignment of unknown prefixes""" g = Graph() assert ( @@ -295,5 +294,6 @@ def test_expand_qname(self): ], ) def test_expand_qname_invalid_curie(self, invalid_curie: str) -> None: + """Test use of invalid CURIEs""" g = Graph() assert g.namespace_manager.expand_qname(invalid_curie) is None From 835ef45cbb520984c155e5ac503528ebed246897 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Mon, 25 Apr 2022 10:35:13 +0100 Subject: [PATCH 05/14] tsk, forgot to check docstring. --- rdflib/namespace/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rdflib/namespace/__init__.py b/rdflib/namespace/__init__.py index 6623caf64..0d0248395 100644 --- a/rdflib/namespace/__init__.py +++ b/rdflib/namespace/__init__.py @@ -595,7 +595,8 @@ def expand_qname(self, curie): Expand a qname (aka CURIE) of the form , e.g. "rdf:type" into its full expression: - >>> g = Graph() + >>> import rdflib + >>> g = rdflib.Graph() >>> g.namespace_manager.expand_qname("rdf:type") http://www.w3.org/1999/02/22-rdf-syntax-ns#type From 96a541a805480a6c5ccf75a523296c7f1596830d Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Mon, 25 Apr 2022 10:40:20 +0100 Subject: [PATCH 06/14] wrong guess, sigh --- rdflib/namespace/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rdflib/namespace/__init__.py b/rdflib/namespace/__init__.py index 0d0248395..17b952c05 100644 --- a/rdflib/namespace/__init__.py +++ b/rdflib/namespace/__init__.py @@ -598,7 +598,7 @@ def expand_qname(self, curie): >>> import rdflib >>> g = rdflib.Graph() >>> g.namespace_manager.expand_qname("rdf:type") - http://www.w3.org/1999/02/22-rdf-syntax-ns#type + 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' Returns None if a namespace is not bound to the prefix or the prefix is malformed. From 33ca64bfe8c371b5a59ecfa2c0c87cfd33573903 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Mon, 25 Apr 2022 11:46:09 +0100 Subject: [PATCH 07/14] hazard a guess at type hinting --- rdflib/namespace/__init__.py | 3 ++- test/test_namespace/test_namespace.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/rdflib/namespace/__init__.py b/rdflib/namespace/__init__.py index 17b952c05..cff70ddb7 100644 --- a/rdflib/namespace/__init__.py +++ b/rdflib/namespace/__init__.py @@ -590,7 +590,7 @@ def compute_qname_strict( return self.__cache_strict[uri] - def expand_qname(self, curie): + def expand_qname(self, curie: str) -> Union[str, None]: """ Expand a qname (aka CURIE) of the form , e.g. "rdf:type" into its full expression: @@ -616,6 +616,7 @@ def expand_qname(self, curie): ns = self.store.namespace(curie.split(":")[0]) if ns is not None: return str(ns) + curie.split(":")[1] + return None def bind( self, diff --git a/test/test_namespace/test_namespace.py b/test/test_namespace/test_namespace.py index ab281f506..89753e30f 100644 --- a/test/test_namespace/test_namespace.py +++ b/test/test_namespace/test_namespace.py @@ -261,7 +261,7 @@ def test_contains_method(self): ref = URIRef("http://www.w3.org/2002/07/owl#real") assert ref in OWL, "OWL does not include owl:real" - def test_expand_qname(self): + def test_expand_qname(self) -> None: g = Graph() assert ( From ab23b0a9f81a9a81aaf813d042944117379c3d9c Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Mon, 25 Apr 2022 21:36:24 +0100 Subject: [PATCH 08/14] changes in response to review --- rdflib/namespace/__init__.py | 21 ++++++-------- test/test_namespace/test_namespace.py | 41 ++++++++++++++------------- 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/rdflib/namespace/__init__.py b/rdflib/namespace/__init__.py index cff70ddb7..756822734 100644 --- a/rdflib/namespace/__init__.py +++ b/rdflib/namespace/__init__.py @@ -590,29 +590,24 @@ def compute_qname_strict( return self.__cache_strict[uri] - def expand_qname(self, curie: str) -> Union[str, None]: + def expand_curie(self, curie: str) -> Union[str, None]: """ Expand a qname (aka CURIE) of the form , e.g. "rdf:type" into its full expression: >>> import rdflib >>> g = rdflib.Graph() - >>> g.namespace_manager.expand_qname("rdf:type") + >>> g.namespace_manager.expand_curie("rdf:type") 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' - Returns None if a namespace is not bound to the prefix or the prefix - is malformed. + Returns None if a namespace is not bound to the prefix. """ - # TODO: When we drop support for 3.7 ... - # if ( - # isinstance(curie, str) - # and (prefix := curie.split(":")[0]) - # and (ns := self.store.namespace(prefix)) - # ): - # return str(ns) + curie.split(":")[1] - - if isinstance(curie, str) and ":" in curie: + if not type(curie) is str: + raise TypeError("Argument must be a string.") + elif ":" not in curie or curie.split(":")[0] == "" or curie.split(":")[1] == "": + raise ValueError("Malformed curie argument, format should be e.g. “foaf:name”.") + else: ns = self.store.namespace(curie.split(":")[0]) if ns is not None: return str(ns) + curie.split(":")[1] diff --git a/test/test_namespace/test_namespace.py b/test/test_namespace/test_namespace.py index 89753e30f..8b7012ddb 100644 --- a/test/test_namespace/test_namespace.py +++ b/test/test_namespace/test_namespace.py @@ -261,39 +261,40 @@ def test_contains_method(self): ref = URIRef("http://www.w3.org/2002/07/owl#real") assert ref in OWL, "OWL does not include owl:real" - def test_expand_qname(self) -> None: + def test_expand_curie(self) -> None: g = Graph() assert ( - g.namespace_manager.expand_qname("rdf:type") + g.namespace_manager.expand_curie("rdf:type") == "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" ) - assert ( - g.namespace_manager.expand_qname("rdf:") - == "http://www.w3.org/1999/02/22-rdf-syntax-ns#" - ) - g.bind("ex", Namespace("urn:example:")) - assert g.namespace_manager.expand_qname("ex:tarek") == "urn:example:tarek" + assert g.namespace_manager.expand_curie("ex:tarek") == "urn:example:tarek" @pytest.mark.parametrize( "invalid_curie", [ - ("em:tarek"), - ("em:"), - ("em"), - (":"), - (":type"), - ("í"), - (" :"), - (""), - ("\n"), - (None), + ("em:tarek", None), + ("em:", ValueError), + ("em", ValueError), + (":", ValueError), + (":type", ValueError), + ("í", ValueError), + (" :", ValueError), + ("", ValueError), + ("\n", ValueError), + (None, TypeError), + (99, TypeError), + (URIRef("urn:example:"), TypeError), ], ) - def test_expand_qname_invalid_curie(self, invalid_curie: str) -> None: + def test_expand_curie_invalid_curie(self, invalid_curie: str) -> None: """Test use of invalid CURIEs""" g = Graph() - assert g.namespace_manager.expand_qname(invalid_curie) is None + if invalid_curie[1] is not None: + with pytest.raises(invalid_curie[1]): + assert g.namespace_manager.expand_curie(invalid_curie[0]) + else: + assert g.namespace_manager.expand_curie(invalid_curie[0]) is None From 34173172a16d07abc953430548cd40a9e529d269 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Mon, 25 Apr 2022 21:55:22 +0100 Subject: [PATCH 09/14] re-black and adjust test --- rdflib/namespace/__init__.py | 4 +++- test/test_namespace/test_namespace.py | 29 +++++++++++++++------------ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/rdflib/namespace/__init__.py b/rdflib/namespace/__init__.py index 756822734..9a7c8f52e 100644 --- a/rdflib/namespace/__init__.py +++ b/rdflib/namespace/__init__.py @@ -606,7 +606,9 @@ def expand_curie(self, curie: str) -> Union[str, None]: if not type(curie) is str: raise TypeError("Argument must be a string.") elif ":" not in curie or curie.split(":")[0] == "" or curie.split(":")[1] == "": - raise ValueError("Malformed curie argument, format should be e.g. “foaf:name”.") + raise ValueError( + "Malformed curie argument, format should be e.g. “foaf:name”." + ) else: ns = self.store.namespace(curie.split(":")[0]) if ns is not None: diff --git a/test/test_namespace/test_namespace.py b/test/test_namespace/test_namespace.py index 8b7012ddb..6fb29baab 100644 --- a/test/test_namespace/test_namespace.py +++ b/test/test_namespace/test_namespace.py @@ -277,24 +277,27 @@ def test_expand_curie(self) -> None: "invalid_curie", [ ("em:tarek", None), - ("em:", ValueError), - ("em", ValueError), - (":", ValueError), - (":type", ValueError), - ("í", ValueError), - (" :", ValueError), - ("", ValueError), - ("\n", ValueError), - (None, TypeError), - (99, TypeError), - (URIRef("urn:example:"), TypeError), + ("em:", "ValueError"), + ("em", "ValueError"), + (":", "ValueError"), + (":type", "ValueError"), + ("í", "ValueError"), + (" :", "ValueError"), + ("", "ValueError"), + ("\n", "ValueError"), + (None, "TypeError"), + (99, "TypeError"), + (URIRef("urn:example:"), "TypeError"), ], ) def test_expand_curie_invalid_curie(self, invalid_curie: str) -> None: """Test use of invalid CURIEs""" g = Graph() - if invalid_curie[1] is not None: - with pytest.raises(invalid_curie[1]): + if invalid_curie[1] == "ValueError": + with pytest.raises(ValueError): + assert g.namespace_manager.expand_curie(invalid_curie[0]) + elif invalid_curie[1] == "TypeError": + with pytest.raises(TypeError): assert g.namespace_manager.expand_curie(invalid_curie[0]) else: assert g.namespace_manager.expand_curie(invalid_curie[0]) is None From e8ae054a69a04205d941c17f8f0eaaec1a9556f2 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Tue, 26 Apr 2022 15:27:28 +0100 Subject: [PATCH 10/14] "principle of least surprise" - return result as URIRef, not str --- rdflib/namespace/__init__.py | 4 ++-- test/test_namespace/test_namespace.py | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/rdflib/namespace/__init__.py b/rdflib/namespace/__init__.py index 9a7c8f52e..00e507e43 100644 --- a/rdflib/namespace/__init__.py +++ b/rdflib/namespace/__init__.py @@ -590,7 +590,7 @@ def compute_qname_strict( return self.__cache_strict[uri] - def expand_curie(self, curie: str) -> Union[str, None]: + def expand_curie(self, curie: str) -> Union[URIRef, None]: """ Expand a qname (aka CURIE) of the form , e.g. "rdf:type" into its full expression: @@ -612,7 +612,7 @@ def expand_curie(self, curie: str) -> Union[str, None]: else: ns = self.store.namespace(curie.split(":")[0]) if ns is not None: - return str(ns) + curie.split(":")[1] + return URIRef(str(ns) + curie.split(":")[1]) return None def bind( diff --git a/test/test_namespace/test_namespace.py b/test/test_namespace/test_namespace.py index 6fb29baab..75615f7e2 100644 --- a/test/test_namespace/test_namespace.py +++ b/test/test_namespace/test_namespace.py @@ -264,14 +264,17 @@ def test_contains_method(self): def test_expand_curie(self) -> None: g = Graph() - assert ( - g.namespace_manager.expand_curie("rdf:type") - == "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" + assert g.namespace_manager.expand_curie("rdf:type") == URIRef( + "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" ) + assert g.namespace_manager.expand_curie("rdf:type") == RDF.type + g.bind("ex", Namespace("urn:example:")) - assert g.namespace_manager.expand_curie("ex:tarek") == "urn:example:tarek" + assert g.namespace_manager.expand_curie("ex:tarek") == URIRef( + "urn:example:tarek" + ) @pytest.mark.parametrize( "invalid_curie", From 34925b9b800e2fb8ced84334eccdbb009df7f2d7 Mon Sep 17 00:00:00 2001 From: Iwan Aucamp Date: Tue, 26 Apr 2022 21:46:22 +0200 Subject: [PATCH 11/14] Fix handling of blank CURIE reference and references with multiple colons --- rdflib/namespace/__init__.py | 17 +++--- test/test_namespace/test_namespace.py | 77 ++++++++++++++------------- 2 files changed, 48 insertions(+), 46 deletions(-) diff --git a/rdflib/namespace/__init__.py b/rdflib/namespace/__init__.py index 00e507e43..39e4a2d90 100644 --- a/rdflib/namespace/__init__.py +++ b/rdflib/namespace/__init__.py @@ -592,27 +592,26 @@ def compute_qname_strict( def expand_curie(self, curie: str) -> Union[URIRef, None]: """ - Expand a qname (aka CURIE) of the form , e.g. "rdf:type" + Expand a CURIE of the form , e.g. "rdf:type" into its full expression: >>> import rdflib >>> g = rdflib.Graph() >>> g.namespace_manager.expand_curie("rdf:type") - 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' - - Returns None if a namespace is not bound to the prefix. + rdflib.term.URIRef('http://www.w3.org/1999/02/22-rdf-syntax-ns#type') + Returns `None` if a namespace is not bound to the prefix. """ if not type(curie) is str: raise TypeError("Argument must be a string.") - elif ":" not in curie or curie.split(":")[0] == "" or curie.split(":")[1] == "": + parts = curie.split(":", 1) + if len(parts) != 2 or len(parts[0]) < 1: raise ValueError( "Malformed curie argument, format should be e.g. “foaf:name”." ) - else: - ns = self.store.namespace(curie.split(":")[0]) - if ns is not None: - return URIRef(str(ns) + curie.split(":")[1]) + ns = self.store.namespace(parts[0]) + if ns is not None: + return URIRef(f"{str(ns)}{parts[1]}") return None def bind( diff --git a/test/test_namespace/test_namespace.py b/test/test_namespace/test_namespace.py index 75615f7e2..173a705ed 100644 --- a/test/test_namespace/test_namespace.py +++ b/test/test_namespace/test_namespace.py @@ -1,4 +1,7 @@ import unittest +from contextlib import ExitStack +from multiprocessing.sharedctypes import Value +from typing import Any, Optional, Type, Union from unittest.case import expectedFailure from warnings import warn @@ -261,46 +264,46 @@ def test_contains_method(self): ref = URIRef("http://www.w3.org/2002/07/owl#real") assert ref in OWL, "OWL does not include owl:real" - def test_expand_curie(self) -> None: - g = Graph() - - assert g.namespace_manager.expand_curie("rdf:type") == URIRef( - "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" - ) - - assert g.namespace_manager.expand_curie("rdf:type") == RDF.type - - g.bind("ex", Namespace("urn:example:")) - - assert g.namespace_manager.expand_curie("ex:tarek") == URIRef( - "urn:example:tarek" - ) - @pytest.mark.parametrize( - "invalid_curie", + ["curie", "expected_result"], [ + ("ex:tarek", URIRef("urn:example:tarek")), + ("ex:", URIRef(f"urn:example:")), + ("ex:a", URIRef(f"urn:example:a")), + ("ex:a:b", URIRef(f"urn:example:a:b")), + ("ex:a:b:c", URIRef(f"urn:example:a:b:c")), + ("ex", ValueError), ("em:tarek", None), - ("em:", "ValueError"), - ("em", "ValueError"), - (":", "ValueError"), - (":type", "ValueError"), - ("í", "ValueError"), - (" :", "ValueError"), - ("", "ValueError"), - ("\n", "ValueError"), - (None, "TypeError"), - (99, "TypeError"), - (URIRef("urn:example:"), "TypeError"), + ("em:", None), + ("em", ValueError), + (":", ValueError), + (":type", ValueError), + ("í", ValueError), + (" :", None), + ("", ValueError), + ("\n", ValueError), + (None, TypeError), + (3, TypeError), + (URIRef("urn:example:"), TypeError), ], ) - def test_expand_curie_invalid_curie(self, invalid_curie: str) -> None: - """Test use of invalid CURIEs""" - g = Graph() - if invalid_curie[1] == "ValueError": - with pytest.raises(ValueError): - assert g.namespace_manager.expand_curie(invalid_curie[0]) - elif invalid_curie[1] == "TypeError": - with pytest.raises(TypeError): - assert g.namespace_manager.expand_curie(invalid_curie[0]) + def test_expand_curie( + self, curie: Any, expected_result: Union[Type[Exception], URIRef, None] + ) -> None: + g = Graph(bind_namespaces="none") + nsm = g.namespace_manager + nsm.bind("ex", "urn:example:") + result: Optional[URIRef] = None + catcher: Optional[pytest.ExceptionInfo[Exception]] = None + with ExitStack() as xstack: + if isinstance(expected_result, type) and issubclass( + expected_result, Exception + ): + catcher = xstack.enter_context(pytest.raises(expected_result)) + result = g.namespace_manager.expand_curie(curie) + + if catcher is not None: + assert result is None + assert catcher.value is not None else: - assert g.namespace_manager.expand_curie(invalid_curie[0]) is None + assert expected_result == result From 17cffe24a21aec39d902b7f946a2eb7662a4086f Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Wed, 27 Apr 2022 00:11:59 +0100 Subject: [PATCH 12/14] Raise exception if prefix not bound, expand exception message, add test of objects/messages. --- rdflib/namespace/__init__.py | 10 ++++-- test/test_namespace/test_namespace.py | 44 ++++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/rdflib/namespace/__init__.py b/rdflib/namespace/__init__.py index 39e4a2d90..6dcf538b3 100644 --- a/rdflib/namespace/__init__.py +++ b/rdflib/namespace/__init__.py @@ -600,10 +600,11 @@ def expand_curie(self, curie: str) -> Union[URIRef, None]: >>> g.namespace_manager.expand_curie("rdf:type") rdflib.term.URIRef('http://www.w3.org/1999/02/22-rdf-syntax-ns#type') - Returns `None` if a namespace is not bound to the prefix. + Raises exception if a namespace is not bound to the prefix. + """ if not type(curie) is str: - raise TypeError("Argument must be a string.") + raise TypeError(f"Argument must be a string, not {type(curie).__name__}.") parts = curie.split(":", 1) if len(parts) != 2 or len(parts[0]) < 1: raise ValueError( @@ -612,7 +613,10 @@ def expand_curie(self, curie: str) -> Union[URIRef, None]: ns = self.store.namespace(parts[0]) if ns is not None: return URIRef(f"{str(ns)}{parts[1]}") - return None + else: + raise ValueError( + f"Prefix \"{curie.split(':')[0]}\" not bound to any namespace." + ) def bind( self, diff --git a/test/test_namespace/test_namespace.py b/test/test_namespace/test_namespace.py index 173a705ed..3c4b760bf 100644 --- a/test/test_namespace/test_namespace.py +++ b/test/test_namespace/test_namespace.py @@ -8,7 +8,7 @@ import pytest from rdflib import DCTERMS -from rdflib.graph import Graph +from rdflib.graph import BNode, Graph, Literal from rdflib.namespace import ( FOAF, OWL, @@ -264,6 +264,40 @@ def test_contains_method(self): ref = URIRef("http://www.w3.org/2002/07/owl#real") assert ref in OWL, "OWL does not include owl:real" + def test_expand_curie(self) -> None: + g = Graph() + + assert g.namespace_manager.expand_curie("rdf:type") == URIRef( + "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" + ) + + assert g.namespace_manager.expand_curie("rdf:type") == RDF.type + + g.bind("ex", Namespace("urn:example:")) + + assert g.namespace_manager.expand_curie("ex:tarek") == URIRef( + "urn:example:tarek" + ) + + def test_expand_curie_exception_messages(self) -> None: + g = Graph() + + with pytest.raises(TypeError) as e: + assert g.namespace_manager.expand_curie(URIRef("urn:example")) == None + assert str(e.value) == "Argument must be a string, not URIRef." + + with pytest.raises(TypeError) as e: + assert g.namespace_manager.expand_curie(Literal("rdf:type")) == None + assert str(e.value) == "Argument must be a string, not Literal." + + with pytest.raises(TypeError) as e: + assert g.namespace_manager.expand_curie(BNode()) == None + assert str(e.value) == "Argument must be a string, not BNode." + + with pytest.raises(TypeError) as e: + assert g.namespace_manager.expand_curie(Graph()) == None + assert str(e.value) == "Argument must be a string, not Graph." + @pytest.mark.parametrize( ["curie", "expected_result"], [ @@ -273,18 +307,20 @@ def test_contains_method(self): ("ex:a:b", URIRef(f"urn:example:a:b")), ("ex:a:b:c", URIRef(f"urn:example:a:b:c")), ("ex", ValueError), - ("em:tarek", None), - ("em:", None), + ("em:tarek", ValueError), + ("em:", ValueError), ("em", ValueError), (":", ValueError), (":type", ValueError), ("í", ValueError), - (" :", None), + (" :", ValueError), ("", ValueError), ("\n", ValueError), (None, TypeError), (3, TypeError), (URIRef("urn:example:"), TypeError), + (BNode(), TypeError), + (Literal("rdf:type"), TypeError), ], ) def test_expand_curie( From d61c5503cba3d4316f07c410d9403ee53ffc0a8d Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Wed, 27 Apr 2022 00:34:44 +0100 Subject: [PATCH 13/14] fix muffed merge --- test/test_namespace/test_namespace.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/test/test_namespace/test_namespace.py b/test/test_namespace/test_namespace.py index 3c4b760bf..52b3da746 100644 --- a/test/test_namespace/test_namespace.py +++ b/test/test_namespace/test_namespace.py @@ -264,20 +264,6 @@ def test_contains_method(self): ref = URIRef("http://www.w3.org/2002/07/owl#real") assert ref in OWL, "OWL does not include owl:real" - def test_expand_curie(self) -> None: - g = Graph() - - assert g.namespace_manager.expand_curie("rdf:type") == URIRef( - "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" - ) - - assert g.namespace_manager.expand_curie("rdf:type") == RDF.type - - g.bind("ex", Namespace("urn:example:")) - - assert g.namespace_manager.expand_curie("ex:tarek") == URIRef( - "urn:example:tarek" - ) def test_expand_curie_exception_messages(self) -> None: g = Graph() From 2aa449c98acc11cdfa4365383a3c9b3afb579ea2 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Wed, 27 Apr 2022 00:36:46 +0100 Subject: [PATCH 14/14] re-re-blacked --- test/test_namespace/test_namespace.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_namespace/test_namespace.py b/test/test_namespace/test_namespace.py index 52b3da746..15a923957 100644 --- a/test/test_namespace/test_namespace.py +++ b/test/test_namespace/test_namespace.py @@ -264,7 +264,6 @@ def test_contains_method(self): ref = URIRef("http://www.w3.org/2002/07/owl#real") assert ref in OWL, "OWL does not include owl:real" - def test_expand_curie_exception_messages(self) -> None: g = Graph()