Skip to content

Commit fe422ff

Browse files
Merge pull request #362 from vincentkelleher/fix_different_types_with_same_name
Fix SchemaView metadata injection and get URI
2 parents 035bcea + 259ecd1 commit fe422ff

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

linkml_runtime/utils/schemaview.py

+14-5
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,16 @@ def imports_closure(self, imports: bool = True, traverse: Optional[bool] = None,
324324

325325
if inject_metadata:
326326
for s in self.schema_map.values():
327-
for x in {**s.classes, **s.enums, **s.slots, **s.subsets, **s.types}.values():
327+
# It is important to merge element definitions as a list as multiple elements of different kinds can
328+
# have the same name which means they have the same dict key.
329+
elements = []
330+
elements.extend(s.classes.values())
331+
elements.extend(s.enums.values())
332+
elements.extend(s.slots.values())
333+
elements.extend(s.subsets.values())
334+
elements.extend(s.types.values())
335+
336+
for x in elements:
328337
x.from_schema = s.id
329338
for c in s.classes.values():
330339
for a in c.attributes.values():
@@ -1070,14 +1079,14 @@ def get_uri(self, element: Union[ElementName, Element], imports=True, expand=Fal
10701079
Return the CURIE or URI for a schema element. If the schema defines a specific URI, this is
10711080
used, otherwise this is constructed from the default prefix combined with the element name
10721081
1073-
:param element_name: name of schema element
1082+
:param element: name of schema element
10741083
:param imports: include imports closure
10751084
:param native: return the native CURIE or URI rather than what is declared in the uri slot
10761085
:param expand: expand the CURIE to a URI; defaults to False
10771086
:return: URI or CURIE as a string
10781087
"""
10791088
e = self.get_element(element, imports=imports)
1080-
e_name = e.name
1089+
10811090
if isinstance(e, ClassDefinition):
10821091
uri = e.class_uri
10831092
e_name = camelcase(e.name)
@@ -1091,8 +1100,8 @@ def get_uri(self, element: Union[ElementName, Element], imports=True, expand=Fal
10911100
raise ValueError(f'Must be class or slot or type: {e}')
10921101
if uri is None or native:
10931102
if e.from_schema is not None:
1094-
schema = next(sc for sc in self.schema_map.values() if sc.id == e.from_schema)
1095-
if schema == None:
1103+
schema = next((sc for sc in self.schema_map.values() if sc.id == e.from_schema), None)
1104+
if schema is None:
10961105
raise ValueError(f'Cannot find {e.from_schema} in schema_map')
10971106
else:
10981107
schema = self.schema_map[self.in_schema(e.name)]

tests/test_utils/test_schemaview.py

+18-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
from jsonasobj2 import JsonObj
77

88
from linkml_runtime.dumpers import yaml_dumper
9-
from linkml_runtime.linkml_model.meta import Example, SchemaDefinition, ClassDefinition, SlotDefinitionName, SlotDefinition, \
10-
ClassDefinitionName, Prefix
9+
from linkml_runtime.linkml_model.meta import Example, SchemaDefinition, ClassDefinition, SlotDefinitionName, \
10+
SlotDefinition, \
11+
ClassDefinitionName, Prefix, TypeDefinition
1112
from linkml_runtime.loaders.yaml_loader import YAMLLoader
1213
from linkml_runtime.utils.introspection import package_schemaview
1314
from linkml_runtime.utils.schemaview import SchemaView, SchemaUsage, OrderedBy
@@ -896,4 +897,18 @@ def test_materialize_nonscalar_slot_usage():
896897
assert cls.attributes["tempo"].annotations.expected_value.value == "a number between 0 and 200"
897898
assert cls.attributes["tempo"].annotations.preferred_unit.value == "BPM"
898899
assert cls.attributes["tempo"].domain_of == ["DJController"]
899-
assert cls.slot_usage["tempo"].domain_of == []
900+
assert cls.slot_usage["tempo"].domain_of == []
901+
902+
903+
def test_type_and_slot_with_same_name():
904+
"""
905+
Test that checks the case where a URI needs to be resolved and a name is ambiguously used for a slot and a
906+
type
907+
"""
908+
schema_definition = SchemaDefinition(id="https://example.org/test#", name="test_schema", default_prefix="ex")
909+
910+
view = SchemaView(schema_definition)
911+
view.add_slot(SlotDefinition(name="test", from_schema="https://example.org/another#"))
912+
view.add_type(TypeDefinition(name="test", from_schema="https://example.org/imported#"))
913+
914+
assert view.get_uri("test", imports=True) == "ex:test"

0 commit comments

Comments
 (0)