cast to value in container classes

This commit is contained in:
sneakers-the-rat 2024-09-25 21:18:09 -07:00
parent fc6f60ad61
commit 911a3ddb61
Signed by untrusted user who does not match committer: jonny
GPG key ID: 6DCB96EF1E4D232D
4 changed files with 27 additions and 4 deletions

View file

@ -53,6 +53,9 @@ Loading
- [ ] Top-level containers are still a little janky, eg. how `ProcessingModule` just accepts
extra args rather than properly abstracting `value` as a `__getitem__(self, key) -> T:`
Changes to linkml
- [ ] Allow parameterizing "extra" fields, so we don't have to stuff things into `value` dicts
## Docs TODOs
```{todolist}

View file

@ -129,7 +129,7 @@ class GroupAdapter(ClassAdapter):
# We are a top-level container class like ProcessingModule
base = self.build_base()
# remove all the attributes and replace with child slot
base.classes[0].attributes = [slot]
base.classes[0].attributes.append(slot)
return base
def handle_container_slot(self, cls: Group) -> BuildResult:

View file

@ -65,7 +65,10 @@ BASEMODEL_COERCE_CHILD = """
annotation = annotation.__args__[0]
try:
if issubclass(annotation, type(v)) and annotation is not type(v):
v = annotation(**{**v.__dict__, **v.__pydantic_extra__})
if v.__pydantic_extra__:
v = annotation(**{**v.__dict__, **v.__pydantic_extra__})
else:
v = annotation(**v.__dict__)
except TypeError:
# fine, annotation is a non-class type like a TypeVar
pass

View file

@ -35,7 +35,7 @@ import h5py
import networkx as nx
import numpy as np
from numpydantic.interface.hdf5 import H5ArrayPath
from pydantic import BaseModel
from pydantic import BaseModel, ValidationError
from tqdm import tqdm
from nwb_linkml.maps.hdf5 import (
@ -167,7 +167,24 @@ def _load_node(
if "neurodata_type" in obj.attrs:
model = provider.get_class(obj.attrs["namespace"], obj.attrs["neurodata_type"])
return model(**args)
try:
return model(**args)
except ValidationError as e1:
# try to restack extra fields into ``value``
if "value" in model.model_fields:
value_dict = {
key: val for key, val in args.items() if key not in model.model_fields
}
for k in value_dict:
del args[k]
args["value"] = value_dict
try:
return model(**args)
except Exception as e2:
raise e2 from e1
else:
raise e1
else:
if "name" in args:
del args["name"]