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

convert schemaview unittests to pytest #343

Merged
merged 9 commits into from
Oct 14, 2024
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ update_model:
cp -pr $(MODEL_DIR)/* linkml_runtime/linkml_model

test:
poetry run python -m unittest discover
poetry run pytest


# temporary measure until linkml-model is synced
linkml_runtime/processing/validation_datamodel.py: linkml_runtime/processing/validation_datamodel.yaml
Expand Down
32 changes: 15 additions & 17 deletions linkml_runtime/utils/schemaview.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
ENUM_NAME = Union[EnumDefinitionName, str]

ElementType = TypeVar("ElementType", bound=Element)
ElementNameType = TypeVar("ElementNameType", bound=Union[ElementName,str])
ElementNameType = TypeVar("ElementNameType", bound=Union[ElementName, str])
DefinitionType = TypeVar("DefinitionType", bound=Definition)
DefinitionNameType = TypeVar("DefinitionNameType", bound=Union[DefinitionName,str])
DefinitionNameType = TypeVar("DefinitionNameType", bound=Union[DefinitionName, str])
ElementDict = Dict[ElementNameType, ElementType]
DefDict = Dict[DefinitionNameType, DefinitionType]

Expand All @@ -53,7 +53,6 @@ class OrderedBy(Enum):
"""



def _closure(f, x, reflexive=True, depth_first=True, **kwargs):
if reflexive:
rv = [x]
Expand Down Expand Up @@ -84,7 +83,7 @@ def load_schema_wrap(path: str, **kwargs):
schema: SchemaDefinition
schema = yaml_loader.load(path, target_class=SchemaDefinition, **kwargs)
if "\n" not in path:
# if "\n" not in path and "://" not in path:
# if "\n" not in path and "://" not in path:
# only set path if the input is not a yaml string or URL.
# Setting the source path is necessary for relative imports;
# while initializing a schema with a yaml string is possible, there
Expand Down Expand Up @@ -229,7 +228,8 @@ def load_import(self, imp: str, from_schema: SchemaDefinition = None):
return schema

@lru_cache(None)
def imports_closure(self, imports: bool = True, traverse: Optional[bool] = None, inject_metadata=True) -> List[SchemaDefinitionName]:
def imports_closure(self, imports: bool = True, traverse: Optional[bool] = None, inject_metadata=True) -> List[
SchemaDefinitionName]:
"""
Return all imports

Expand Down Expand Up @@ -314,7 +314,7 @@ def imports_closure(self, imports: bool = True, traverse: Optional[bool] = None,
visited.add(sn)

# filter duplicates, keeping first entry
closure = list({k:None for k in closure}.keys())
closure = list({k: None for k in closure}.keys())

if inject_metadata:
for s in self.schema_map.values():
Expand Down Expand Up @@ -420,7 +420,6 @@ def _order_inheritance(self, elements: DefDict) -> DefDict:

return {s.name: s for s in slist}


@lru_cache(None)
def all_classes(self, ordered_by=OrderedBy.PRESERVE, imports=True) -> Dict[ClassDefinitionName, ClassDefinition]:
"""
Expand Down Expand Up @@ -865,15 +864,14 @@ def permissible_value_ancestors(self, permissible_value_text: str,

@lru_cache(None)
def permissible_value_descendants(self, permissible_value_text: str,
enum_name: ENUM_NAME,
reflexive=True,
depth_first=True) -> List[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,
Expand Down Expand Up @@ -1396,9 +1394,9 @@ def induced_slot(self, slot_name: SLOT_NAME, class_name: CLASS_NAME = None, impo
else:
# can rewrite below as:
# 1. if v2:
# 2. if v2 is not None and
# 2. if v2 is not None and
# (
# (isinstance(v2, (dict, list)) and v2) or
# (isinstance(v2, (dict, list)) and v2) or
# (isinstance(v2, JsonObj) and as_dict(v2))
# )
if not is_empty(v2):
Expand Down Expand Up @@ -1548,7 +1546,7 @@ def is_inlined(self, slot: SlotDefinition, imports=True) -> bool:
return True
elif slot.inlined_as_list:
return True

id_slot = self.get_identifier_slot(range, imports=imports)
if id_slot is None:
# must be inlined as has no identifier
Expand Down Expand Up @@ -1592,7 +1590,7 @@ def slot_range_as_union(self, slot: SlotDefinition) -> List[ElementName]:
"""
Returns all applicable ranges for a slot

Typically any given slot has exactly one range, and one metamodel element type,
Typically, any given slot has exactly one range, and one metamodel element type,
but a proposed feature in LinkML 1.2 is range expressions, where ranges can be defined as unions

:param slot:
Expand All @@ -1604,9 +1602,9 @@ def slot_range_as_union(self, slot: SlotDefinition) -> List[ElementName]:
if x.range:
range_union_of.append(x.range)
return range_union_of

def get_classes_by_slot(
self, slot: SlotDefinition, include_induced: bool = False
self, slot: SlotDefinition, include_induced: bool = False
) -> List[ClassDefinitionName]:
"""Get all classes that use a given slot, either as a direct or induced slot.

Expand Down
Loading
Loading