Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Perf: Remove unnecessary deepcopy calls in Schemaview.induced_slot #296

Merged
merged 1 commit into from
Feb 14, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions linkml_runtime/utils/schemaview.py
Original file line number Diff line number Diff line change
Expand Up @@ -1224,15 +1224,16 @@ def induced_slot(self, slot_name: SLOT_NAME, class_name: CLASS_NAME = None, impo
:param imports: include imports closure
:return: dynamic slot constructed by inference
"""
slot = self.get_slot(slot_name, imports, attributes=False)
if class_name:
cls = self.get_class(class_name, imports, strict=True)
else:
cls = None

# attributes take priority over schema-level slot definitions, IF
# the attributes is declared for the class or an ancestor
slot_comes_from_attribute = False
if cls:
slot = self.get_slot(slot_name, imports, attributes=False)
# traverse ancestors (reflexive), starting with
# the main class
for an in self.class_ancestors(class_name):
Expand All @@ -1243,19 +1244,21 @@ def induced_slot(self, slot_name: SLOT_NAME, class_name: CLASS_NAME = None, impo
break
else:
slot = self.get_slot(slot_name, imports, attributes=True)

if slot is None:
raise ValueError(f"No such slot {slot_name} as an attribute of {class_name} ancestors "
"or as a slot definition in the schema")

# copy the slot, as it will be modified
induced_slot = deepcopy(slot)
induced_slot = copy(slot)
if not slot_comes_from_attribute:
slot_anc_names = self.slot_ancestors(slot_name, reflexive=True)
# inheritable slot: first propagate from ancestors
for anc_sn in reversed(slot_anc_names):
anc_slot = self.get_slot(anc_sn, attributes=False)
for metaslot_name in SlotDefinition._inherited_slots:
if getattr(anc_slot, metaslot_name, None):
setattr(induced_slot, metaslot_name, deepcopy(getattr(anc_slot, metaslot_name)))
setattr(induced_slot, metaslot_name, copy(getattr(anc_slot, metaslot_name)))
COMBINE = {
'maximum_value': lambda x, y: min(x, y),
'minimum_value': lambda x, y: max(x, y),
Expand Down Expand Up @@ -1302,7 +1305,7 @@ def induced_slot(self, slot_name: SLOT_NAME, class_name: CLASS_NAME = None, impo
if induced_slot.name in c.slots or induced_slot.name in c.attributes:
if c.name not in induced_slot.domain_of:
induced_slot.domain_of.append(c.name)
return deepcopy(induced_slot)
return induced_slot

@lru_cache()
def _metaslots_for_slot(self):
Expand Down
Loading