From 6477efdb74b581df57d80841133e22c8e5eeacec Mon Sep 17 00:00:00 2001 From: Kernc Date: Mon, 14 Dec 2020 18:39:03 +0100 Subject: [PATCH] ENH: Make ClosedNamespace extend str like Namespace does Useful for testing URIRef is from a particular namespace by means of: URIRef(...).startswith(NS) ^^^^^^^^^^^^^^^ where `URIRef.defrag()` currently wouldn't cut it. --- rdflib/namespace.py | 25 +++++++++++++------------ test/test_namespace.py | 5 ++++- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/rdflib/namespace.py b/rdflib/namespace.py index 056230c58..361dd2599 100644 --- a/rdflib/namespace.py +++ b/rdflib/namespace.py @@ -172,18 +172,21 @@ def __repr__(self): return "URIPattern(%r)" % str(self) -class ClosedNamespace(object): +class ClosedNamespace(str): """ A namespace with a closed list of members - Trying to create terms not listen is an error + Trying to create terms not listed is an error """ - def __init__(self, uri, terms): - self.uri = uri - self.__uris = {} - for t in terms: - self.__uris[t] = URIRef(self.uri + t) + def __new__(cls, uri, terms): + try: + rt = super().__new__(cls, uri) + except UnicodeDecodeError: + rt = super().__new__(cls, uri, "utf-8") + rt.uri = uri # back-compat + rt.__uris = {t: URIRef(rt + t) for t in terms} + return rt def term(self, name): uri = self.__uris.get(name) @@ -204,9 +207,6 @@ def __getattr__(self, name): except KeyError as e: raise AttributeError(e) - def __str__(self): - return str(self.uri) - def __repr__(self): return "rdf.namespace.ClosedNamespace(%r)" % str(self.uri) @@ -222,8 +222,9 @@ class _RDFNamespace(ClosedNamespace): Closed namespace for RDF terms """ - def __init__(self): - super(_RDFNamespace, self).__init__( + def __new__(cls): + return super().__new__( + cls, URIRef("http://www.w3.org/1999/02/22-rdf-syntax-ns#"), terms=[ # Syntax Names diff --git a/test/test_namespace.py b/test/test_namespace.py index 510d8515b..b6860e33c 100644 --- a/test/test_namespace.py +++ b/test/test_namespace.py @@ -111,6 +111,9 @@ def add_not_in_namespace(s): # a property name within the core FOAF namespace self.assertEqual( - add_not_in_namespace("givenName"), + FOAF.givenName, URIRef("http://xmlns.com/foaf/0.1/givenName"), ) + + # namescape can be used as str + self.assertTrue(FOAF.givenName.startswith(FOAF))