"""OWL IRI"""
import weakref
from abc import ABCMeta
from typing import Final, Union
from weakref import WeakKeyDictionary
from owlapy import namespaces
from owlapy.namespaces import Namespaces
from .owl_annotation import OWLAnnotationSubject, OWLAnnotationValue
class _WeakCached(type):
__slots__ = ()
def __init__(cls, what, bases, dct):
super().__init__(what, bases, dct)
cls._cache = WeakKeyDictionary()
def __call__(cls, *args, **kwargs):
_temp = super().__call__(*args, **kwargs)
ret = cls._cache.get(_temp)
if ret is None:
cls._cache[_temp] = weakref.ref(_temp)
return _temp
else:
return ret()
class _meta_IRI(ABCMeta, _WeakCached):
__slots__ = ()
pass
[docs]
class IRI(OWLAnnotationSubject, OWLAnnotationValue, metaclass=_meta_IRI):
"""An IRI, consisting of a namespace and a remainder."""
__slots__ = '_namespace', '_remainder', '__weakref__'
type_index: Final = 0
_namespace: str
_remainder: str
def __init__(self, namespace: Union[str, Namespaces], remainder: str="", is_file_path=False):
if isinstance(namespace, Namespaces):
namespace = namespace.ns
elif not isinstance(namespace, str):
raise TypeError(f"Expected 'namespace' to be an instance of str or Namespaces, got {type(namespace).__name__} instead ({namespace!r}).")
elif not is_file_path:
if not namespace or namespace[-1] not in ("/", ":", "#"):
raise ValueError("It should be a valid IRI based on /, :, and #. "
"Are you saving a file? - then set is_file_path=True "
"to overcome this assertion.")
if not isinstance(remainder, str):
raise TypeError(f"Expected 'remainder' to be an instance of str, got {type(remainder).__name__} instead ({remainder!r}).")
import sys
# https://docs.python.org/3.2/library/sys.html?highlight=sys.intern#sys.intern
self._namespace = sys.intern(namespace)
self._remainder = remainder
[docs]
@staticmethod
def create(iri:str | Namespaces, remainder:str=None, is_file_path=False) -> 'IRI':
if not isinstance(iri, (str, Namespaces)):
raise TypeError(f"Expected 'iri' to be an instance of str or Namespaces, got {type(iri).__name__} instead ({iri!r}).")
if is_file_path and iri != "":
return IRI(iri, "", is_file_path)
elif remainder is not None:
if not isinstance(remainder, str):
raise TypeError(f"Expected 'remainder' to be an instance of str, got {type(remainder).__name__} instead ({remainder!r}).")
return IRI(iri, remainder)
else:
if not isinstance(iri, str):
raise TypeError(f"Expected 'iri' to be an instance of str when 'remainder' is None, got {type(iri).__name__} instead ({iri!r}).")
# Extract remainder from input string
if "/" not in iri:
raise ValueError(f"Input must contain /\tCurrently, {iri}. Are you saving a file? - then "
f"set is_file_path=True to overcome this assertion.")
if " " in iri:
raise ValueError(f"Input must not contain whitespace. Currently:{iri}.")
index = 1 + max(iri.rfind("/"), iri.rfind(":"), iri.rfind("#"))
return IRI(iri[0:index], iri[index:])
[docs]
def __repr__(self):
return f"IRI({repr(self._namespace)}, {repr(self._remainder)})"
[docs]
def __eq__(self, other):
if type(other) is type(self):
return self._namespace is other._namespace and self._remainder == other._remainder
return False
[docs]
def __hash__(self):
return hash(("IRI", self._namespace, self._remainder))
[docs]
def is_nothing(self):
"""Determines if this IRI is equal to the IRI that owl:Nothing is named with.
Returns:
:True if this IRI is equal to <http://www.w3.org/2002/07/owl#Nothing> and otherwise False.
"""
from owlapy.vocab import OWLRDFVocabulary
return self == OWLRDFVocabulary.OWL_NOTHING.iri
[docs]
def is_thing(self):
"""Determines if this IRI is equal to the IRI that owl:Thing is named with.
Returns:
:True if this IRI is equal to <http://www.w3.org/2002/07/owl#Thing> and otherwise False.
"""
from owlapy.vocab import OWLRDFVocabulary
return self == OWLRDFVocabulary.OWL_THING.iri
[docs]
def is_reserved_vocabulary(self) -> bool:
"""Determines if this IRI is in the reserved vocabulary. An IRI is in the reserved vocabulary if it starts with
<http://www.w3.org/1999/02/22-rdf-syntax-ns#> or <http://www.w3.org/2000/01/rdf-schema#> or
<http://www.w3.org/2001/XMLSchema#> or <http://www.w3.org/2002/07/owl#>.
Returns:
True if the IRI is in the reserved vocabulary, otherwise False.
"""
return (self._namespace == namespaces.OWL or self._namespace == namespaces.RDF
or self._namespace == namespaces.RDFS or self._namespace == namespaces.XSD)
[docs]
def as_iri(self) -> 'IRI':
# documented in parent
return self
[docs]
def as_str(self) -> str:
"""
CD: Should be deprecated.
Returns:
The string that specifies the IRI.
"""
return self._namespace + self._remainder
@property
def str(self) -> str:
"""
Returns:
The string that specifies the IRI.
"""
return self.as_str()
@property
def remainder(self) -> str:
"""
Returns:
The string corresponding to the remainder of the IRI.
"""
return self._remainder
[docs]
def get_namespace(self) -> str:
"""
Returns:
The namespace as string.
"""
return self._namespace
[docs]
def get_remainder(self) -> str:
"""
Returns:
The remainder (coincident with NCName usually) for this IRI.
"""
return self._remainder