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

Add autocompletion for namespaces (IPython only) #599

Merged
merged 4 commits into from
May 27, 2021
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
49 changes: 43 additions & 6 deletions osp/core/ontology/namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from collections.abc import Iterable
import rdflib
import logging

import itertools
from osp.core.ontology.entity import OntologyEntity
from osp.core.ontology.relationship import OntologyRelationship
from osp.core.ontology.cuba import rdflib_cuba
Expand Down Expand Up @@ -32,6 +32,17 @@ def __init__(self, name, namespace_registry, iri):
self._reference_by_label = \
namespace_registry._get_reference_by_label(self._iri)

def __dir__(self):
"""Attributes available for the OntologyNamespace class.

Returns:
Iterable: the available attributes, which include the methods and
the ontology entities in the namespace.
"""
entity_autocompletion = self._iter_labels() \
if self._reference_by_label else self._iter_suffixes()
return itertools.chain(dir(super()), entity_autocompletion)

def __str__(self):
"""Transform the namespace to a human readable string.

Expand Down Expand Up @@ -254,20 +265,46 @@ def _get_from_label(self, label, lang=None, case_sensitive=False):
results[0] = results[0].inverse
return results[0]

def __iter__(self):
"""Iterate over the ontology entities in the namespace.
def _iter_iris(self):
"""Iterate over the IRIs of the ontology entities in the namespace.

:return: An iterator over the entities.
:rtype: Iterator[OntologyEntity]
:return: An iterator over the entity IRIs.
:rtype: Iterator[rdflib.URIRef]
"""
types = [rdflib.OWL.DatatypeProperty,
rdflib.OWL.ObjectProperty,
rdflib.OWL.Class]
return (self._namespace_registry.from_iri(s)
return (s
kysrpex marked this conversation as resolved.
Show resolved Hide resolved
for t in types
for s, _, _ in self._graph.triples((None, rdflib.RDF.type, t))
if s in self)

def __iter__(self):
kysrpex marked this conversation as resolved.
Show resolved Hide resolved
"""Iterate over the ontology entities in the namespace.

:return: An iterator over the entities.
:rtype: Iterator[OntologyEntity]
"""
return (self._namespace_registry.from_iri(iri)
for iri in self._iter_iris())

def _iter_labels(self):
"""Iterate over the labels of the ontology entities in the namespace.

:return: An iterator over the entity labels.
:rtype: Iterator[str]
"""
return itertools.chain(*(self._get_labels_for_iri(iri)
for iri in self._iter_iris()))

def _iter_suffixes(self):
"""Iterate over suffixes of the ontology entities in the namespace.

:return: An iterator over the entity suffixes.
:rtype: Iterator[str]
"""
return (str(iri)[len(str(self._iri)):] for iri in self._iter_iris())

def __contains__(self, item):
"""Check whether the given entity is part of the namespace.

Expand Down
10 changes: 10 additions & 0 deletions tests/test_namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,16 @@ def test_get_entity_name(self):
"City_T"
)

def test_autocompletion_ipython(self):
"""Checks that all the expected ontology entities are in __dir__.

The check is done just for the `cuba` namespace.
"""
expected = {'activeRelationship', 'passiveRelationship',
'relationship', 'attribute', 'path', 'Entity', 'File',
'Nothing', 'Wrapper'}
self.assertSetEqual(set(dir(cuba)) & expected, expected)


if __name__ == "__main__":
unittest.main()