Skip to content

Commit

Permalink
Merge pull request #39 from linkml/issue-38
Browse files Browse the repository at this point in the history
fixes #38
  • Loading branch information
cmungall authored Sep 10, 2021
2 parents 1b68040 + 164a7f3 commit f659e6b
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 4 deletions.
10 changes: 7 additions & 3 deletions linkml_runtime/utils/schemaview.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def load_import(self, imp: str, from_schema: SchemaDefinition = None):
sname = self.importmap.get(str(imp), imp) # Import map may use CURIE
sname = self.namespaces().uri_for(sname) if ':' in sname else sname
sname = self.importmap.get(str(sname), sname) # It may also use URI or other forms
print(f'Loading schema {sname} from {from_schema.source_file}')
logging.info(f'Loading schema {sname} from {from_schema.source_file}')
schema = load_schema_wrap(sname + '.yaml',
base_dir=os.path.dirname(from_schema.source_file) if from_schema.source_file else None)
return schema
Expand Down Expand Up @@ -667,8 +667,10 @@ def induced_slot(self, slot_name: SLOT_NAME, class_name: CLASS_NAME = None, impo
'minimum_value': lambda x, y: max(x, y),
}
for metaslot_name in SlotDefinition._inherited_slots:
# inheritance of slots; priority order
# slot-level assignment < ancestor slot_usage < self slot_usage
v = getattr(islot, metaslot_name, None)
for an in self.class_ancestors(class_name):
for an in reversed(self.class_ancestors(class_name)):
a = self.get_class(an, imports)
anc_slot_usage = a.slot_usage.get(slot_name, {})
v2 = getattr(anc_slot_usage, metaslot_name, None)
Expand All @@ -679,7 +681,9 @@ def induced_slot(self, slot_name: SLOT_NAME, class_name: CLASS_NAME = None, impo
if v2 is not None:
v = COMBINE[metaslot_name](v, v2)
else:
break
if v2 is not None:
v = v2
logging.debug(f'{v} takes precedence over {v2} for {islot.name}.{metaslot_name}')
if v is None:
if metaslot_name == 'range':
v = self.schema.default_range
Expand Down
2 changes: 2 additions & 0 deletions tests/test_utils/input/kitchen_sink.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,9 @@ slots:
- subset A
- subset B
related to:
range: Thing
type:
range: string
street:
city:
has birth event:
Expand Down
2 changes: 2 additions & 0 deletions tests/test_utils/input/kitchen_sink_noimports.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,9 @@ slots:
- subset A
- subset B
related to:
range: Thing
type:
range: string
street:
city:
has birth event:
Expand Down
13 changes: 12 additions & 1 deletion tests/test_utils/test_schemaview.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ def test_schemaview(self):
#assert list(view.annotation_dict('employed at')[]

if True:
for sn, s in view.all_slot().items():
logging.info(f'SN = {sn} RANGE={s.range}')
# this section is mostly for debugging
for cn in all_cls.keys():
logging.debug(f'{cn} PARENTS = {view.class_parents(cn)}')
Expand Down Expand Up @@ -86,9 +88,14 @@ def test_schemaview(self):
#assert view.get_class('Company').class_uri == 'prov:Agent'
assert view.get_uri('Company') == 'ks:Company'

# test induced slots

for c in ['Company', 'Person', 'Organization',]:
assert view.induced_slot('aliases', c).multivalued is True

assert view.get_identifier_slot('Company').name == 'id'
assert view.get_identifier_slot('Thing').name == 'id'
assert view.get_identifier_slot('FamilialRelationship') is None
for c in ['Company', 'Person', 'Organization', 'Thing']:
assert view.induced_slot('id', c).identifier is True
assert view.induced_slot('name', c).identifier is not True
Expand All @@ -99,10 +106,14 @@ def test_schemaview(self):
logging.debug(f's={s.range} // c = {c}')
assert s.range == 'date'
assert s.slot_uri == 'prov:startedAtTime'
# test slot_usage
assert view.induced_slot('age in years', 'Person').minimum_value == 0
assert view.induced_slot('age in years', 'Adult').minimum_value == 16
assert view.induced_slot('name', 'Person').pattern is not None
assert view.induced_slot('type', 'FamilialRelationship').range == 'FamilialRelationshipType'
assert view.induced_slot('related to', 'FamilialRelationship').range == 'Person'
assert view.get_slot('related to').range == 'Thing'
assert view.induced_slot('related to', 'Relationship').range == 'Thing'

a = view.get_class('activity')
self.assertCountEqual(a.exact_mappings, ['prov:Activity'])
Expand Down Expand Up @@ -213,7 +224,7 @@ def test_imports(self):
assert view.induced_slot('name', c).range == 'string'
for c in ['Event', 'EmploymentEvent', 'MedicalEvent']:
s = view.induced_slot('started at time', c)
logging.debug(f's={s.range} // c = {c}')
print(f's={s.range} // c = {c}')
assert s.range == 'date'
assert s.slot_uri == 'prov:startedAtTime'
assert view.induced_slot('age in years', 'Person').minimum_value == 0
Expand Down

0 comments on commit f659e6b

Please sign in to comment.