Skip to content

Commit

Permalink
BREAKING CHANGE: eliminate rdflib.term.Genid and `rdflib.term.RDFLi…
Browse files Browse the repository at this point in the history
…bGenid`

TBD ...

- Fixes <RDFLib#1828>
  • Loading branch information
aucampia committed Jun 19, 2023
1 parent f278b86 commit 07b43db
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 58 deletions.
30 changes: 17 additions & 13 deletions rdflib/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -1773,6 +1773,10 @@ def do_skolemize2(t: _TripleType) -> _TripleType:
def de_skolemize(
self, new_graph: Optional[Graph] = None, uriref: Optional[URIRef] = None
) -> Graph:
"""
.. warning::
De-skolemization is not a well defined process.
"""
def do_de_skolemize(uriref: URIRef, t: _TripleType) -> _TripleType:
(s, p, o) = t
if s == uriref:
Expand All @@ -1788,19 +1792,19 @@ def do_de_skolemize(uriref: URIRef, t: _TripleType) -> _TripleType:
def do_de_skolemize2(t: _TripleType) -> _TripleType:
(s, p, o) = t

if RDFLibGenid._is_rdflib_skolem(s):
# type error: Argument 1 to "RDFLibGenid" has incompatible type "Node"; expected "str"
s = RDFLibGenid(s).de_skolemize() # type: ignore[arg-type]
elif Genid._is_external_skolem(s):
# type error: Argument 1 to "Genid" has incompatible type "Node"; expected "str"
s = Genid(s).de_skolemize() # type: ignore[arg-type]

if RDFLibGenid._is_rdflib_skolem(o):
# type error: Argument 1 to "RDFLibGenid" has incompatible type "Node"; expected "str"
o = RDFLibGenid(o).de_skolemize() # type: ignore[arg-type]
elif Genid._is_external_skolem(o):
# type error: Argument 1 to "Genid" has incompatible type "Node"; expected "str"
o = Genid(o).de_skolemize() # type: ignore[arg-type]
# if RDFLibGenid._is_rdflib_skolem(s):
# # type error: Argument 1 to "RDFLibGenid" has incompatible type "Node"; expected "str"
# s = RDFLibGenid(s).de_skolemize() # type: ignore[arg-type]
# elif Genid._is_external_skolem(s):
# # type error: Argument 1 to "Genid" has incompatible type "Node"; expected "str"
# s = Genid(s).de_skolemize() # type: ignore[arg-type]

# if RDFLibGenid._is_rdflib_skolem(o):
# # type error: Argument 1 to "RDFLibGenid" has incompatible type "Node"; expected "str"
# o = RDFLibGenid(o).de_skolemize() # type: ignore[arg-type]
# elif Genid._is_external_skolem(o):
# # type error: Argument 1 to "Genid" has incompatible type "Node"; expected "str"
# o = Genid(o).de_skolemize() # type: ignore[arg-type]

return s, p, o

Expand Down
79 changes: 34 additions & 45 deletions rdflib/term.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* Numerical Ranges
"""
from __future__ import annotations
import re
from fractions import Fraction

Expand Down Expand Up @@ -57,7 +58,7 @@
TypeVar,
Union,
)
from urllib.parse import urldefrag, urljoin, urlparse
from urllib.parse import urldefrag, urljoin, urlparse, urlsplit

from isodate import (
Duration,
Expand All @@ -79,9 +80,10 @@
_SKOLEM_DEFAULT_AUTHORITY = "https://rdflib.github.io"

logger = logging.getLogger(__name__)
skolem_genid = "/.well-known/genid/"
rdflib_skolem_genid = "/.well-known/genid/rdflib/"
skolems: Dict[str, "BNode"] = {}
_WELL_KNOWN_GENID = "/.well-known/genid/"
_RDFLIB_GENID_SUFFIX = "rdflib/"
_RDFLIB_GENID_PATH = "/.well-known/genid/" + _RDFLIB_GENID_SUFFIX
# _skolems: Dict[str, "BNode"] = {}


_invalid_uri_chars = '<>" {}|\\^`'
Expand Down Expand Up @@ -347,16 +349,19 @@ def __radd__(self, other) -> "URIRef":
def __mod__(self, other) -> "URIRef":
return self.__class__(str(self) % other)

def de_skolemize(self) -> "BNode":
"""Create a Blank Node from a skolem URI, in accordance
with http://www.w3.org/TR/rdf11-concepts/#section-skolemization.
This function accepts only rdflib type skolemization, to provide
a round-tripping within the system.
.. versionadded:: 4.0
"""
if isinstance(self, RDFLibGenid):
parsed_uri = urlparse("%s" % self)
class _Deskolemizer:
def __init__(self) -> None:
self._skolems: Dict[str, BNode] = {}

def __call__(self, uri: str) -> Union[BNode, str]:
parsed_uri = urlsplit(uri)
if parsed_uri.query != "" or parsed_uri.fragment != "":
# Behaviour is undefined for skolem URIs with query or fragment, so just return the URI
return uri
if parsed_uri.path.startswith(_WELL_KNOWN_GENID):
genid_suffix = parsed_uri.path[len(_WELL_KNOWN_GENID) :]
if genid_suffix.startswith(_RDFLIB_GENID_SUFFIX):
genid_suffix = genid_suffix[len(_RDFLIB_GENID_SUFFIX) :]
return BNode(value=parsed_uri.path[len(rdflib_skolem_genid) :])
elif isinstance(self, Genid):
bnode_id = "%s" % self
Expand All @@ -370,38 +375,22 @@ def de_skolemize(self) -> "BNode":
raise Exception("<%s> is not a skolem URI" % self)


class Genid(URIRef):
__slots__ = ()

@staticmethod
def _is_external_skolem(uri: Any) -> bool:
if not isinstance(uri, str):
uri = str(uri)
parsed_uri = urlparse(uri)
gen_id = parsed_uri.path.rfind(skolem_genid)
if gen_id != 0:
return False
return True

# def _is_external_skolem(uri: str) -> bool:
# parsed_uri = urlparse(uri)
# gen_id = parsed_uri.path.rfind(skolem_genid)
# if gen_id != 0:
# return False
# return True

class RDFLibGenid(Genid):
__slots__ = ()

@staticmethod
def _is_rdflib_skolem(uri: Any) -> bool:
if not isinstance(uri, str):
uri = str(uri)
parsed_uri = urlparse(uri)
if (
parsed_uri.params != ""
or parsed_uri.query != ""
or parsed_uri.fragment != ""
):
return False
gen_id = parsed_uri.path.rfind(rdflib_skolem_genid)
if gen_id != 0:
return False
return True
# def _is_rdflib_skolem(uri: str) -> bool:
# parsed_uri = urlparse(uri)
# if parsed_uri.params != "" or parsed_uri.query != "" or parsed_uri.fragment != "":
# return False
# gen_id = parsed_uri.path.rfind(rdflib_skolem_genid)
# if gen_id != 0:
# return False
# return True


def _unique_id() -> str:
Expand Down Expand Up @@ -499,7 +488,7 @@ def skolemize(
if authority is None:
authority = _SKOLEM_DEFAULT_AUTHORITY
if basepath is None:
basepath = rdflib_skolem_genid
basepath = _RDFLIB_SKOLEM_GENID
skolem = "%s%s" % (basepath, str(self))
return URIRef(urljoin(authority, skolem))

Expand Down

0 comments on commit 07b43db

Please sign in to comment.