Skip to content

Commit 8a92d35

Browse files
authored
Merge pull request RDFLib#1821 from edmondchuc/fix-issue-1808
Fix issue 1808
2 parents 65cae4e + 6b5850d commit 8a92d35

File tree

6 files changed

+169
-10
lines changed

6 files changed

+169
-10
lines changed

rdflib/graph.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
from urllib.request import url2pathname
2424
from warnings import warn
2525

26-
import rdflib.term
2726
import rdflib.util # avoid circular dependency
2827
from rdflib import exceptions, namespace, plugin, query
2928
from rdflib.collection import Collection
@@ -34,7 +33,7 @@
3433
from rdflib.resource import Resource
3534
from rdflib.serializer import Serializer
3635
from rdflib.store import Store
37-
from rdflib.term import BNode, Genid, IdentifiedNode, Literal, Node, URIRef
36+
from rdflib.term import BNode, Genid, IdentifiedNode, Literal, Node, RDFLibGenid, URIRef
3837

3938
assert Literal # avoid warning
4039
assert Namespace # avoid warning
@@ -1512,10 +1511,17 @@ def do_de_skolemize(uriref, t):
15121511

15131512
def do_de_skolemize2(t):
15141513
(s, p, o) = t
1515-
if isinstance(s, Genid):
1516-
s = s.de_skolemize()
1517-
if isinstance(o, Genid):
1518-
o = o.de_skolemize()
1514+
1515+
if RDFLibGenid._is_rdflib_skolem(s):
1516+
s = RDFLibGenid(s).de_skolemize()
1517+
elif Genid._is_external_skolem(s):
1518+
s = Genid(s).de_skolemize()
1519+
1520+
if RDFLibGenid._is_rdflib_skolem(o):
1521+
o = RDFLibGenid(o).de_skolemize()
1522+
elif Genid._is_external_skolem(o):
1523+
o = Genid(o).de_skolemize()
1524+
15191525
return s, p, o
15201526

15211527
retval = Graph() if new_graph is None else new_graph

