""" Test custom features of the pydantic generator Note that since this is largely a subclass, we don't test all of the functionality of the generator because it's tested in the base linkml package. """ import re import sys import typing import numpy as np import pytest from pydantic import BaseModel # def test_arraylike(imported_schema): # """ # Arraylike classes are converted to slots that specify nptyping arrays # # array: Optional[Union[ # NDArray[Shape["* x, * y"], Number], # NDArray[Shape["* x, * y, 3 z"], Number], # NDArray[Shape["* x, * y, 3 z, 4 a"], Number] # ]] = Field(None) # """ # # check that we have gotten an NDArray annotation and its shape is correct # array = imported_schema["core"].MainTopLevel.model_fields["array"].annotation # args = typing.get_args(array) # for i, shape in enumerate(("* x, * y", "* x, * y, 3 z", "* x, * y, 3 z, 4 a")): # assert isinstance(args[i], NDArrayMeta) # assert args[i].__args__[0].__args__ # assert args[i].__args__[1] == np.number # # # we shouldn't have an actual class for the array # assert not hasattr(imported_schema["core"], "MainTopLevel__Array") # assert not hasattr(imported_schema["core"], "MainTopLevelArray") # # # def test_inject_fields(imported_schema): # """ # Our root model should have the special fields we injected # """ # base = imported_schema["core"].ConfiguredBaseModel # assert "hdf5_path" in base.model_fields # assert "object_id" in base.model_fields # # # def test_linkml_meta(imported_schema): # """ # We should be able to store some linkml metadata with our classes # """ # meta = imported_schema["core"].LinkML_Meta # assert "tree_root" in meta.model_fields # assert imported_schema["core"].MainTopLevel.linkml_meta.default.tree_root == True # assert imported_schema["core"].OtherClass.linkml_meta.default.tree_root == False # # # def test_skip(linkml_schema): # """ # We can skip slots and classes # """ # modules = generate_and_import( # linkml_schema, # split=False, # generator_kwargs={ # "SKIP_SLOTS": ("SkippableSlot",), # "SKIP_CLASSES": ("Skippable", "skippable"), # }, # ) # assert not hasattr(modules["core"], "Skippable") # assert "SkippableSlot" not in modules["core"].MainTopLevel.model_fields # # # def test_inline_with_identifier(imported_schema): # """ # By default, if a class has an identifier attribute, it is inlined # as a string rather than its class. We overrode that to be able to make dictionaries of collections # """ # main = imported_schema["core"].MainTopLevel # inline = main.model_fields["inline_dict"].annotation # assert typing.get_origin(typing.get_args(inline)[0]) == dict # # god i hate pythons typing interface # otherclass, stillanother = typing.get_args( # typing.get_args(typing.get_args(inline)[0])[1] # ) # assert otherclass is imported_schema["core"].OtherClass # assert stillanother is imported_schema["core"].StillAnotherClass # # # def test_namespace(imported_schema): # """ # Namespace schema import all classes from the other schema # Returns: # # """ # ns = imported_schema["namespace"] # # for classname, modname in ( # ("MainThing", "test_schema.imported"), # ("Arraylike", "test_schema.imported"), # ("MainTopLevel", "test_schema.core"), # ("Skippable", "test_schema.core"), # ("OtherClass", "test_schema.core"), # ("StillAnotherClass", "test_schema.core"), # ): # assert hasattr(ns, classname) # if imported_schema["split"]: # assert getattr(ns, classname).__module__ == modname # # # def test_get_set_item(imported_schema): # """We can get and set without explicitly addressing array""" # cls_ = imported_schema["core"].MainTopLevel(array=np.array([[1, 2, 3], [4, 5, 6]])) # cls_[0] = 50 # assert (cls_[0] == 50).all() # assert (cls_.array[0] == 50).all() # # cls_[1, 1] = 100 # assert cls_[1, 1] == 100 # assert cls_.array[1, 1] == 100