Skip to content
Draft
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
768118c
First version of added namespace search in get_by_label
francescalb Mar 14, 2025
bcafad0
Corrected namespace search
francescalb Mar 14, 2025
79acb31
Updated so that emmo-inferred is given emmo as prefix (as prev)
francescalb Mar 14, 2025
dd99912
Updated test_patch to new emmo
francescalb Mar 14, 2025
3390620
Updated graph to have default for emmorelations
francescalb Mar 14, 2025
d5a6ea5
test_load and test_save updated
francescalb Mar 14, 2025
00e8d9a
Updated excelparser-tests with emmo-1.0.0
francescalb Mar 14, 2025
3aadfee
Updated redirections_test
francescalb Mar 14, 2025
6782a73
Update documentation test.
francescalb Mar 14, 2025
652951a
Test_save updated
francescalb Mar 14, 2025
d5ab563
Update ontopy/ontology.py
francescalb Mar 14, 2025
04b46f9
Update ontopy/ontology.py
francescalb Mar 14, 2025
46926c6
Update ontopy/ontology.py
francescalb Mar 14, 2025
64d0f8d
Merge branch 'flb/emmo_1.0.0_released' into flb/get_by_label_w_namespace
francescalb Mar 14, 2025
0b96a02
pre-commit
francescalb Mar 14, 2025
172af04
Merge branch 'flb/emmo_1.0.0_released' into flb/get_by_label_w_namespace
francescalb Mar 14, 2025
5f4b4ec
just temporarily push
francescalb Mar 18, 2025
f106279
Added possibility of specifying iri in new_entity
francescalb Mar 20, 2025
861a348
pylint fixes and docs corrections
francescalb Mar 20, 2025
5d47dde
Merge branch 'flb/specifiy_iri_new_entity' into flb/get_by_label_w_na…
francescalb Mar 20, 2025
8a13a0d
Merge branch 'master' into flb/get_by_label_w_namespace
jesper-friis May 29, 2025
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
186 changes: 122 additions & 64 deletions ontopy/ontology.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,33 +312,42 @@ def get_by_label(
*,
label_annotations: str = None,
prefix: str = None,
namespace: str = None,
imported: bool = True,
colon_in_label: bool = None,
):
"""Returns entity with label annotation `label`.

Arguments:
label: label so search for.
May be written as 'label' or 'prefix:label'.
get_by_label('prefix:label') ==
get_by_label('label', prefix='prefix').
label_annotations: a sequence of label annotation names to look up.
Defaults to the `label_annotations` property.
prefix: if provided, it should be the last component of
the base iri of an ontology (with trailing slash (/) or hash
(#) stripped off). The search for a matching label will be
limited to this namespace.
imported: Whether to also look for `label` in imported ontologies.
colon_in_label: Whether to accept colon (:) in a label or name-part
of IRI. Defaults to the `colon_in_label` property of `self`.
Setting this true cannot be combined with `prefix`.
label: label so search for.
May be written as 'label' or 'prefix:label'
get_by_label('prefix:label') is equivalent to
searching for both
get_by_label('label', prefix='prefix') and
get_by_label('label', namespace='prefix')
label_annotations: a sequence of label annotation names to look up.
Defaults to the `label_annotations` property.
prefix: if provided, it should be the last component of
the base iri of an ontology (with trailing slash (/) or hash
(#) stripped off). The search for a matching label will be
limited to this ontology. `prefix` is ignored if `namespace`
is provided.
namespace: if provided, it should be the namespace of the entity.
It can be provided either as the whole namespace or only as the
last 'word' in the namespace, i.e. what is defined as the
namespace.name. `namespace` takes precedence over `prefix`.
imported: Whether to also look for `label` in imported ontologies.
colon_in_label: Whether to accept colon (:) in a label or name-part
of IRI. Defaults to the `colon_in_label` property of `self`.
Setting this true cannot be combined with `prefix`.

If several entities have the same label, only the one which is
found first is returned.Use get_by_label_all() to get all matches.

Note, if different prefixes are provided in the label and via
the `prefix` argument a warning will be issued and the
`prefix` argument will take precedence.
Note, if namespace is provided directly in the first argument as
'namespace:label' it will be used as namespace and
any value given to the `namespace` argument will be
ignored.

A NoSuchLabelError is raised if `label` cannot be found.
"""
Expand All @@ -353,23 +362,35 @@ def get_by_label(

if colon_in_label is None:
colon_in_label = self._colon_in_label
if colon_in_label:
if prefix:
raise ValueError(
"`prefix` cannot be combined with `colon_in_label`"
if colon_in_label and prefix:
raise ValueError(
"`prefix` cannot be combined with `colon_in_label`"
)

splitlabel = label.split(":", 1)
if len(splitlabel) == 2 and not splitlabel[1].startswith("//"):
label = splitlabel[1]
if namespace and namespace != splitlabel[0]:
warnings.warn(
f"Namespace given both as argument ({namespace}) "
f"and in label as ({splitlabel[0]}). "
"Namespace given in argument is ignored. "
)
else:
splitlabel = label.split(":", 1)
if len(splitlabel) == 2 and not splitlabel[1].startswith("//"):
label = splitlabel[1]
if prefix and prefix != splitlabel[0]:
warnings.warn(
f"Prefix given both as argument ({prefix}) "
f"and in label ({splitlabel[0]}). "
"Prefix given in argument takes precedence. "
)
if not prefix:
prefix = splitlabel[0]
namespace = splitlabel[0]
#print('namespace', namespace)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be removed

if namespace:
#print('in get_by_label namespavce')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be removed

entityset = self.get_by_label_all(
label,
label_annotations=label_annotations,
namespace=namespace,
)
if len(entityset) == 1:
return entityset.pop()
raise NoSuchLabelError(
f"No label annotations matches for '{label}' "
f"with namespace '{namespace}'."
)

if prefix:
entityset = self.get_by_label_all(
Expand All @@ -379,11 +400,6 @@ def get_by_label(
)
if len(entityset) == 1:
return entityset.pop()
if len(entityset) > 1:
raise AmbiguousLabelError(
f"Several entities have the same label '{label}' "
f"with prefix '{prefix}'."
)
raise NoSuchLabelError(
f"No label annotations matches for '{label}' "
f"with prefix '{prefix}'."
Expand Down Expand Up @@ -425,24 +441,30 @@ def get_by_label_all(
label,
label_annotations=None,
prefix=None,
namespace=None,
exact_match=False,
) -> "Set[Optional[owlready2.entity.EntityClass]]":
"""Returns set of entities with label annotation `label`.

Arguments:
label: label so search for.
May be written as 'label' or 'prefix:label'. Wildcard matching
using glob pattern is also supported if `exact_match` is set to
false.
label_annotations: a sequence of label annotation names to look up.
Defaults to the `label_annotations` property.
prefix: if provided, it should be the last component of
the base iri of an ontology (with trailing slash (/) or hash
(#) stripped off). The search for a matching label will be
limited to this namespace.
exact_match: Do not treat "*" and brackets as special characters
when matching. May be useful if your ontology has labels
containing such labels.
label: label so search for.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like an extra indentation

May be written as 'label' or 'prefix:label'. Wildcard matching
using glob pattern is also supported if `exact_match` is set to
false.
label_annotations: a sequence of label annotation names to look up.
Defaults to the `label_annotations` property.
prefix: if provided, it should be the last component of
the base iri of an ontology (with trailing slash (/) or hash
(#) stripped off). The search for a matching label will be
limited to this ontology. `prefix` is ignored if `namespace`
is provided.
namespace: if provided, it should be the namespace of the entity.
It can be provided either as the whole namespace or only as the
last 'word' in the namespace, i.e. what is defined as the
namespace.name. `namespace` takes precedence over `prefix`.
exact_match: Do not treat "*" and brackets as special characters
when matching. May be useful if your ontology has labels
containing such labels.

Returns:
Set of all matching entities or an empty set if no matches
Expand Down Expand Up @@ -496,13 +518,27 @@ def get_by_label_all(
entities.update(
ent for ent in self.get_entities() if ent.name in matches
)
if namespace:
#print("in namespace", namespace)
#print("entities", entities)
#for ent in entities:
# print("ent.namespace", ent.namespace)
# print("ent.namespace.name", ent.namespace.name)
# print("namespace", namespace)
# print(namespace in [ent.namespace.name, ent.namespace.base_iri])
Comment on lines +522 to +528
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be removed

return set(
ent
for ent in entities
if namespace in [ent.namespace.name, ent.namespace._base_iri]
)

if prefix:
return set(
ent
for ent in entities
if ent.namespace.ontology.prefix == prefix
)

return entities

def _to_storids(self, sequence, create_if_missing=False):
Expand Down Expand Up @@ -2025,7 +2061,7 @@ def get_wu_palmer_measure(self, cls1, cls2):
generations2 = self.number_of_generations(cls2, cca)
return 2 * ccadepth / (generations1 + generations2 + 2 * ccadepth)

def new_entity(
def new_entity( # pylint: disable=too-many-arguments,too-many-branches,too-many-positional-arguments
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These pylint disable's will probably make the line too long. Probably better to move the comment to after the docstring (line 2119)

self,
name: str,
parent: Union[
Expand All @@ -2045,6 +2081,7 @@ def new_entity(
]
] = "class",
preflabel: Optional[str] = None,
iri: Optional[str] = None,
) -> Union[
ThingClass,
ObjectPropertyClass,
Expand All @@ -2068,6 +2105,8 @@ def new_entity(
be added as prefLabel if skos:prefLabel is in the ontology
and listed in `self.label_annotations`. Set `preflabel` to
False, to avoid assigning a prefLabel.
iri: IRI of the entity. If None, a new IRI will be generated
based on the ontology base IRI and the entity name.

Returns:
the new entity.
Expand Down Expand Up @@ -2113,7 +2152,8 @@ def new_entity(

with self:
entity = types.new_class(name, parents)

if iri:
entity.iri = iri
preflabel_iri = "http://www.w3.org/2004/02/skos/core#prefLabel"
if preflabel:
if not self.world[preflabel_iri]:
Expand All @@ -2134,63 +2174,81 @@ def new_entity(

# Method that creates new ThingClass using new_entity
def new_class(
self, name: str, parent: Union[ThingClass, Iterable]
self,
name: str,
parent: Union[ThingClass, Iterable],
iri: Optional[str] = None,
) -> ThingClass:
"""Create and return new class.

Args:
name: name of the class
parent: parent(s) of the class
iri: IRI of the new class. If None, a new IRI will be generated
based on the ontology base IRI and the entity name.


Returns:
the new class.
"""
return self.new_entity(name, parent, "class")
return self.new_entity(name, parent, "class", iri=iri)

# Method that creates new ObjectPropertyClass using new_entity
def new_object_property(
self, name: str, parent: Union[ObjectPropertyClass, Iterable]
self,
name: str,
parent: Union[ObjectPropertyClass, Iterable],
iri: Optional[str] = None,
) -> ObjectPropertyClass:
"""Create and return new object property.

Args:
name: name of the object property
parent: parent(s) of the object property

iri: IRI of the new object property. If None, a new IRI will be
based on the ontology base IRI and the entity name.
Returns:
the new object property.
"""
return self.new_entity(name, parent, "object_property")
return self.new_entity(name, parent, "object_property", iri=iri)

# Method that creates new DataPropertyClass using new_entity
def new_data_property(
self, name: str, parent: Union[DataPropertyClass, Iterable]
self,
name: str,
parent: Union[DataPropertyClass, Iterable],
iri: Optional[str] = None,
) -> DataPropertyClass:
"""Create and return new data property.

Args:
name: name of the data property
parent: parent(s) of the data property

iri: IRI of the new data property. If None, a new IRI will be
based on the ontology base IRI and the entity name
Returns:
the new data property.
"""
return self.new_entity(name, parent, "data_property")
return self.new_entity(name, parent, "data_property", iri=iri)

# Method that creates new AnnotationPropertyClass using new_entity
def new_annotation_property(
self, name: str, parent: Union[AnnotationPropertyClass, Iterable]
self,
name: str,
parent: Union[AnnotationPropertyClass, Iterable],
iri: Optional[str] = None,
) -> AnnotationPropertyClass:
"""Create and return new annotation property.

Args:
name: name of the annotation property
parent: parent(s) of the annotation property

iri: IRI of the new annotation property. If None, a new IRI will
be based on the ontology base IRI and the entity name.
Returns:
the new annotation property.
"""
return self.new_entity(name, parent, "annotation_property")
return self.new_entity(name, parent, "annotation_property", iri=iri)

def difference(self, other: owlready2.Ontology) -> set:
"""Return a set of triples that are in this, but not in the
Expand Down
Loading
Loading