rdflib/term.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ def skolemize(
486486
if basepath is None:
487487
basepath = rdflib_skolem_genid
488488
skolem = "%s%s" % (basepath, str(self))
489-
return RDFLibGenid(urljoin(authority, skolem))
489+
return URIRef(urljoin(authority, skolem))
490490

491491

492492
class Literal(Identifier):
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import logging
2+
import re
3+
from test.testutils import GraphHelper
4+
from typing import Pattern, Union
5+
6+
import pytest
7+
8+
from rdflib import Graph
9+
from rdflib.namespace import Namespace
10+
from rdflib.term import BNode, Literal, URIRef
11+
12+
EG = Namespace("http://example.com/")
13+
14+
base_triples = {
15+
(EG.subject, EG.predicate, EG.object0),
16+
(EG.subject, EG.predicate, EG.object1),
17+
}
18+
19+
20+
@pytest.mark.parametrize(
21+
["node", "expected_uri"],
22+
[
23+
(URIRef("http://example.com"), None),
24+
(Literal("some string in here ..."), None),
25+
(BNode("GMeng4V7"), "http://rdlib.net/.well-known/genid/rdflib/GMeng4V7"),
26+
(
27+
BNode(),
28+
re.compile("^" + re.escape("http://rdlib.net/.well-known/genid/rdflib/")),
29+
),
30+
],
31+
)
32+
def test_skolemization(
33+
node: Union[BNode, URIRef, Literal], expected_uri: Union[Pattern[str], str, None]
34+
) -> None:
35+
g = Graph()
36+
for triple in base_triples:
37+
g.add(triple)
38+
g.add((EG.scheck, EG.pcheck, node))
39+
assert len(g) == 3
40+
dsg = g.skolemize()
41+
if expected_uri is None:
42+
GraphHelper.assert_sets_equals(g, dsg)
43+
else:
44+
assert len(dsg) == len(g)
45+
iset = GraphHelper.triple_or_quad_set(dsg)
46+
logging.debug("iset = %s", iset)
47+
assert iset.issuperset(base_triples)
48+
check_triples = list(dsg.triples((EG.scheck, EG.pcheck, None)))
49+
assert len(check_triples) == 1
50+
sbnode = check_triples[0][2]
51+
logging.debug("sbnode = %s, sbnode_value = %s", sbnode, f"{sbnode}")
52+
assert isinstance(sbnode, URIRef)
53+
if isinstance(expected_uri, str):
54+
assert expected_uri == f"{sbnode}"
55+
else:
56+
assert expected_uri.match(f"{sbnode}") is not None
57+
58+
59+
@pytest.mark.parametrize(
60+
["iri", "expected_bnode_value"],
61+
[
62+
("http://example.com", None),
63+
("http://example.com/not/.well-known/genid/1", None),
64+
("http://rdlib.net/not/.well-known/genid/1", None),
65+
("http://example.com/.well-known/genid/1", re.compile("^N")),
66+
("http://rdlib.net/.well-known/genid/rdflib/GMeng4V7", "GMeng4V7"),
67+
],
68+
)
69+
def test_deskolemization(
70+
iri: str, expected_bnode_value: Union[str, None, Pattern[str]]
71+
) -> None:
72+
g = Graph()
73+
for triple in base_triples:
74+
g.add(triple)
75+
g.add((EG.scheck, EG.pcheck, URIRef(iri)))
76+
assert len(g) == 3
77+
dsg = g.de_skolemize()
78+
if expected_bnode_value is None:
79+
GraphHelper.assert_sets_equals(g, dsg)
80+
else:
81+
assert len(dsg) == len(g)
82+
iset = GraphHelper.triple_or_quad_set(dsg)
83+
logging.debug("iset = %s", iset)
84+
assert iset.issuperset(base_triples)
85+
check_triples = list(dsg.triples((EG.scheck, EG.pcheck, None)))
86+
assert len(check_triples) == 1
87+
bnode = check_triples[0][2]
88+
logging.debug("bnode = %s, bnode_value = %s", bnode, f"{bnode}")
89+
assert isinstance(bnode, BNode)
90+
if isinstance(expected_bnode_value, str):
91+
assert expected_bnode_value == f"{bnode}"
92+
else:
93+
assert expected_bnode_value.match(f"{bnode}") is not None

test/test_issues/test_issue1404.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from rdflib import FOAF, Graph, URIRef
22
from rdflib.compare import isomorphic
3-
from rdflib.term import RDFLibGenid
43

54

65
def test_skolem_de_skolem_roundtrip():
@@ -30,9 +29,9 @@ def test_skolem_de_skolem_roundtrip():
3029

3130
skolemized_graph = graph.skolemize()
3231

33-
# Check the BNode is now an RDFLibGenid after skolemization.
32+
# Check the BNode is now a URIRef after skolemization.
3433
skolem_bnode = skolemized_graph.value(**query)
35-
assert type(skolem_bnode) == RDFLibGenid
34+
assert type(skolem_bnode) == URIRef
3635

3736
# Check that the original bnode id exists somewhere in the uri.
3837
assert bnode_id in skolem_bnode

test/test_issues/test_issue1808.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from rdflib import Graph
2+
from rdflib.term import BNode, URIRef, rdflib_skolem_genid
3+
4+
5+
def test():
6+
"""Test skolemised URI query retrieves expected results.
7+
8+
Issue: https://github.com/RDFLib/rdflib/issues/1808
9+
"""
10+
11+
g = Graph()
12+
g.parse(data='[] <urn:prop> "val" .', format="turtle")
13+
for s, p, o in g:
14+
assert isinstance(s, BNode)
15+
16+
gs = g.skolemize()
17+
for s, p, o in gs:
18+
assert isinstance(s, URIRef) and s.__contains__(rdflib_skolem_genid)
19+
20+
query_with_iri = 'select ?p ?o {{ <{}> ?p ?o }}'.format(s)
21+
query_for_all = 'select ?s ?p ?o { ?s ?p ?o }'
22+
23+
count = 0
24+
for row in gs.query(query_with_iri):
25+
count += 1
26+
assert count == 1
27+
28+
count = 0
29+
for row in gs.query(query_for_all):
30+
count += 1
31+
assert count == 1
32+
33+
gp = Graph()
34+
gp.parse(data=gs.serialize(format='turtle'), format='turtle')
35+
36+
count = 0
37+
for row in gp.query(query_with_iri):
38+
count += 1
39+
assert count == 1
40+
41+
count = 0
42+
for row in gp.query(query_for_all):
43+
count += 1
44+
assert count == 1

test/test_skolem_genid.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from rdflib import URIRef
2+
from rdflib.term import Genid, RDFLibGenid
3+
4+
5+
def test_skolem_genid_and_rdflibgenid():
6+
rdflib_genid = URIRef(
7+
"http://rdflib.net/.well-known/genid/rdflib/N97c39b957bc444949a82793519348dc2"
8+
)
9+
custom_genid = URIRef(
10+
"http://example.com/.well-known/genid/example/Ne864c0e3684044f381d518fdac652f2e"
11+
)
12+
13+
assert RDFLibGenid._is_rdflib_skolem(rdflib_genid) is True
14+
assert Genid._is_external_skolem(rdflib_genid) is True
15+
16+
assert RDFLibGenid._is_rdflib_skolem(custom_genid) is False
17+
assert Genid._is_external_skolem(custom_genid) is True

0 commit comments

Comments
 (0)