Skip to content

Commit ad8d5ad

Browse files
author
Vincent Kelleher
committed
raise an error when two classes have the same ambiguous attribute
Closes linkml/linkml#2403 Signed-off-by: Vincent Kelleher <[email protected]>
1 parent ad74966 commit ad8d5ad

File tree

3 files changed

+37
-5
lines changed

3 files changed

+37
-5
lines changed

linkml_runtime/utils/schemaview.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -631,8 +631,8 @@ def get_slot(self, slot_name: SLOT_NAME, imports=True, attributes=True, strict=F
631631
for c in self.all_classes(imports=imports).values():
632632
if slot_name in c.attributes:
633633
if slot is not None:
634-
# slot name is ambiguous: return a stub slot
635-
return SlotDefinition(slot_name)
634+
raise ValueError(f'Attribute "{slot_name}" is already defined in another class, please use a '
635+
f'slot in that case')
636636
slot = copy(c.attributes[slot_name])
637637
slot.from_schema = c.from_schema
638638
slot.owner = c.name
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
id: https://examples.org/get-slot-with-attribute#
2+
name: get-slot-with-attribute
3+
4+
prefixes:
5+
test: https://examples.org/get-slot-with-attribute#
6+
7+
default_prefix: test
8+
default_range: string
9+
10+
classes:
11+
ClassWithAttributes:
12+
attributes:
13+
randomAttribute:
14+
description: "A random attribute for testing purposes"
15+
range: integer
16+
minimum_value: 0
17+
maximum_value: 999
18+
19+
ImportantSecondClass:
20+
description: "Important class to reproduce the error I got as the class loop needs to have at least a
21+
second iteration"
22+
attributes:
23+
randomAttribute:
24+
description: "Now you see the ambiguity intensifying ?"
25+
range: integer
26+
minimum_value: 0
27+
maximum_value: 111

tests/test_utils/test_schemaview.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -744,9 +744,6 @@ def test_ambiguous_attributes():
744744
a2x = SlotDefinition('a2', range='BarEnum')
745745
view.add_class(ClassDefinition('C2', attributes={a1x.name: a1x, a2x.name: a2x}))
746746

747-
assert view.get_slot(a1.name).range is None
748-
assert view.get_slot(a2.name).range is None
749-
assert view.get_slot(a3.name).range is not None
750747
assert len(view.all_slots(attributes=True)) == 3
751748
assert len(view.all_slots(attributes=False)) == 0
752749
assert len(view.all_slots()) == 3
@@ -757,6 +754,14 @@ def test_ambiguous_attributes():
757754
assert view.induced_slot(a2x.name, 'C2').range == a2x.range
758755

759756

757+
def test_ambiguous_attribute_through_get_slot():
758+
schema_path = os.path.join(INPUT_DIR, "get_slot_with_ambiguous_attributes.yaml")
759+
sv = SchemaView(schema_path)
760+
with pytest.raises(ValueError) as exception:
761+
sv.get_slot("randomAttribute")
762+
assert str(exception.value) == ('Attribute "randomAttribute" is already defined in another class, please use a '
763+
'slot in that case')
764+
760765
def test_metamodel_in_schemaview():
761766
view = package_schemaview('linkml_runtime.linkml_model.meta')
762767
assert 'meta' in view.imports_closure()

0 commit comments

Comments
 (0)