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 - [ ] 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:` 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 ## Docs TODOs
```{todolist} ```{todolist}

View file

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

View file

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

View file

@ -35,7 +35,7 @@ import h5py
import networkx as nx import networkx as nx
import numpy as np import numpy as np
from numpydantic.interface.hdf5 import H5ArrayPath from numpydantic.interface.hdf5 import H5ArrayPath
from pydantic import BaseModel from pydantic import BaseModel, ValidationError
from tqdm import tqdm from tqdm import tqdm
from nwb_linkml.maps.hdf5 import ( from nwb_linkml.maps.hdf5 import (
@ -167,7 +167,24 @@ def _load_node(
if "neurodata_type" in obj.attrs: if "neurodata_type" in obj.attrs:
model = provider.get_class(obj.attrs["namespace"], obj.attrs["neurodata_type"]) model = provider.get_class(obj.attrs["namespace"], obj.attrs["neurodata_type"])
try:
return model(**args) 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: else:
if "name" in args: if "name" in args:
del args["name"] del args["name"]