Skip to content

Commit 878d01e

Browse files
authored
Merge pull request #467 from linkml/schemaview_pv_fn_edits
schemaview.py: make `permissible_value_*` act consistently with other such methods
2 parents 89e17c7 + 881a0ad commit 878d01e

File tree

2 files changed

+37
-28
lines changed

2 files changed

+37
-28
lines changed

linkml_runtime/utils/schemaview.py

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -820,41 +820,37 @@ def enum_parents(
820820
@lru_cache(None)
821821
def permissible_value_parent(
822822
self, permissible_value: str, enum_name: ENUM_NAME
823-
) -> list[str | PermissibleValueText] | None:
823+
) -> list[str | PermissibleValueText]:
824824
""":param enum_name: child enum name
825825
:param permissible_value: permissible value
826826
:return: all direct parent enum names (is_a)
827827
"""
828828
enum = self.get_enum(enum_name, strict=True)
829-
if enum:
830-
if permissible_value in enum.permissible_values:
831-
pv = enum.permissible_values[permissible_value]
832-
if pv.is_a:
833-
return [pv.is_a]
834-
return None
835-
return []
829+
pv = enum.permissible_values.get(permissible_value)
830+
if not pv:
831+
err_msg = f'"{permissible_value}" is not a permissible value of the enum "{enum_name}".'
832+
raise ValueError(err_msg)
833+
return [pv.is_a] if pv.is_a else []
836834

837835
@lru_cache(None)
838836
def permissible_value_children(
839837
self, permissible_value: str, enum_name: ENUM_NAME
840-
) -> list[str | PermissibleValueText] | None:
838+
) -> list[str | PermissibleValueText]:
841839
""":param enum_name: parent enum name
842840
:param permissible_value: permissible value
843841
:return: all direct child permissible values (is_a)
844842
"""
845843
enum = self.get_enum(enum_name, strict=True)
846-
children = []
847-
if enum:
848-
if permissible_value in enum.permissible_values:
849-
pv = enum.permissible_values[permissible_value]
850-
for isapv in enum.permissible_values:
851-
isapv_entity = enum.permissible_values[isapv]
852-
if isapv_entity.is_a and pv.text == isapv_entity.is_a:
853-
children.append(isapv)
854-
return children
855-
return None
856-
msg = f'No such enum as "{enum_name}"'
857-
raise ValueError(msg)
844+
pv = enum.permissible_values.get(permissible_value)
845+
if not pv:
846+
err_msg = f'"{permissible_value}" is not a permissible value of the enum "{enum_name}".'
847+
raise ValueError(err_msg)
848+
849+
return [
850+
isa_pv
851+
for isa_pv, isa_pv_entity in enum.permissible_values.items()
852+
if isa_pv_entity.is_a and pv.text == isa_pv_entity.is_a
853+
]
858854

859855
@lru_cache(None)
860856
def slot_parents(

tests/test_utils/test_schemaview.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,8 +1106,12 @@ def test_alias_slot(schema_view_no_imports: SchemaView) -> None:
11061106
assert postal_code_slot.alias == "zip" # Assert alias is 'zip'
11071107

11081108

1109-
def test_enums_and_enum_relationships(schema_view_no_imports: SchemaView) -> None:
1110-
"""Test various aspects of Enum representation.
1109+
def test_permissible_value_relationships(schema_view_no_imports: SchemaView) -> None:
1110+
"""Test relationships between permissible values.
1111+
1112+
These tests use valid permissible_value / enum combinations.
1113+
1114+
See test_permissible_value_relationships_fail for invalid enum-PV pairings.
11111115
11121116
CAT:
11131117
LION:
@@ -1122,18 +1126,14 @@ def test_enums_and_enum_relationships(schema_view_no_imports: SchemaView) -> Non
11221126
"""
11231127
view = schema_view_no_imports
11241128

1125-
# Test for ValueError when passing incorrect parameters
1126-
with pytest.raises(ValueError, match='No such enum: "not_an_enum"'):
1127-
view.permissible_value_parent("not_a_pv", "not_an_enum")
1128-
11291129
animals = "Animals"
11301130
animal_enum = view.get_enum(animals)
11311131
assert animal_enum.name == animals
11321132

11331133
pv_cat = animal_enum.permissible_values["CAT"]
11341134
assert pv_cat.text == "CAT"
11351135
assert pv_cat.is_a is None
1136-
assert view.permissible_value_parent("CAT", animals) is None
1136+
assert view.permissible_value_parent("CAT", animals) == []
11371137
assert view.permissible_value_ancestors("CAT", animals) == ["CAT"]
11381138
assert set(view.permissible_value_children("CAT", animals)) == {"LION", "TABBY"}
11391139
assert set(view.permissible_value_descendants("CAT", animals)) == {"CAT", "LION", "ANGRY_LION", "TABBY"}
@@ -1160,6 +1160,19 @@ def test_enums_and_enum_relationships(schema_view_no_imports: SchemaView) -> Non
11601160
assert view.permissible_value_descendants("ANGRY_LION", animals) == ["ANGRY_LION"]
11611161

11621162

1163+
@pytest.mark.parametrize("fn", ["parent", "children", "ancestors", "descendants"])
1164+
def test_permissible_value_relationships_fail(schema_view_no_imports: SchemaView, fn: str) -> None:
1165+
"""Test permissible_value relationships with incorrect enum/PV pairs."""
1166+
method_name = f"permissible_value_{fn}"
1167+
# invalid enum
1168+
with pytest.raises(ValueError, match='No such enum: "invalid_enum"'):
1169+
getattr(schema_view_no_imports, method_name)("invalid_pv", "invalid_enum")
1170+
1171+
# invalid pv, valid enum
1172+
with pytest.raises(ValueError, match='"invalid_pv" is not a permissible value of the enum "Animals"'):
1173+
getattr(schema_view_no_imports, method_name)("invalid_pv", "Animals")
1174+
1175+
11631176
# FIXME: improve testing of dynamic enums
11641177
def test_dynamic_enum(schema_view_with_imports: SchemaView) -> None:
11651178
"""Rudimentary test of dynamic enum."""

0 commit comments

Comments
 (0)