summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIwan Aucamp <aucampia@gmail.com>2023-03-26 12:53:29 +0200
committerGitHub <noreply@github.com>2023-03-26 12:53:29 +0200
commit57bb42886b57a37f1ba93a4d1b52651d978d049c (patch)
treeac75957fa29dc49c39618b01fcc9dda29bcb4ea9
parent4da67f9a17ffe8fa128afcdd2259e337bccafaa3 (diff)
downloadrdflib-57bb42886b57a37f1ba93a4d1b52651d978d049c.tar.gz
fix: restore the 6.1.1 default bound namespaces (#2313)
The namespaces bound by default by `rdflib.graph.Graph` and `rdflib.namespace.NamespaceManager` was reduced in version 6.2.0 of RDFLib, however, this also would cause code that worked with 6.1.1 to break, so this constituted a breaking change. This change restores the previous behaviour, binding the same namespaces as was bound in 6.1.1. To bind a reduced set of namespaces, the `bind_namespaces` parameter of `rdflib.graph.Graph` or `rdflib.namespace.NamespaceManager` can be used. - Closes <https://github.com/RDFLib/rdflib/issues/2103>.
-rw-r--r--rdflib/graph.py2
-rw-r--r--rdflib/namespace/__init__.py15
-rw-r--r--test/test_graph/test_namespace_rebinding.py3
-rw-r--r--test/test_namespace/test_namespacemanager.py96
-rw-r--r--test/test_serializers/test_xmlwriter_qname.py4
-rw-r--r--test/test_sparql/test_service.py16
-rw-r--r--test/utils/httpservermock.py5
7 files changed, 121 insertions, 20 deletions
diff --git a/rdflib/graph.py b/rdflib/graph.py
index 7d32ab38..4a96e6d3 100644
--- a/rdflib/graph.py
+++ b/rdflib/graph.py
@@ -437,7 +437,7 @@ class Graph(Node):
identifier: Optional[Union[_ContextIdentifierType, str]] = None,
namespace_manager: Optional[NamespaceManager] = None,
base: Optional[str] = None,
- bind_namespaces: "_NamespaceSetString" = "core",
+ bind_namespaces: "_NamespaceSetString" = "rdflib",
):
super(Graph, self).__init__()
self.base = base
diff --git a/rdflib/namespace/__init__.py b/rdflib/namespace/__init__.py
index fb6d845b..c88fdedd 100644
--- a/rdflib/namespace/__init__.py
+++ b/rdflib/namespace/__init__.py
@@ -360,13 +360,13 @@ class NamespaceManager(object):
* core:
* binds several core RDF prefixes only
* owl, rdf, rdfs, xsd, xml from the NAMESPACE_PREFIXES_CORE object
- * this is default
* rdflib:
* binds all the namespaces shipped with RDFLib as DefinedNamespace instances
* all the core namespaces and all the following: brick, csvw, dc, dcat
* dcmitype, dcterms, dcam, doap, foaf, geo, odrl, org, prof, prov, qb, schema
* sh, skos, sosa, ssn, time, vann, void
* see the NAMESPACE_PREFIXES_RDFLIB object for the up-to-date list
+ * this is default
* none:
* binds no namespaces to prefixes
* note this is NOT default behaviour
@@ -374,6 +374,14 @@ class NamespaceManager(object):
* using prefix bindings from prefix.cc which is a online prefixes database
* not implemented yet - this is aspirational
+ .. attention::
+
+ The namespaces bound for specific values of ``bind_namespaces``
+ constitute part of RDFLib's public interface, so changes to them should
+ only be additive within the same minor version. Removing values, or
+ removing namespaces that are bound by default, constitutes a breaking
+ change.
+
See the
Sample usage
@@ -390,10 +398,11 @@ class NamespaceManager(object):
>>> all_ns = [n for n in g.namespace_manager.namespaces()]
>>> assert ('ex', rdflib.term.URIRef('http://example.com/')) in all_ns
>>>
-
"""
- def __init__(self, graph: "Graph", bind_namespaces: "_NamespaceSetString" = "core"):
+ def __init__(
+ self, graph: "Graph", bind_namespaces: "_NamespaceSetString" = "rdflib"
+ ):
self.graph = graph
self.__cache: Dict[str, Tuple[str, URIRef, str]] = {}
self.__cache_strict: Dict[str, Tuple[str, URIRef, str]] = {}
diff --git a/test/test_graph/test_namespace_rebinding.py b/test/test_graph/test_namespace_rebinding.py
index 3125d57e..15cf4473 100644
--- a/test/test_graph/test_namespace_rebinding.py
+++ b/test/test_graph/test_namespace_rebinding.py
@@ -3,7 +3,7 @@ from test.data import context1, context2, tarek
import pytest
from rdflib import ConjunctiveGraph, Graph, Literal
-from rdflib.namespace import OWL, Namespace
+from rdflib.namespace import OWL, Namespace, NamespaceManager
from rdflib.plugins.stores.memory import Memory
from rdflib.term import URIRef
@@ -294,6 +294,7 @@ def test_multigraph_bindings():
# Including newly-created objects that use the store
cg = ConjunctiveGraph(store=store)
+ cg.namespace_manager = NamespaceManager(cg, bind_namespaces="core")
assert ("foaf", foaf1_uri) not in list(cg.namespaces())
assert ("friend-of-a-friend", foaf1_uri) in list(cg.namespaces())
diff --git a/test/test_namespace/test_namespacemanager.py b/test/test_namespace/test_namespacemanager.py
index d79f0419..20cb9594 100644
--- a/test/test_namespace/test_namespacemanager.py
+++ b/test/test_namespace/test_namespacemanager.py
@@ -33,9 +33,41 @@ def test_core_prefixes_bound():
g = Graph()
# prefixes in Graph
- assert len(list(g.namespaces())) == len(_NAMESPACE_PREFIXES_CORE)
+ assert len(list(g.namespaces())) == len(
+ {**_NAMESPACE_PREFIXES_RDFLIB, **_NAMESPACE_PREFIXES_CORE}
+ )
pre = sorted([x[0] for x in list(g.namespaces())])
- assert pre == ["owl", "rdf", "rdfs", "xml", "xsd"]
+ assert pre == [
+ "brick",
+ "csvw",
+ "dc",
+ "dcam",
+ "dcat",
+ "dcmitype",
+ "dcterms",
+ "doap",
+ "foaf",
+ "geo",
+ "odrl",
+ "org",
+ "owl",
+ "prof",
+ "prov",
+ "qb",
+ "rdf",
+ "rdfs",
+ "schema",
+ "sh",
+ "skos",
+ "sosa",
+ "ssn",
+ "time",
+ "vann",
+ "void",
+ "wgs",
+ "xml",
+ "xsd",
+ ]
def test_rdflib_prefixes_bound():
@@ -176,6 +208,40 @@ def test_nman_bind_namespaces(
["selector", "expected_bindings"],
[
(
+ None,
+ {
+ "brick": "https://brickschema.org/schema/Brick#",
+ "csvw": "http://www.w3.org/ns/csvw#",
+ "dc": "http://purl.org/dc/elements/1.1/",
+ "dcat": "http://www.w3.org/ns/dcat#",
+ "dcmitype": "http://purl.org/dc/dcmitype/",
+ "dcterms": "http://purl.org/dc/terms/",
+ "dcam": "http://purl.org/dc/dcam/",
+ "doap": "http://usefulinc.com/ns/doap#",
+ "foaf": "http://xmlns.com/foaf/0.1/",
+ "odrl": "http://www.w3.org/ns/odrl/2/",
+ "geo": "http://www.opengis.net/ont/geosparql#",
+ "org": "http://www.w3.org/ns/org#",
+ "owl": "http://www.w3.org/2002/07/owl#",
+ "prof": "http://www.w3.org/ns/dx/prof/",
+ "prov": "http://www.w3.org/ns/prov#",
+ "qb": "http://purl.org/linked-data/cube#",
+ "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
+ "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
+ "schema": "https://schema.org/",
+ "sh": "http://www.w3.org/ns/shacl#",
+ "skos": "http://www.w3.org/2004/02/skos/core#",
+ "sosa": "http://www.w3.org/ns/sosa/",
+ "ssn": "http://www.w3.org/ns/ssn/",
+ "time": "http://www.w3.org/2006/time#",
+ "vann": "http://purl.org/vocab/vann/",
+ "void": "http://rdfs.org/ns/void#",
+ "wgs": "https://www.w3.org/2003/01/geo/wgs84_pos#",
+ "xsd": "http://www.w3.org/2001/XMLSchema#",
+ "xml": "http://www.w3.org/XML/1998/namespace",
+ },
+ ),
+ (
"rdflib",
{
"brick": "https://brickschema.org/schema/Brick#",
@@ -208,19 +274,39 @@ def test_nman_bind_namespaces(
"xsd": "http://www.w3.org/2001/XMLSchema#",
"xml": "http://www.w3.org/XML/1998/namespace",
},
- )
+ ),
+ (
+ "core",
+ {
+ "owl": "http://www.w3.org/2002/07/owl#",
+ "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
+ "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
+ "xsd": "http://www.w3.org/2001/XMLSchema#",
+ "xml": "http://www.w3.org/XML/1998/namespace",
+ },
+ ),
],
)
def test_bound_namespaces_subset(
- selector: Any, expected_bindings: Dict[str, str]
+ selector: Optional[Any], expected_bindings: Dict[str, str]
) -> None:
- graph = Graph(bind_namespaces=selector)
+ if selector is not None:
+ graph = Graph(bind_namespaces=selector)
+ else:
+ graph = Graph()
bound_namespaces = dict(
(key, str(value)) for key, value in graph.namespace_manager.namespaces()
)
assert (
expected_bindings.items() <= bound_namespaces.items()
), f"missing items {expected_bindings.items() - bound_namespaces.items()}"
+ empty_graph = Graph(bind_namespaces="none")
+ if selector is not None:
+ nman = NamespaceManager(empty_graph, bind_namespaces=selector)
+ else:
+ nman = NamespaceManager(empty_graph)
+ nman_bound_namespaces = dict((key, str(value)) for key, value in nman.namespaces())
+ assert bound_namespaces == nman_bound_namespaces
def test_compute_qname_no_generate() -> None:
diff --git a/test/test_serializers/test_xmlwriter_qname.py b/test/test_serializers/test_xmlwriter_qname.py
index 662d3f59..13ee84a0 100644
--- a/test/test_serializers/test_xmlwriter_qname.py
+++ b/test/test_serializers/test_xmlwriter_qname.py
@@ -10,7 +10,7 @@ TRIXNS = rdflib.Namespace("http://www.w3.org/2004/03/trix/trix-1/")
def test_xmlwriter_namespaces():
- g = rdflib.Graph()
+ g = rdflib.Graph(bind_namespaces="core")
with tempfile.TemporaryFile() as fp:
xmlwr = XMLWriter(fp, g.namespace_manager, extra_ns={"": TRIXNS, "ex": EXNS})
@@ -32,7 +32,7 @@ def test_xmlwriter_namespaces():
def test_xmlwriter_decl():
- g = rdflib.Graph()
+ g = rdflib.Graph(bind_namespaces="core")
with tempfile.TemporaryFile() as fp:
xmlwr = XMLWriter(fp, g.namespace_manager, decl=0, extra_ns={"": TRIXNS})
diff --git a/test/test_sparql/test_service.py b/test/test_sparql/test_service.py
index d83ac32e..3a827054 100644
--- a/test/test_sparql/test_service.py
+++ b/test/test_sparql/test_service.py
@@ -330,14 +330,16 @@ def test_with_mock(
"head": {"vars": ["var"]},
"results": {"bindings": [{"var": item} for item in response_bindings]},
}
- function_httpmock.responses[MethodName.GET].append(
- MockHTTPResponse(
- 200,
- "OK",
- json.dumps(response).encode("utf-8"),
- {"Content-Type": ["application/sparql-results+json"]},
- )
+ mock_response = MockHTTPResponse(
+ 200,
+ "OK",
+ json.dumps(response).encode("utf-8"),
+ {"Content-Type": ["application/sparql-results+json"]},
)
+ # Adding the same response for GET and POST as the method used by RDFLib is
+ # dependent on the size of the service query.
+ function_httpmock.responses[MethodName.GET].append(mock_response)
+ function_httpmock.responses[MethodName.POST].append(mock_response)
catcher: Optional[pytest.ExceptionInfo[Exception]] = None
with ExitStack() as xstack:
diff --git a/test/utils/httpservermock.py b/test/utils/httpservermock.py
index 54596feb..6a87bf19 100644
--- a/test/utils/httpservermock.py
+++ b/test/utils/httpservermock.py
@@ -96,7 +96,10 @@ class BaseHTTPServerMock:
logging.debug("headers %s", request.headers)
requests[method_name].append(request)
- response = responses[method_name].pop(0)
+ try:
+ response = responses[method_name].pop(0)
+ except IndexError as error:
+ raise ValueError(f"No response for {method_name} request") from error
handler.send_response(response.status_code, response.reason_phrase)
apply_headers_to(response.headers, handler)
handler.end_headers()