Skip to content

Commit 1df179d

Browse files
ialarmedalienvladistan
authored andcommitted
Add in checks to ensure that the slot is populated correctly when calling various slot range functions'
1 parent 3821f34 commit 1df179d

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

linkml_runtime/utils/schemaview.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,8 +465,7 @@ def imports_closure(
465465
# visit item
466466
sn = todo.pop()
467467
if sn not in self.schema_map:
468-
imported_schema = self.load_import(sn)
469-
self.schema_map[sn] = imported_schema
468+
self.schema_map[sn] = self.load_import(sn)
470469

471470
# resolve item's imports if it has not been visited already
472471
# we will get duplicates, but not cycles this way, and
@@ -1904,6 +1903,10 @@ def slot_applicable_range_elements(self, slot: SlotDefinition) -> list[ClassDefi
19041903
:param slot:
19051904
:return: list of element types
19061905
"""
1906+
if not slot or not isinstance(slot, SlotDefinition):
1907+
err_msg = "A SlotDefinition must be provided to generate the slot applicable range elements."
1908+
raise ValueError(err_msg)
1909+
19071910
is_any = False
19081911
range_types = []
19091912
for r in self.slot_range_as_union(slot):
@@ -1930,6 +1933,10 @@ def slot_range_as_union(self, slot: SlotDefinition) -> list[ElementName]:
19301933
:param slot:
19311934
:return: list of ranges
19321935
"""
1936+
if not slot or not isinstance(slot, SlotDefinition):
1937+
err_msg = "A SlotDefinition must be provided to generate the slot range as union."
1938+
raise ValueError(err_msg)
1939+
19331940
return list({y.range for y in [slot, *[x for x in [*slot.exactly_one_of, *slot.any_of] if x.range]]})
19341941

19351942
def induced_slot_range(self, slot: SlotDefinition, strict: bool = False) -> set[str | ElementName]: # noqa: FBT001, FBT002
@@ -1947,6 +1954,9 @@ def induced_slot_range(self, slot: SlotDefinition, strict: bool = False) -> set[
19471954
:return: set of ranges
19481955
:rtype: set[str | ElementName]
19491956
"""
1957+
if not slot or not isinstance(slot, SlotDefinition):
1958+
err_msg = "A SlotDefinition must be provided to generate the induced slot range."
1959+
raise ValueError(err_msg)
19501960

19511961
slot_range = slot.range
19521962
any_of_range = {x.range for x in slot.any_of if x.range}

tests/test_utils/test_schemaview.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2125,6 +2125,41 @@ def test_slot_range(
21252125
pytest.fail(f"Unexpected range_function value: {range_function}")
21262126

21272127

2128+
@pytest.mark.parametrize(
2129+
"slot_argument",
2130+
[
2131+
None,
2132+
"slot_name",
2133+
12345,
2134+
"",
2135+
set(),
2136+
{"this": "that"},
2137+
True,
2138+
False,
2139+
lambda x: f"slot {x}",
2140+
ClassDefinition(name="whatever"),
2141+
SlotDefinitionName("something"),
2142+
],
2143+
)
2144+
@pytest.mark.parametrize(
2145+
("range_function", "err_desc"),
2146+
[
2147+
("slot_range_as_union", "slot range as union"),
2148+
("induced_slot_range", "induced slot range"),
2149+
("slot_applicable_range_elements", "slot applicable range elements"),
2150+
],
2151+
)
2152+
def test_range_function_non_slot_input(
2153+
schema_view_core: SchemaView, slot_argument: Any, range_function: str, err_desc: str
2154+
) -> None:
2155+
"""Ensure that incorrect input to the range function generates an error message.
2156+
2157+
The schema content is not important as this is solely for testing errors when calling `range` functions with the wrong argument.
2158+
"""
2159+
with pytest.raises(ValueError, match=f"A SlotDefinition must be provided to generate the {err_desc}."):
2160+
getattr(schema_view_core, range_function)(slot_argument)
2161+
2162+
21282163
"""End of range-related tests. Phew!"""
21292164

21302165

0 commit comments

Comments
 (0)