From aad5f86f2d677b8bb177c8cb6b020508645acda2 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Tue, 12 Dec 2023 17:09:29 -0800 Subject: [PATCH 1/4] remove noisy warning --- linkml_runtime/utils/schemaview.py | 1 - 1 file changed, 1 deletion(-) diff --git a/linkml_runtime/utils/schemaview.py b/linkml_runtime/utils/schemaview.py index 78f94240..92a16fc4 100644 --- a/linkml_runtime/utils/schemaview.py +++ b/linkml_runtime/utils/schemaview.py @@ -931,7 +931,6 @@ def get_uri(self, element: Union[ElementName, Element], imports=True, expand=Fal if schema == None: raise ValueError(f'Cannot find {e.from_schema} in schema_map') else: - logging.warning(f'from_schema not populated for element {e.name}') schema = self.schema_map[self.in_schema(e.name)] pfx = schema.default_prefix uri = f'{pfx}:{e_name}' From 3f7ca5d37a52f0813caf32ddd3498a2a12c23627 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 13 Dec 2023 13:01:16 -0800 Subject: [PATCH 2/4] fixing tests --- linkml_runtime/utils/schemaview.py | 46 +++++++++++++++++++++++++++++ tests/test_utils/test_schemaview.py | 6 ++++ 2 files changed, 52 insertions(+) diff --git a/linkml_runtime/utils/schemaview.py b/linkml_runtime/utils/schemaview.py index 92a16fc4..34e3de02 100644 --- a/linkml_runtime/utils/schemaview.py +++ b/linkml_runtime/utils/schemaview.py @@ -618,6 +618,36 @@ def permissible_value_parent(self, permissible_value: str, enum_name: ENUM_NAME) else: return [] + @lru_cache() + def permissible_value_children(self, permissible_value: str, enum_name: ENUM_NAME) -> Union[ + str, PermissibleValueText, None, ValueError]: + """ + :param enum_name: parent enum name + :param permissible_value: permissible value + :return: all direct child enum names (is_a) + + CAT: + LION: + is_a: CAT + ANGRY_LION: + is_a: LION + BIRD: + EAGLE: + is_a: BIRD + + """ + + enum = self.get_enum(enum_name, strict=True) + if enum: + if permissible_value in enum.permissible_values: + pv = enum.permissible_values[permissible_value] + for isapv in enum.permissible_values: + isapv_entity = enum.permissible_values[isapv] + if isapv_entity.is_a and pv.text == isapv_entity.is_a: + return [isapv] + else: + return [] + @lru_cache() def slot_parents(self, slot_name: SLOT_NAME, imports=True, mixins=True, is_a=True) -> List[SlotDefinitionName]: """ @@ -719,6 +749,22 @@ def permissible_value_ancestors(self, permissible_value_text: str, reflexive=reflexive, depth_first=depth_first) + @lru_cache() + def permissible_value_descendants(self, permissible_value_text: str, + enum_name: ENUM_NAME, + reflexive=True, + depth_first=True) -> List[str]: + """ + Closure of permissible_value_children method + :enum + """ + + + return _closure(lambda x: self.permissible_value_children(x, enum_name), + permissible_value_text, + reflexive=reflexive, + depth_first=depth_first) + @lru_cache() def enum_ancestors(self, enum_name: ENUM_NAME, imports=True, mixins=True, reflexive=True, is_a=True, depth_first=True) -> List[EnumDefinitionName]: diff --git a/tests/test_utils/test_schemaview.py b/tests/test_utils/test_schemaview.py index aca871ff..6e7c5383 100644 --- a/tests/test_utils/test_schemaview.py +++ b/tests/test_utils/test_schemaview.py @@ -53,9 +53,15 @@ def test_schemaview_enums(self): if pv == "CAT": self.assertEqual(view.permissible_value_parent(pv, e.name), None) self.assertEqual(view.permissible_value_ancestors(pv, e.name), ['CAT']) + self.assertIn("LION", view.permissible_value_descendants(pv, e.name)) + self.assertIn("ANGRY_LION", view.permissible_value_descendants(pv, e.name)) + self.assertNotIn("EAGLE", view.permissible_value_descendants(pv, e.name)) + if pv == "LION": + self.assertIn("ANGRY_LION", view.permissible_value_children(pv, e.name)) if pv == "ANGRY_LION": self.assertEqual(view.permissible_value_parent(pv, e.name), ['LION']) self.assertEqual(view.permissible_value_ancestors(pv, e.name), ['ANGRY_LION', 'LION', 'CAT']) + self.assertEquals(["ANGRY_LION"], view.permissible_value_descendants(pv, e.name)) for cn, c in view.all_classes().items(): if c.name == "Adult": self.assertEqual(view.class_ancestors(c.name), ['Adult', 'Person', 'HasAliases', 'Thing']) From 740cbea55f08b8e19586d07f7a407bb00197c179 Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 13 Dec 2023 13:14:01 -0800 Subject: [PATCH 3/4] add sibling children --- linkml_runtime/utils/schemaview.py | 8 ++++++-- tests/test_utils/input/kitchen_sink_noimports.yaml | 2 ++ tests/test_utils/test_schemaview.py | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/linkml_runtime/utils/schemaview.py b/linkml_runtime/utils/schemaview.py index 34e3de02..0900f036 100644 --- a/linkml_runtime/utils/schemaview.py +++ b/linkml_runtime/utils/schemaview.py @@ -624,13 +624,15 @@ def permissible_value_children(self, permissible_value: str, enum_name: ENUM_NAM """ :param enum_name: parent enum name :param permissible_value: permissible value - :return: all direct child enum names (is_a) + :return: all direct child permissible values (is_a) CAT: LION: is_a: CAT ANGRY_LION: is_a: LION + TABBY: + is_a: CAT BIRD: EAGLE: is_a: BIRD @@ -638,13 +640,15 @@ def permissible_value_children(self, permissible_value: str, enum_name: ENUM_NAM """ enum = self.get_enum(enum_name, strict=True) + children = [] if enum: if permissible_value in enum.permissible_values: pv = enum.permissible_values[permissible_value] for isapv in enum.permissible_values: isapv_entity = enum.permissible_values[isapv] if isapv_entity.is_a and pv.text == isapv_entity.is_a: - return [isapv] + children.append(isapv) + return children else: return [] diff --git a/tests/test_utils/input/kitchen_sink_noimports.yaml b/tests/test_utils/input/kitchen_sink_noimports.yaml index 9173ec43..6b3e7ec6 100644 --- a/tests/test_utils/input/kitchen_sink_noimports.yaml +++ b/tests/test_utils/input/kitchen_sink_noimports.yaml @@ -364,6 +364,8 @@ enums: is_a: OtherEnum permissible_values: CAT: + TABBY: + is_a: CAT LION: is_a: CAT ANGRY_LION: diff --git a/tests/test_utils/test_schemaview.py b/tests/test_utils/test_schemaview.py index 6e7c5383..deb29fa7 100644 --- a/tests/test_utils/test_schemaview.py +++ b/tests/test_utils/test_schemaview.py @@ -55,6 +55,9 @@ def test_schemaview_enums(self): self.assertEqual(view.permissible_value_ancestors(pv, e.name), ['CAT']) self.assertIn("LION", view.permissible_value_descendants(pv, e.name)) self.assertIn("ANGRY_LION", view.permissible_value_descendants(pv, e.name)) + self.assertIn("TABBY", view.permissible_value_descendants(pv, e.name)) + self.assertIn("TABBY", view.permissible_value_children(pv, e.name)) + self.assertIn("LION", view.permissible_value_children(pv, e.name)) self.assertNotIn("EAGLE", view.permissible_value_descendants(pv, e.name)) if pv == "LION": self.assertIn("ANGRY_LION", view.permissible_value_children(pv, e.name)) From 641c7b55d7a6a62643ea5abe23257678cb1f354d Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Wed, 13 Dec 2023 13:18:05 -0800 Subject: [PATCH 4/4] more tests --- linkml_runtime/utils/schemaview.py | 2 +- tests/test_utils/test_schemaview.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/linkml_runtime/utils/schemaview.py b/linkml_runtime/utils/schemaview.py index 0900f036..0471b5f8 100644 --- a/linkml_runtime/utils/schemaview.py +++ b/linkml_runtime/utils/schemaview.py @@ -650,7 +650,7 @@ def permissible_value_children(self, permissible_value: str, enum_name: ENUM_NAM children.append(isapv) return children else: - return [] + raise ValueError(f'No such enum as "{enum_name}"') @lru_cache() def slot_parents(self, slot_name: SLOT_NAME, imports=True, mixins=True, is_a=True) -> List[SlotDefinitionName]: diff --git a/tests/test_utils/test_schemaview.py b/tests/test_utils/test_schemaview.py index deb29fa7..576a2f15 100644 --- a/tests/test_utils/test_schemaview.py +++ b/tests/test_utils/test_schemaview.py @@ -47,6 +47,8 @@ def test_all_aliases(self): def test_schemaview_enums(self): view = SchemaView(SCHEMA_NO_IMPORTS) + with self.assertRaises(ValueError): + view.permissible_value_parent("not_a_pv", "not_an_enum") for en, e in view.all_enums().items(): if e.name == "Animals": for pv, v in e.permissible_values.items():