Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: restore the 6.1.1 default bound namespaces #2313

Merged
merged 1 commit into from
Mar 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion rdflib/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ def __init__(
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
Expand Down
15 changes: 12 additions & 3 deletions rdflib/namespace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,20 +360,28 @@ 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
* cc:
* 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

Expand All @@ -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]] = {}
Expand Down
3 changes: 2 additions & 1 deletion test/test_graph/test_namespace_rebinding.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
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

Expand Down Expand Up @@ -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())
Expand Down
96 changes: 91 additions & 5 deletions test/test_namespace/test_namespacemanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down Expand Up @@ -175,6 +207,40 @@ def test_nman_bind_namespaces(
@pytest.mark.parametrize(
["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",
{
Expand Down Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions test/test_serializers/test_xmlwriter_qname.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


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})
Expand All @@ -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})
Expand Down
16 changes: 9 additions & 7 deletions test/test_sparql/test_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
5 changes: 4 additions & 1 deletion test/utils/httpservermock.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ def do_handler(handler: BaseHTTPRequestHandler) -> None:
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()
Expand Down