From 2b901343f6fcf9658369498268a7a12f700ca2c9 Mon Sep 17 00:00:00 2001 From: Sujay Patil Date: Wed, 22 May 2024 17:17:37 -0700 Subject: [PATCH 1/2] display any_of, exactly_one_of, none_of, all_of range assertions in class Usages section --- linkml_runtime/utils/schemaview.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/linkml_runtime/utils/schemaview.py b/linkml_runtime/utils/schemaview.py index 3dfb2a4f..92ebe980 100644 --- a/linkml_runtime/utils/schemaview.py +++ b/linkml_runtime/utils/schemaview.py @@ -1657,7 +1657,7 @@ def usage_index(self) -> Dict[ElementName, List[SchemaUsage]]: :return: dictionary of SchemaUsages keyed by used elements """ - ROLES = ['domain', 'range'] + ROLES = ['domain', 'range', 'any_of', 'exactly_one_of', 'none_of', 'all_of'] ix = defaultdict(list) for cn, c in self.all_classes().items(): direct_slots = c.slots @@ -1671,6 +1671,9 @@ def usage_index(self) -> Dict[ElementName, List[SchemaUsage]]: vl = [v] for x in vl: if x is not None: + if isinstance(x, AnonymousSlotExpression): + x = x.range + k = f"{k}[range]" u = SchemaUsage(used_by=cn, slot=sn, metaslot=k, used=x) u.inferred = sn in direct_slots ix[x].append(u) From ef4f5a55088f61d33bc8cf62b3166fd10a15cdd3 Mon Sep 17 00:00:00 2001 From: Sujay Patil Date: Thu, 23 May 2024 11:53:38 -0700 Subject: [PATCH 2/2] tests for any_of ranges in usage_index() --- linkml_runtime/utils/schemaview.py | 1 + .../input/kitchen_sink_noimports.yaml | 10 +++++ tests/test_utils/test_schemaview.py | 38 ++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/linkml_runtime/utils/schemaview.py b/linkml_runtime/utils/schemaview.py index 92ebe980..1511ca06 100644 --- a/linkml_runtime/utils/schemaview.py +++ b/linkml_runtime/utils/schemaview.py @@ -1674,6 +1674,7 @@ def usage_index(self) -> Dict[ElementName, List[SchemaUsage]]: if isinstance(x, AnonymousSlotExpression): x = x.range k = f"{k}[range]" + k = k.split("[")[0] + "[range]" if "[range]" in k else k u = SchemaUsage(used_by=cn, slot=sn, metaslot=k, used=x) u.inferred = sn in direct_slots ix[x].append(u) diff --git a/tests/test_utils/input/kitchen_sink_noimports.yaml b/tests/test_utils/input/kitchen_sink_noimports.yaml index 807fe6be..9d53d80a 100644 --- a/tests/test_utils/input/kitchen_sink_noimports.yaml +++ b/tests/test_utils/input/kitchen_sink_noimports.yaml @@ -87,9 +87,15 @@ classes: - age in years - addresses - has birth event + - reason_for_happiness slot_usage: name: pattern: "^\\S+ \\S+" ## do not do this in a real schema, people have all kinds of names + reason_for_happiness: + any_of: + - range: BirthEvent + - range: EmploymentEvent + - range: MarriageEvent Adult: is_a: Person @@ -353,6 +359,10 @@ slots: alias: zip range: string + reason_for_happiness: + range: string + required: false + enums: FamilialRelationshipType: diff --git a/tests/test_utils/test_schemaview.py b/tests/test_utils/test_schemaview.py index ec7f5fbe..367fb842 100644 --- a/tests/test_utils/test_schemaview.py +++ b/tests/test_utils/test_schemaview.py @@ -186,7 +186,7 @@ def test_schemaview(self): self.assertCountEqual(['id', 'name', ## From Thing 'has employment history', 'has familial relationships', 'has medical history', - AGE_IN_YEARS, 'addresses', 'has birth event', ## From Person + AGE_IN_YEARS, 'addresses', 'has birth event', 'reason_for_happiness', ## From Person 'aliases' ## From HasAliases ], view.class_slots('Person')) @@ -256,6 +256,42 @@ def test_schemaview(self): logging.debug(f' {k} = {v}') self.assertIn(SchemaUsage(used_by='FamilialRelationship', slot=RELATED_TO, metaslot='range', used='Person', inferred=False), u['Person']) + self.assertListEqual( + [SchemaUsage(used_by='Person', + slot='reason_for_happiness', + metaslot='any_of[range]', + used='MarriageEvent', + inferred=True + ), + SchemaUsage(used_by='Adult', + slot='reason_for_happiness', + metaslot='any_of[range]', + used='MarriageEvent', + inferred=False + )], + u['MarriageEvent']) + self.assertListEqual( + [SchemaUsage(used_by='Person', + slot='has employment history', + metaslot='range', + used='EmploymentEvent', + inferred=True), + SchemaUsage(used_by='Person', + slot='reason_for_happiness', + metaslot='any_of[range]', + used='EmploymentEvent', + inferred=True), + SchemaUsage(used_by='Adult', + slot='has employment history', + metaslot='range', + used='EmploymentEvent', + inferred=False), + SchemaUsage(used_by='Adult', + slot='reason_for_happiness', + metaslot='any_of[range]', + used='EmploymentEvent', + inferred=False)], + u['EmploymentEvent']) # test methods also work for attributes leaves = view.class_leaves()