diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_base.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_base.py index 0aca06c..534e1d1 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_base.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_1_0.hdmf_common_table import Container, Data, DynamicTable @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_behavior.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_behavior.py index 5136ecd..3b7be04 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_behavior.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_behavior.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_0.core_nwb_base import ( NWBDataInterface, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_device.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_device.py index c08c6ff..8f90b2e 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_device.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_device.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_0.core_nwb_base import NWBContainer @@ -31,7 +31,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -86,6 +86,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ecephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ecephys.py index 42d8653..e8f1dd5 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ecephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ecephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_0.core_nwb_base import ( @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_epoch.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_epoch.py index 3eef400..f1c7f15 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_epoch.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_epoch.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_0.core_nwb_base import TimeSeries @@ -46,7 +47,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -101,6 +102,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_file.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_file.py index 613b948..acbd7b1 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_file.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_file.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_0.core_nwb_base import ( NWBContainer, @@ -50,7 +50,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -105,6 +105,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_icephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_icephys.py index be65250..0117aab 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_icephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_icephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_0.core_nwb_base import ( @@ -52,7 +53,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -107,6 +108,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_image.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_image.py index 8185f44..f77d91c 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_image.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_image.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_0.core_nwb_base import Image, TimeSeries, TimeSeriesStartingTime, TimeSeriesSync @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_misc.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_misc.py index e7e1279..8f354bb 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_misc.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_misc.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_0.core_nwb_base import TimeSeries, TimeSeriesStartingTime, TimeSeriesSync @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ogen.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ogen.py index 100fc9b..b6cc006 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ogen.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ogen.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_0.core_nwb_base import ( NWBContainer, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ophys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ophys.py index a8f98a2..5703a71 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ophys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_ophys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_0.core_nwb_base import ( @@ -49,7 +50,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -104,6 +105,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_retinotopy.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_retinotopy.py index 718a1c6..af02819 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_retinotopy.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/core_nwb_retinotopy.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_0.core_nwb_base import NWBData, NWBDataInterface @@ -41,7 +42,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -96,6 +97,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/namespace.py index 92e7d3e..510f1a8 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_0/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_0.core_nwb_base import ( Image, @@ -159,7 +159,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -214,6 +214,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_base.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_base.py index d92282c..d8d3a5c 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_base.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_1_2.hdmf_common_table import Container, Data, DynamicTable @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_behavior.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_behavior.py index 2c853af..34a1425 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_behavior.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_behavior.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_1.core_nwb_base import ( NWBDataInterface, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_device.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_device.py index b1b1b16..154b9e0 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_device.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_device.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_1.core_nwb_base import NWBContainer @@ -31,7 +31,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -86,6 +86,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ecephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ecephys.py index f74a7e7..d3aecd0 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ecephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ecephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_1.core_nwb_base import ( @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_epoch.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_epoch.py index 7f4bb40..7d0c58f 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_epoch.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_epoch.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_1.core_nwb_base import TimeSeries @@ -46,7 +47,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -101,6 +102,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_file.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_file.py index b203b9b..6fb88f8 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_file.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_file.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_1.core_nwb_base import ( NWBContainer, @@ -50,7 +50,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -105,6 +105,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_icephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_icephys.py index 772841e..dda06d4 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_icephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_icephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_1.core_nwb_base import ( @@ -52,7 +53,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -107,6 +108,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_image.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_image.py index 5e824fa..b79228e 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_image.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_image.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_1.core_nwb_base import Image, TimeSeries, TimeSeriesStartingTime, TimeSeriesSync @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_misc.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_misc.py index e212e58..2de9d2b 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_misc.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_misc.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_1.core_nwb_base import TimeSeries, TimeSeriesStartingTime, TimeSeriesSync @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ogen.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ogen.py index 81dcca7..030cb10 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ogen.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ogen.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_1.core_nwb_base import ( NWBContainer, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ophys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ophys.py index e054ec2..d77e6e8 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ophys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_ophys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_1.core_nwb_base import ( @@ -49,7 +50,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -104,6 +105,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_retinotopy.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_retinotopy.py index 0b7b720..76510e5 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_retinotopy.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/core_nwb_retinotopy.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_1.core_nwb_base import NWBData, NWBDataInterface @@ -41,7 +42,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -96,6 +97,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/namespace.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/namespace.py index 228bdac..c2dec9e 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_1/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_1.core_nwb_base import ( Image, @@ -159,7 +159,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -214,6 +214,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_base.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_base.py index d2b5e5c..4ceb281 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_base.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_1_3.hdmf_common_table import Container, Data, DynamicTable @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_behavior.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_behavior.py index 0935da2..0eb31ab 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_behavior.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_behavior.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_2.core_nwb_base import ( NWBDataInterface, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_device.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_device.py index 4aa5ede..2db19bc 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_device.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_device.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_2.core_nwb_base import NWBContainer @@ -31,7 +31,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -86,6 +86,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ecephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ecephys.py index 4336705..fe36215 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ecephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ecephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_2.core_nwb_base import ( @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_epoch.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_epoch.py index 7731ed5..5eb1fae 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_epoch.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_epoch.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_2.core_nwb_base import TimeSeries @@ -46,7 +47,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -101,6 +102,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_file.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_file.py index f694d2c..b207a06 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_file.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_file.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_2.core_nwb_base import ( NWBContainer, @@ -50,7 +50,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -105,6 +105,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_icephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_icephys.py index 4858631..6684ca5 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_icephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_icephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_2.core_nwb_base import ( @@ -52,7 +53,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -107,6 +108,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_image.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_image.py index 56bc5e9..69265e7 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_image.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_image.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_2.core_nwb_base import Image, TimeSeries, TimeSeriesStartingTime, TimeSeriesSync @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_misc.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_misc.py index 59564fe..52edd9e 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_misc.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_misc.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_2.core_nwb_base import TimeSeries, TimeSeriesStartingTime, TimeSeriesSync @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ogen.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ogen.py index 36196b3..3f45f68 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ogen.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ogen.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_2.core_nwb_base import ( NWBContainer, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ophys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ophys.py index f2b41df..17bc9b5 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ophys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_ophys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_2.core_nwb_base import ( @@ -49,7 +50,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -104,6 +105,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_retinotopy.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_retinotopy.py index 3f6e756..7371a8e 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_retinotopy.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/core_nwb_retinotopy.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_2.core_nwb_base import NWBDataInterface @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/namespace.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/namespace.py index b89e5a5..e936b85 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_2/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_2.core_nwb_base import ( Image, @@ -162,7 +162,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -217,6 +217,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_base.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_base.py index b163e24..28eae4b 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_base.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_1_3.hdmf_common_table import Container, Data, DynamicTable @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_behavior.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_behavior.py index 5bcab66..cc77ca9 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_behavior.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_behavior.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_4.core_nwb_base import ( NWBDataInterface, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_device.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_device.py index f370d51..cfd7e71 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_device.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_device.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_4.core_nwb_base import NWBContainer @@ -31,7 +31,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -86,6 +86,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ecephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ecephys.py index f28980b..37357ce 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ecephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ecephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_4.core_nwb_base import ( @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_epoch.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_epoch.py index cb37363..35122ba 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_epoch.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_epoch.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_4.core_nwb_base import TimeSeries @@ -46,7 +47,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -101,6 +102,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_file.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_file.py index 8172d22..ad07027 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_file.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_file.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_4.core_nwb_base import ( NWBContainer, @@ -51,7 +51,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -106,6 +106,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_icephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_icephys.py index 4c5a2cf..26d6210 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_icephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_icephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_4.core_nwb_base import ( @@ -52,7 +53,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -107,6 +108,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_image.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_image.py index bf08d2b..08fed95 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_image.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_image.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_4.core_nwb_base import Image, TimeSeries, TimeSeriesStartingTime, TimeSeriesSync @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_misc.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_misc.py index f98882b..e382147 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_misc.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_misc.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_4.core_nwb_base import TimeSeries, TimeSeriesStartingTime, TimeSeriesSync @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ogen.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ogen.py index 38f8335..64da160 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ogen.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ogen.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_4.core_nwb_base import ( NWBContainer, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ophys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ophys.py index 1199e61..8c88d0e 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ophys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_ophys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_4.core_nwb_base import ( @@ -55,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -110,6 +111,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_retinotopy.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_retinotopy.py index 0af340d..75a8554 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_retinotopy.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/core_nwb_retinotopy.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_4.core_nwb_base import NWBDataInterface @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/namespace.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/namespace.py index 69651fd..f825bfd 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_4/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_4.core_nwb_base import ( Image, @@ -169,7 +169,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -224,6 +224,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_base.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_base.py index 3afefe9..b57367d 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_base.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_1_3.hdmf_common_table import Container, Data, DynamicTable @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_behavior.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_behavior.py index f6ae2e5..e7f2cdd 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_behavior.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_behavior.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_5.core_nwb_base import ( NWBDataInterface, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_device.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_device.py index eec3289..9399bcc 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_device.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_device.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_5.core_nwb_base import NWBContainer @@ -31,7 +31,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -86,6 +86,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ecephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ecephys.py index 90b585e..1ae2798 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ecephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ecephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_5.core_nwb_base import ( @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_epoch.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_epoch.py index 71eeb95..0d907f0 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_epoch.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_epoch.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_5.core_nwb_base import TimeSeries @@ -46,7 +47,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -101,6 +102,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_file.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_file.py index 6648e37..c280107 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_file.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_file.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_5.core_nwb_base import ( NWBContainer, @@ -51,7 +51,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -106,6 +106,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_icephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_icephys.py index 403fec4..15354c8 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_icephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_icephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_5.core_nwb_base import ( @@ -52,7 +53,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -107,6 +108,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_image.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_image.py index 9c670dd..bc724f8 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_image.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_image.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_5.core_nwb_base import Image, TimeSeries, TimeSeriesStartingTime, TimeSeriesSync @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_misc.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_misc.py index e73895a..6d59495 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_misc.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_misc.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_5.core_nwb_base import TimeSeries, TimeSeriesStartingTime, TimeSeriesSync @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ogen.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ogen.py index 8c8b746..42b2190 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ogen.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ogen.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_5.core_nwb_base import ( NWBContainer, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ophys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ophys.py index a31241c..feab6d7 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ophys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_ophys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_2_5.core_nwb_base import ( @@ -55,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -110,6 +111,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_retinotopy.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_retinotopy.py index 5d13706..2cd2579 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_retinotopy.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/core_nwb_retinotopy.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_5.core_nwb_base import NWBDataInterface @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/namespace.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/namespace.py index 6be8c81..0c925e7 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_2_5/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_2_5.core_nwb_base import ( Image, @@ -169,7 +169,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -224,6 +224,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_base.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_base.py index 5f82fcd..ef01b9a 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_base.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_5_0.hdmf_common_base import Container, Data from ...hdmf_common.v1_5_0.hdmf_common_table import DynamicTable @@ -33,7 +33,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -88,6 +88,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_behavior.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_behavior.py index afb8921..727c35d 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_behavior.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_behavior.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_3_0.core_nwb_base import ( NWBDataInterface, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_device.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_device.py index 2fc40f2..d44423e 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_device.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_device.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_3_0.core_nwb_base import NWBContainer @@ -31,7 +31,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -86,6 +86,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_ecephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_ecephys.py index 6af7ff2..109d3e7 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_ecephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_ecephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_3_0.core_nwb_base import ( @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_epoch.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_epoch.py index 0a22431..2f539de 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_epoch.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_epoch.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_3_0.core_nwb_base import TimeSeries @@ -46,7 +47,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -101,6 +102,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_file.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_file.py index 13d67cb..2cc8c0b 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_file.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_file.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_3_0.core_nwb_base import ( NWBContainer, @@ -51,7 +51,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -106,6 +106,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -242,6 +264,9 @@ class NWBFile(NWBContainer): description="""Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.""", ) units: Optional[Units] = Field(None, description="""Data about sorted spike units.""") + specifications: Optional[dict] = Field( + None, description="""Nested dictionary of schema specifications""" + ) class NWBFileStimulus(ConfiguredBaseModel): @@ -340,10 +365,6 @@ class NWBFileGeneral(ConfiguredBaseModel): None, description="""Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.""", ) - lab_meta_data: Optional[Dict[str, LabMetaData]] = Field( - None, - description="""Place-holder than can be extended so that lab-specific meta-data can be placed in /general.""", - ) devices: Optional[Dict[str, Device]] = Field( None, description="""Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.""", @@ -369,6 +390,10 @@ class NWBFileGeneral(ConfiguredBaseModel): description="""Metadata related to optophysiology.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "ImagingPlane"}]}}, ) + value: Optional[Dict[str, LabMetaData]] = Field( + None, + description="""Place-holder than can be extended so that lab-specific meta-data can be placed in /general.""", + ) class GeneralSourceScript(ConfiguredBaseModel): @@ -404,12 +429,12 @@ class GeneralExtracellularEphys(ConfiguredBaseModel): } }, ) - electrode_group: Optional[Dict[str, ElectrodeGroup]] = Field( - None, description="""Physical group of electrodes.""" - ) electrodes: Optional[ExtracellularEphysElectrodes] = Field( None, description="""A table of all electrodes (i.e. channels) used for recording.""" ) + value: Optional[Dict[str, ElectrodeGroup]] = Field( + None, description="""Physical group of electrodes.""" + ) class ExtracellularEphysElectrodes(DynamicTable): @@ -565,12 +590,12 @@ class GeneralIntracellularEphys(ConfiguredBaseModel): None, description="""Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.""", ) - intracellular_electrode: Optional[Dict[str, IntracellularElectrode]] = Field( - None, description="""An intracellular electrode.""" - ) sweep_table: Optional[SweepTable] = Field( None, description="""The table which groups different PatchClampSeries together.""" ) + value: Optional[Dict[str, IntracellularElectrode]] = Field( + None, description="""An intracellular electrode.""" + ) class NWBFileIntervals(ConfiguredBaseModel): @@ -596,7 +621,7 @@ class NWBFileIntervals(ConfiguredBaseModel): invalid_times: Optional[TimeIntervals] = Field( None, description="""Time intervals that should be removed from analysis.""" ) - time_intervals: Optional[Dict[str, TimeIntervals]] = Field( + value: Optional[Dict[str, TimeIntervals]] = Field( None, description="""Optional additional table(s) for describing other experimental time intervals.""", ) diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_icephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_icephys.py index 6094a09..095685f 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_icephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_icephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_3_0.core_nwb_base import ( @@ -52,7 +53,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -107,6 +108,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_image.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_image.py index 4964397..51e194b 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_image.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_image.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_3_0.core_nwb_base import Image, TimeSeries, TimeSeriesStartingTime, TimeSeriesSync from ...core.v2_3_0.core_nwb_device import Device @@ -33,7 +33,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -88,6 +88,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_misc.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_misc.py index 95576ab..2b98315 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_misc.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_misc.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_3_0.core_nwb_base import TimeSeries, TimeSeriesStartingTime, TimeSeriesSync @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_ogen.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_ogen.py index e66477e..9c2910f 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_ogen.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_ogen.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_3_0.core_nwb_base import ( NWBContainer, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_ophys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_ophys.py index 6813220..72c78b0 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_ophys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_ophys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_3_0.core_nwb_base import ( @@ -55,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -110,6 +111,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_retinotopy.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_retinotopy.py index 67ebc9b..5a4f132 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_retinotopy.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/core_nwb_retinotopy.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_3_0.core_nwb_base import NWBDataInterface @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/namespace.py index c562bb8..6791a67 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_3_0/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_3_0.core_nwb_base import ( Image, @@ -186,7 +186,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -241,6 +241,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_base.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_base.py index a3f929e..6375215 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_base.py @@ -46,7 +46,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -101,6 +101,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_behavior.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_behavior.py index 7a46192..ffc7c01 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_behavior.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_behavior.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_4_0.core_nwb_base import ( NWBDataInterface, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_device.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_device.py index 9510135..dc33187 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_device.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_device.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_4_0.core_nwb_base import NWBContainer @@ -31,7 +31,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -86,6 +86,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_ecephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_ecephys.py index 44503f1..212152e 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_ecephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_ecephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_4_0.core_nwb_base import ( @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_epoch.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_epoch.py index 1c1b5ef..443ab75 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_epoch.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_epoch.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_4_0.core_nwb_base import TimeSeries @@ -46,7 +47,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -101,6 +102,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_file.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_file.py index 26bd1fa..2c0dd21 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_file.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_file.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_4_0.core_nwb_base import ( NWBContainer, @@ -59,7 +59,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -114,6 +114,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -250,6 +272,9 @@ class NWBFile(NWBContainer): description="""Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.""", ) units: Optional[Units] = Field(None, description="""Data about sorted spike units.""") + specifications: Optional[dict] = Field( + None, description="""Nested dictionary of schema specifications""" + ) class NWBFileStimulus(ConfiguredBaseModel): @@ -348,10 +373,6 @@ class NWBFileGeneral(ConfiguredBaseModel): None, description="""Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.""", ) - lab_meta_data: Optional[Dict[str, LabMetaData]] = Field( - None, - description="""Place-holder than can be extended so that lab-specific meta-data can be placed in /general.""", - ) devices: Optional[Dict[str, Device]] = Field( None, description="""Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.""", @@ -377,6 +398,10 @@ class NWBFileGeneral(ConfiguredBaseModel): description="""Metadata related to optophysiology.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "ImagingPlane"}]}}, ) + value: Optional[Dict[str, LabMetaData]] = Field( + None, + description="""Place-holder than can be extended so that lab-specific meta-data can be placed in /general.""", + ) class GeneralSourceScript(ConfiguredBaseModel): @@ -412,12 +437,12 @@ class GeneralExtracellularEphys(ConfiguredBaseModel): } }, ) - electrode_group: Optional[Dict[str, ElectrodeGroup]] = Field( - None, description="""Physical group of electrodes.""" - ) electrodes: Optional[ExtracellularEphysElectrodes] = Field( None, description="""A table of all electrodes (i.e. channels) used for recording.""" ) + value: Optional[Dict[str, ElectrodeGroup]] = Field( + None, description="""Physical group of electrodes.""" + ) class ExtracellularEphysElectrodes(DynamicTable): @@ -573,9 +598,6 @@ class GeneralIntracellularEphys(ConfiguredBaseModel): None, description="""[DEPRECATED] Use IntracellularElectrode.filtering instead. Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.""", ) - intracellular_electrode: Optional[Dict[str, IntracellularElectrode]] = Field( - None, description="""An intracellular electrode.""" - ) sweep_table: Optional[SweepTable] = Field( None, description="""[DEPRECATED] Table used to group different PatchClampSeries. SweepTable is being replaced by IntracellularRecordingsTable and SimultaneousRecordingsTable tabels. Additional SequentialRecordingsTable, RepetitionsTable and ExperimentalConditions tables provide enhanced support for experiment metadata.""", @@ -600,6 +622,9 @@ class GeneralIntracellularEphys(ConfiguredBaseModel): None, description="""A table for grouping different intracellular recording repetitions together that belong to the same experimental experimental_conditions.""", ) + value: Optional[Dict[str, IntracellularElectrode]] = Field( + None, description="""An intracellular electrode.""" + ) class NWBFileIntervals(ConfiguredBaseModel): @@ -625,7 +650,7 @@ class NWBFileIntervals(ConfiguredBaseModel): invalid_times: Optional[TimeIntervals] = Field( None, description="""Time intervals that should be removed from analysis.""" ) - time_intervals: Optional[Dict[str, TimeIntervals]] = Field( + value: Optional[Dict[str, TimeIntervals]] = Field( None, description="""Optional additional table(s) for describing other experimental time intervals.""", ) diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_icephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_icephys.py index d6191fa..1ec7e47 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_icephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_icephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_4_0.core_nwb_base import ( @@ -55,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -110,6 +111,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_image.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_image.py index 1ed0f7f..867e901 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_image.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_image.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_4_0.core_nwb_base import Image, TimeSeries, TimeSeriesStartingTime, TimeSeriesSync from ...core.v2_4_0.core_nwb_device import Device @@ -33,7 +33,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -88,6 +88,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_misc.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_misc.py index 4f4825b..c15bfaf 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_misc.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_misc.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_4_0.core_nwb_base import TimeSeries, TimeSeriesStartingTime, TimeSeriesSync @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_ogen.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_ogen.py index 64478a5..1b3b008 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_ogen.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_ogen.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_4_0.core_nwb_base import ( NWBContainer, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_ophys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_ophys.py index 6e69afa..6eb8098 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_ophys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_ophys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_4_0.core_nwb_base import ( @@ -55,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -110,6 +111,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_retinotopy.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_retinotopy.py index 3024bed..aa95910 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_retinotopy.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/core_nwb_retinotopy.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_4_0.core_nwb_base import NWBDataInterface @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/namespace.py index 2055051..287ae0d 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_4_0/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_4_0.core_nwb_base import ( Image, @@ -199,7 +199,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -254,6 +254,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_base.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_base.py index abb0545..eca9ced 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_base.py @@ -57,7 +57,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -112,6 +112,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_behavior.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_behavior.py index 3df8abe..2b89eab 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_behavior.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_behavior.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_5_0.core_nwb_base import ( NWBDataInterface, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_device.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_device.py index 6ac30a8..6af43d3 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_device.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_device.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_5_0.core_nwb_base import NWBContainer @@ -31,7 +31,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -86,6 +86,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_ecephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_ecephys.py index eec63d7..7521407 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_ecephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_ecephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_5_0.core_nwb_base import ( @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_epoch.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_epoch.py index 39d2d4f..72fa554 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_epoch.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_epoch.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_5_0.core_nwb_base import TimeSeriesReferenceVectorData @@ -46,7 +47,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -101,6 +102,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_file.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_file.py index 338a1cb..b682562 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_file.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_file.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_5_0.core_nwb_base import ( Images, @@ -60,7 +60,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -115,6 +115,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -251,6 +273,9 @@ class NWBFile(NWBContainer): description="""Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.""", ) units: Optional[Units] = Field(None, description="""Data about sorted spike units.""") + specifications: Optional[dict] = Field( + None, description="""Nested dictionary of schema specifications""" + ) class NWBFileStimulus(ConfiguredBaseModel): @@ -351,10 +376,6 @@ class NWBFileGeneral(ConfiguredBaseModel): None, description="""Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.""", ) - lab_meta_data: Optional[Dict[str, LabMetaData]] = Field( - None, - description="""Place-holder than can be extended so that lab-specific meta-data can be placed in /general.""", - ) devices: Optional[Dict[str, Device]] = Field( None, description="""Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.""", @@ -380,6 +401,10 @@ class NWBFileGeneral(ConfiguredBaseModel): description="""Metadata related to optophysiology.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "ImagingPlane"}]}}, ) + value: Optional[Dict[str, LabMetaData]] = Field( + None, + description="""Place-holder than can be extended so that lab-specific meta-data can be placed in /general.""", + ) class GeneralSourceScript(ConfiguredBaseModel): @@ -415,12 +440,12 @@ class GeneralExtracellularEphys(ConfiguredBaseModel): } }, ) - electrode_group: Optional[Dict[str, ElectrodeGroup]] = Field( - None, description="""Physical group of electrodes.""" - ) electrodes: Optional[ExtracellularEphysElectrodes] = Field( None, description="""A table of all electrodes (i.e. channels) used for recording.""" ) + value: Optional[Dict[str, ElectrodeGroup]] = Field( + None, description="""Physical group of electrodes.""" + ) class ExtracellularEphysElectrodes(DynamicTable): @@ -576,9 +601,6 @@ class GeneralIntracellularEphys(ConfiguredBaseModel): None, description="""[DEPRECATED] Use IntracellularElectrode.filtering instead. Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.""", ) - intracellular_electrode: Optional[Dict[str, IntracellularElectrode]] = Field( - None, description="""An intracellular electrode.""" - ) sweep_table: Optional[SweepTable] = Field( None, description="""[DEPRECATED] Table used to group different PatchClampSeries. SweepTable is being replaced by IntracellularRecordingsTable and SimultaneousRecordingsTable tabels. Additional SequentialRecordingsTable, RepetitionsTable and ExperimentalConditions tables provide enhanced support for experiment metadata.""", @@ -603,6 +625,9 @@ class GeneralIntracellularEphys(ConfiguredBaseModel): None, description="""A table for grouping different intracellular recording repetitions together that belong to the same experimental experimental_conditions.""", ) + value: Optional[Dict[str, IntracellularElectrode]] = Field( + None, description="""An intracellular electrode.""" + ) class NWBFileIntervals(ConfiguredBaseModel): @@ -628,7 +653,7 @@ class NWBFileIntervals(ConfiguredBaseModel): invalid_times: Optional[TimeIntervals] = Field( None, description="""Time intervals that should be removed from analysis.""" ) - time_intervals: Optional[Dict[str, TimeIntervals]] = Field( + value: Optional[Dict[str, TimeIntervals]] = Field( None, description="""Optional additional table(s) for describing other experimental time intervals.""", ) diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_icephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_icephys.py index 5628183..3a26054 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_icephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_icephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_5_0.core_nwb_base import ( @@ -55,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -110,6 +111,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_image.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_image.py index 4d62c19..ca85b5f 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_image.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_image.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_5_0.core_nwb_base import ( Image, @@ -39,7 +39,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -94,6 +94,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_misc.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_misc.py index 13bfb53..bbf932a 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_misc.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_misc.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_5_0.core_nwb_base import TimeSeries, TimeSeriesStartingTime, TimeSeriesSync @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_ogen.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_ogen.py index 724bd92..1d5b11d 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_ogen.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_ogen.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_5_0.core_nwb_base import ( NWBContainer, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_ophys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_ophys.py index 78e9c62..ff4af91 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_ophys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_ophys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_5_0.core_nwb_base import ( @@ -55,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -110,6 +111,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_retinotopy.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_retinotopy.py index f886ffc..6dd0861 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_retinotopy.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/core_nwb_retinotopy.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_5_0.core_nwb_base import NWBDataInterface @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/namespace.py index 08d0b93..597113b 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_5_0/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_5_0.core_nwb_base import ( Image, @@ -200,7 +200,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -255,6 +255,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_base.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_base.py index 5a1224a..3524f64 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_base.py @@ -57,7 +57,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -112,6 +112,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_behavior.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_behavior.py index 2abebb7..74fe1cd 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_behavior.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_behavior.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_6_0_alpha.core_nwb_base import ( NWBDataInterface, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_device.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_device.py index 4aa7351..a2f28f3 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_device.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_device.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_6_0_alpha.core_nwb_base import NWBContainer @@ -31,7 +31,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -86,6 +86,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_ecephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_ecephys.py index d3bc1a8..d9c78cd 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_ecephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_ecephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_6_0_alpha.core_nwb_base import ( @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_epoch.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_epoch.py index 907f235..c40d820 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_epoch.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_epoch.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_6_0_alpha.core_nwb_base import TimeSeriesReferenceVectorData @@ -46,7 +47,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -101,6 +102,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_file.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_file.py index 5ad7185..38cf653 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_file.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_file.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_6_0_alpha.core_nwb_base import ( Images, @@ -60,7 +60,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -115,6 +115,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -251,6 +273,9 @@ class NWBFile(NWBContainer): description="""Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.""", ) units: Optional[Units] = Field(None, description="""Data about sorted spike units.""") + specifications: Optional[dict] = Field( + None, description="""Nested dictionary of schema specifications""" + ) class NWBFileStimulus(ConfiguredBaseModel): @@ -351,10 +376,6 @@ class NWBFileGeneral(ConfiguredBaseModel): None, description="""Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.""", ) - lab_meta_data: Optional[Dict[str, LabMetaData]] = Field( - None, - description="""Place-holder than can be extended so that lab-specific meta-data can be placed in /general.""", - ) devices: Optional[Dict[str, Device]] = Field( None, description="""Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.""", @@ -380,6 +401,10 @@ class NWBFileGeneral(ConfiguredBaseModel): description="""Metadata related to optophysiology.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "ImagingPlane"}]}}, ) + value: Optional[Dict[str, LabMetaData]] = Field( + None, + description="""Place-holder than can be extended so that lab-specific meta-data can be placed in /general.""", + ) class GeneralSourceScript(ConfiguredBaseModel): @@ -415,12 +440,12 @@ class GeneralExtracellularEphys(ConfiguredBaseModel): } }, ) - electrode_group: Optional[Dict[str, ElectrodeGroup]] = Field( - None, description="""Physical group of electrodes.""" - ) electrodes: Optional[ExtracellularEphysElectrodes] = Field( None, description="""A table of all electrodes (i.e. channels) used for recording.""" ) + value: Optional[Dict[str, ElectrodeGroup]] = Field( + None, description="""Physical group of electrodes.""" + ) class ExtracellularEphysElectrodes(DynamicTable): @@ -576,9 +601,6 @@ class GeneralIntracellularEphys(ConfiguredBaseModel): None, description="""[DEPRECATED] Use IntracellularElectrode.filtering instead. Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.""", ) - intracellular_electrode: Optional[Dict[str, IntracellularElectrode]] = Field( - None, description="""An intracellular electrode.""" - ) sweep_table: Optional[SweepTable] = Field( None, description="""[DEPRECATED] Table used to group different PatchClampSeries. SweepTable is being replaced by IntracellularRecordingsTable and SimultaneousRecordingsTable tabels. Additional SequentialRecordingsTable, RepetitionsTable and ExperimentalConditions tables provide enhanced support for experiment metadata.""", @@ -603,6 +625,9 @@ class GeneralIntracellularEphys(ConfiguredBaseModel): None, description="""A table for grouping different intracellular recording repetitions together that belong to the same experimental experimental_conditions.""", ) + value: Optional[Dict[str, IntracellularElectrode]] = Field( + None, description="""An intracellular electrode.""" + ) class NWBFileIntervals(ConfiguredBaseModel): @@ -628,7 +653,7 @@ class NWBFileIntervals(ConfiguredBaseModel): invalid_times: Optional[TimeIntervals] = Field( None, description="""Time intervals that should be removed from analysis.""" ) - time_intervals: Optional[Dict[str, TimeIntervals]] = Field( + value: Optional[Dict[str, TimeIntervals]] = Field( None, description="""Optional additional table(s) for describing other experimental time intervals.""", ) diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_icephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_icephys.py index 84a24e2..40071e1 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_icephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_icephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_6_0_alpha.core_nwb_base import ( @@ -55,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -110,6 +111,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_image.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_image.py index 733114f..f7700ad 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_image.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_image.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_6_0_alpha.core_nwb_base import ( Image, @@ -39,7 +39,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -94,6 +94,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_misc.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_misc.py index 43160a9..40579cd 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_misc.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_misc.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_6_0_alpha.core_nwb_base import TimeSeries, TimeSeriesStartingTime, TimeSeriesSync @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_ogen.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_ogen.py index f3e6a15..1353cf5 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_ogen.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_ogen.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_6_0_alpha.core_nwb_base import ( NWBContainer, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_ophys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_ophys.py index d736ef5..2900441 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_ophys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_ophys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_6_0_alpha.core_nwb_base import ( @@ -59,7 +60,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -114,6 +115,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_retinotopy.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_retinotopy.py index 334a02e..ef83e27 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_retinotopy.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/core_nwb_retinotopy.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_6_0_alpha.core_nwb_base import NWBDataInterface @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/namespace.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/namespace.py index dd19a19..86a32bf 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_6_0_alpha/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_6_0_alpha.core_nwb_base import ( Image, @@ -202,7 +202,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -257,6 +257,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_base.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_base.py index 6031ce0..9d752fe 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_base.py @@ -57,7 +57,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -112,6 +112,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_behavior.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_behavior.py index d0d1919..e95ff25 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_behavior.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_behavior.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_7_0.core_nwb_base import ( NWBDataInterface, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_device.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_device.py index 6d85cf6..f5199c6 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_device.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_device.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_7_0.core_nwb_base import NWBContainer @@ -31,7 +31,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -86,6 +86,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_ecephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_ecephys.py index 13b1cad..e5765f2 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_ecephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_ecephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_7_0.core_nwb_base import ( @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_epoch.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_epoch.py index d114b30..01fe7f1 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_epoch.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_epoch.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_7_0.core_nwb_base import TimeSeriesReferenceVectorData @@ -46,7 +47,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -101,6 +102,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_file.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_file.py index bcaf029..7dd78cf 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_file.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_file.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_7_0.core_nwb_base import ( Images, @@ -60,7 +60,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -115,6 +115,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -251,6 +273,9 @@ class NWBFile(NWBContainer): description="""Experimental intervals, whether that be logically distinct sub-experiments having a particular scientific goal, trials (see trials subgroup) during an experiment, or epochs (see epochs subgroup) deriving from analysis of data.""", ) units: Optional[Units] = Field(None, description="""Data about sorted spike units.""") + specifications: Optional[dict] = Field( + None, description="""Nested dictionary of schema specifications""" + ) class NWBFileStimulus(ConfiguredBaseModel): @@ -359,10 +384,6 @@ class NWBFileGeneral(ConfiguredBaseModel): None, description="""Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc.""", ) - lab_meta_data: Optional[Dict[str, LabMetaData]] = Field( - None, - description="""Place-holder than can be extended so that lab-specific meta-data can be placed in /general.""", - ) devices: Optional[Dict[str, Device]] = Field( None, description="""Description of hardware devices used during experiment, e.g., monitors, ADC boards, microscopes, etc.""", @@ -388,6 +409,10 @@ class NWBFileGeneral(ConfiguredBaseModel): description="""Metadata related to optophysiology.""", json_schema_extra={"linkml_meta": {"any_of": [{"range": "ImagingPlane"}]}}, ) + value: Optional[Dict[str, LabMetaData]] = Field( + None, + description="""Place-holder than can be extended so that lab-specific meta-data can be placed in /general.""", + ) class GeneralSourceScript(ConfiguredBaseModel): @@ -423,12 +448,12 @@ class GeneralExtracellularEphys(ConfiguredBaseModel): } }, ) - electrode_group: Optional[Dict[str, ElectrodeGroup]] = Field( - None, description="""Physical group of electrodes.""" - ) electrodes: Optional[ExtracellularEphysElectrodes] = Field( None, description="""A table of all electrodes (i.e. channels) used for recording.""" ) + value: Optional[Dict[str, ElectrodeGroup]] = Field( + None, description="""Physical group of electrodes.""" + ) class ExtracellularEphysElectrodes(DynamicTable): @@ -584,9 +609,6 @@ class GeneralIntracellularEphys(ConfiguredBaseModel): None, description="""[DEPRECATED] Use IntracellularElectrode.filtering instead. Description of filtering used. Includes filtering type and parameters, frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.""", ) - intracellular_electrode: Optional[Dict[str, IntracellularElectrode]] = Field( - None, description="""An intracellular electrode.""" - ) sweep_table: Optional[SweepTable] = Field( None, description="""[DEPRECATED] Table used to group different PatchClampSeries. SweepTable is being replaced by IntracellularRecordingsTable and SimultaneousRecordingsTable tables. Additional SequentialRecordingsTable, RepetitionsTable and ExperimentalConditions tables provide enhanced support for experiment metadata.""", @@ -611,6 +633,9 @@ class GeneralIntracellularEphys(ConfiguredBaseModel): None, description="""A table for grouping different intracellular recording repetitions together that belong to the same experimental experimental_conditions.""", ) + value: Optional[Dict[str, IntracellularElectrode]] = Field( + None, description="""An intracellular electrode.""" + ) class NWBFileIntervals(ConfiguredBaseModel): @@ -636,7 +661,7 @@ class NWBFileIntervals(ConfiguredBaseModel): invalid_times: Optional[TimeIntervals] = Field( None, description="""Time intervals that should be removed from analysis.""" ) - time_intervals: Optional[Dict[str, TimeIntervals]] = Field( + value: Optional[Dict[str, TimeIntervals]] = Field( None, description="""Optional additional table(s) for describing other experimental time intervals.""", ) diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_icephys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_icephys.py index 937b260..f218898 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_icephys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_icephys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_7_0.core_nwb_base import ( @@ -55,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -110,6 +111,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_image.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_image.py index 331bb3a..9be36c0 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_image.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_image.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_7_0.core_nwb_base import ( Image, @@ -39,7 +39,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -94,6 +94,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_misc.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_misc.py index 8c06050..85d8ba5 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_misc.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_misc.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_7_0.core_nwb_base import TimeSeries, TimeSeriesStartingTime, TimeSeriesSync @@ -48,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -103,6 +104,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_ogen.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_ogen.py index f2f31a2..f878664 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_ogen.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_ogen.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_7_0.core_nwb_base import ( NWBContainer, @@ -38,7 +38,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -93,6 +93,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_ophys.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_ophys.py index c842819..3116a14 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_ophys.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_ophys.py @@ -17,6 +17,7 @@ from pydantic import ( RootModel, ValidationInfo, field_validator, + model_validator, ) from ...core.v2_7_0.core_nwb_base import ( @@ -55,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -110,6 +111,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_retinotopy.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_retinotopy.py index 0cdfaac..a440c91 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_retinotopy.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/core_nwb_retinotopy.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_7_0.core_nwb_base import NWBDataInterface @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/namespace.py index 95df714..1e0d087 100644 --- a/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/core/v2_7_0/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...core.v2_7_0.core_nwb_base import ( Image, @@ -203,7 +203,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -258,6 +258,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/__init__.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/__init__.py index 8b13789..e69de29 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/__init__.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/__init__.py @@ -1 +0,0 @@ - diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_0/hdmf_common_sparse.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_0/hdmf_common_sparse.py index f4811e5..ad32861 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_0/hdmf_common_sparse.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_0/hdmf_common_sparse.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator metamodel_version = "None" @@ -30,7 +30,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -85,6 +85,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_0/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_0/hdmf_common_table.py index 0e5173a..abb7584 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_0/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_0/hdmf_common_table.py @@ -54,7 +54,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -109,6 +109,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_0/namespace.py index b494ff8..d751e29 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_0/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_1_0.hdmf_common_sparse import ( CSRMatrix, @@ -46,7 +46,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -101,6 +101,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_2/hdmf_common_sparse.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_2/hdmf_common_sparse.py index 96a432f..6c16910 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_2/hdmf_common_sparse.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_2/hdmf_common_sparse.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator metamodel_version = "None" @@ -30,7 +30,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -85,6 +85,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_2/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_2/hdmf_common_table.py index f763497..e7aa06c 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_2/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_2/hdmf_common_table.py @@ -54,7 +54,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -109,6 +109,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_2/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_2/namespace.py index a7b07c0..d4ed186 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_2/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_2/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_1_2.hdmf_common_sparse import ( CSRMatrix, @@ -46,7 +46,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -101,6 +101,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_3/hdmf_common_sparse.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_3/hdmf_common_sparse.py index a702232..28e7b7f 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_3/hdmf_common_sparse.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_3/hdmf_common_sparse.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator metamodel_version = "None" @@ -30,7 +30,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -85,6 +85,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_3/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_3/hdmf_common_table.py index b047088..d2b56a3 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_3/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_3/hdmf_common_table.py @@ -54,7 +54,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -109,6 +109,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_3/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_3/namespace.py index d0eb276..89152db 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_3/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_1_3/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_1_3.hdmf_common_sparse import ( CSRMatrix, @@ -46,7 +46,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -101,6 +101,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/hdmf_common_base.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/hdmf_common_base.py index 62ac415..944bae6 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/hdmf_common_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/hdmf_common_base.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator metamodel_version = "None" @@ -29,7 +29,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -51,12 +51,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -67,13 +62,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -85,12 +75,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/hdmf_common_sparse.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/hdmf_common_sparse.py index 2e171cb..30f3337 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/hdmf_common_sparse.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/hdmf_common_sparse.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator metamodel_version = "None" @@ -30,7 +30,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -52,12 +52,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -68,13 +63,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -86,12 +76,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/hdmf_common_table.py index 135e3c6..956138f 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/hdmf_common_table.py @@ -56,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -78,12 +78,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -94,13 +89,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -112,12 +102,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -595,12 +610,19 @@ class DynamicTableMixin(ConfiguredBaseModel): model[key] = to_cast(name=key, description="", value=val) except ValidationError as e: # pragma: no cover raise ValidationError.from_exception_data( - title=f"field {key} cannot be cast to VectorData from {val}", + title="cast_extra_columns", line_errors=[ { - "type": "model_type", + "type": "value_error", "input": val, - } + "loc": ("DynamicTableMixin", "cast_extra_columns"), + "ctx": { + "error": ValueError( + f"field {key} cannot be cast to {to_cast} from {val}" + ) + }, + }, + *e.errors(), ], ) from e return model @@ -663,11 +685,14 @@ class DynamicTableMixin(ConfiguredBaseModel): # should pass if we're supposed to be a VectorData column # don't want to override intention here by insisting that it is # *actually* a VectorData column in case an NDArray has been specified for now + description = cls.model_fields[info.field_name].description + description = description if description is not None else "" + return handler( annotation( val, name=info.field_name, - description=cls.model_fields[info.field_name].description, + description=description, ) ) except Exception: diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/namespace.py index 1bdd7c4..9e7cf0f 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_0/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_2_0.hdmf_common_base import Container, Data from ...hdmf_common.v1_2_0.hdmf_common_sparse import ( @@ -45,7 +45,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -67,12 +67,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -83,13 +78,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -101,12 +91,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_base.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_base.py index c166f2b..5ae420f 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_base.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator metamodel_version = "None" @@ -29,7 +29,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -51,12 +51,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -67,13 +62,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -85,12 +75,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_sparse.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_sparse.py index d68c966..a10c6e8 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_sparse.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_sparse.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_2_1.hdmf_common_base import Container @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -54,12 +54,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -70,13 +65,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -88,12 +78,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_table.py index 1bcfbb6..8e5f858 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/hdmf_common_table.py @@ -56,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -78,12 +78,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -94,13 +89,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -112,12 +102,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -595,12 +610,19 @@ class DynamicTableMixin(ConfiguredBaseModel): model[key] = to_cast(name=key, description="", value=val) except ValidationError as e: # pragma: no cover raise ValidationError.from_exception_data( - title=f"field {key} cannot be cast to VectorData from {val}", + title="cast_extra_columns", line_errors=[ { - "type": "model_type", + "type": "value_error", "input": val, - } + "loc": ("DynamicTableMixin", "cast_extra_columns"), + "ctx": { + "error": ValueError( + f"field {key} cannot be cast to {to_cast} from {val}" + ) + }, + }, + *e.errors(), ], ) from e return model @@ -663,11 +685,14 @@ class DynamicTableMixin(ConfiguredBaseModel): # should pass if we're supposed to be a VectorData column # don't want to override intention here by insisting that it is # *actually* a VectorData column in case an NDArray has been specified for now + description = cls.model_fields[info.field_name].description + description = description if description is not None else "" + return handler( annotation( val, name=info.field_name, - description=cls.model_fields[info.field_name].description, + description=description, ) ) except Exception: diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/namespace.py index 69a3e11..8b71fd0 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_2_1/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_2_1.hdmf_common_base import Container, Data, SimpleMultiContainer from ...hdmf_common.v1_2_1.hdmf_common_sparse import ( @@ -45,7 +45,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -67,12 +67,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -83,13 +78,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -101,12 +91,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_base.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_base.py index ac4722f..055b7d8 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_base.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator metamodel_version = "None" @@ -29,7 +29,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -51,12 +51,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -67,13 +62,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -85,12 +75,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_resources.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_resources.py index d24f662..f1efea0 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_resources.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_resources.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_3_0.hdmf_common_base import Container, Data @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -54,12 +54,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -70,13 +65,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -88,12 +78,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_sparse.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_sparse.py index 542738c..c2546ba 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_sparse.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_sparse.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_3_0.hdmf_common_base import Container @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -54,12 +54,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -70,13 +65,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -88,12 +78,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_table.py index 724cfba..905fd65 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/hdmf_common_table.py @@ -56,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -78,12 +78,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -94,13 +89,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -112,12 +102,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -595,12 +610,19 @@ class DynamicTableMixin(ConfiguredBaseModel): model[key] = to_cast(name=key, description="", value=val) except ValidationError as e: # pragma: no cover raise ValidationError.from_exception_data( - title=f"field {key} cannot be cast to VectorData from {val}", + title="cast_extra_columns", line_errors=[ { - "type": "model_type", + "type": "value_error", "input": val, - } + "loc": ("DynamicTableMixin", "cast_extra_columns"), + "ctx": { + "error": ValueError( + f"field {key} cannot be cast to {to_cast} from {val}" + ) + }, + }, + *e.errors(), ], ) from e return model @@ -663,11 +685,14 @@ class DynamicTableMixin(ConfiguredBaseModel): # should pass if we're supposed to be a VectorData column # don't want to override intention here by insisting that it is # *actually* a VectorData column in case an NDArray has been specified for now + description = cls.model_fields[info.field_name].description + description = description if description is not None else "" + return handler( annotation( val, name=info.field_name, - description=cls.model_fields[info.field_name].description, + description=description, ) ) except Exception: diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/namespace.py index 96107ed..9caab70 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_3_0/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_3_0.hdmf_common_base import Container, Data, SimpleMultiContainer from ...hdmf_common.v1_3_0.hdmf_common_resources import ( @@ -47,7 +47,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -69,12 +69,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -85,13 +80,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -103,12 +93,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_4_0/hdmf_common_base.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_4_0/hdmf_common_base.py index 80ff949..9b140b9 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_4_0/hdmf_common_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_4_0/hdmf_common_base.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator metamodel_version = "None" @@ -29,7 +29,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -51,12 +51,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -67,13 +62,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -85,12 +75,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -156,10 +171,10 @@ class SimpleMultiContainer(Container): {"from_schema": "hdmf-common.base", "tree_root": True} ) + name: str = Field(...) value: Optional[Dict[str, Container]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "Container"}]}} ) - name: str = Field(...) # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_4_0/hdmf_common_sparse.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_4_0/hdmf_common_sparse.py index 2633579..1fd7ffa 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_4_0/hdmf_common_sparse.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_4_0/hdmf_common_sparse.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_4_0.hdmf_common_base import Container @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -54,12 +54,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -70,13 +65,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -88,12 +78,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_4_0/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_4_0/hdmf_common_table.py index 248a227..fc9e813 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_4_0/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_4_0/hdmf_common_table.py @@ -56,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -78,12 +78,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -94,13 +89,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -112,12 +102,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -595,12 +610,19 @@ class DynamicTableMixin(ConfiguredBaseModel): model[key] = to_cast(name=key, description="", value=val) except ValidationError as e: # pragma: no cover raise ValidationError.from_exception_data( - title=f"field {key} cannot be cast to VectorData from {val}", + title="cast_extra_columns", line_errors=[ { - "type": "model_type", + "type": "value_error", "input": val, - } + "loc": ("DynamicTableMixin", "cast_extra_columns"), + "ctx": { + "error": ValueError( + f"field {key} cannot be cast to {to_cast} from {val}" + ) + }, + }, + *e.errors(), ], ) from e return model @@ -663,11 +685,14 @@ class DynamicTableMixin(ConfiguredBaseModel): # should pass if we're supposed to be a VectorData column # don't want to override intention here by insisting that it is # *actually* a VectorData column in case an NDArray has been specified for now + description = cls.model_fields[info.field_name].description + description = description if description is not None else "" + return handler( annotation( val, name=info.field_name, - description=cls.model_fields[info.field_name].description, + description=description, ) ) except Exception: diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_4_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_4_0/namespace.py index 5e9f469..d3da688 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_4_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_4_0/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_4_0.hdmf_common_base import Container, Data, SimpleMultiContainer from ...hdmf_common.v1_4_0.hdmf_common_sparse import CSRMatrix @@ -39,7 +39,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -61,12 +61,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -77,13 +72,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -95,12 +85,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_0/hdmf_common_base.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_0/hdmf_common_base.py index 47eee69..f7c84ac 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_0/hdmf_common_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_0/hdmf_common_base.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator metamodel_version = "None" @@ -29,7 +29,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -84,6 +84,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_0/hdmf_common_sparse.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_0/hdmf_common_sparse.py index e805809..18b46fc 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_0/hdmf_common_sparse.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_0/hdmf_common_sparse.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_5_0.hdmf_common_base import Container @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_0/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_0/hdmf_common_table.py index 00fa3ed..1e8961a 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_0/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_0/hdmf_common_table.py @@ -56,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -111,6 +111,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_0/namespace.py index 6a2b5ed..962b332 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_0/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_5_0.hdmf_common_base import Container, Data, SimpleMultiContainer from ...hdmf_common.v1_5_0.hdmf_common_sparse import CSRMatrix @@ -40,7 +40,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -95,6 +95,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_1/hdmf_common_base.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_1/hdmf_common_base.py index adb45dd..dda9d1b 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_1/hdmf_common_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_1/hdmf_common_base.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator metamodel_version = "None" @@ -29,7 +29,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -51,12 +51,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -67,13 +62,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -85,12 +75,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -156,10 +171,10 @@ class SimpleMultiContainer(Container): {"from_schema": "hdmf-common.base", "tree_root": True} ) + name: str = Field(...) value: Optional[Dict[str, Container]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "Container"}]}} ) - name: str = Field(...) # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_1/hdmf_common_sparse.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_1/hdmf_common_sparse.py index 9731e34..68477d5 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_1/hdmf_common_sparse.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_1/hdmf_common_sparse.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_5_1.hdmf_common_base import Container @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -54,12 +54,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -70,13 +65,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -88,12 +78,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_1/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_1/hdmf_common_table.py index 68e87e2..046be46 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_1/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_1/hdmf_common_table.py @@ -56,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -78,12 +78,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -94,13 +89,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -112,12 +102,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -595,12 +610,19 @@ class DynamicTableMixin(ConfiguredBaseModel): model[key] = to_cast(name=key, description="", value=val) except ValidationError as e: # pragma: no cover raise ValidationError.from_exception_data( - title=f"field {key} cannot be cast to VectorData from {val}", + title="cast_extra_columns", line_errors=[ { - "type": "model_type", + "type": "value_error", "input": val, - } + "loc": ("DynamicTableMixin", "cast_extra_columns"), + "ctx": { + "error": ValueError( + f"field {key} cannot be cast to {to_cast} from {val}" + ) + }, + }, + *e.errors(), ], ) from e return model @@ -663,11 +685,14 @@ class DynamicTableMixin(ConfiguredBaseModel): # should pass if we're supposed to be a VectorData column # don't want to override intention here by insisting that it is # *actually* a VectorData column in case an NDArray has been specified for now + description = cls.model_fields[info.field_name].description + description = description if description is not None else "" + return handler( annotation( val, name=info.field_name, - description=cls.model_fields[info.field_name].description, + description=description, ) ) except Exception: @@ -996,10 +1021,14 @@ class AlignedDynamicTable(AlignedDynamicTableMixin, DynamicTable): {"from_schema": "hdmf-common.table", "tree_root": True} ) + name: str = Field(...) + categories: List[str] = Field( + ..., + description="""The names of the categories in this AlignedDynamicTable. Each category is represented by one DynamicTable stored in the parent group. This attribute should be used to specify an order of categories and the category names must match the names of the corresponding DynamicTable in the group.""", + ) value: Optional[Dict[str, DynamicTable]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "DynamicTable"}]}} ) - name: str = Field(...) colnames: List[str] = Field( ..., description="""The names of the columns in this table. This should be used to specify an order to the columns.""", diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_1/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_1/namespace.py index 83568c9..fc5a53c 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_1/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_5_1/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_5_1.hdmf_common_base import Container, Data, SimpleMultiContainer from ...hdmf_common.v1_5_1.hdmf_common_sparse import CSRMatrix @@ -40,7 +40,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -62,12 +62,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -78,13 +73,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -96,12 +86,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_6_0/hdmf_common_base.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_6_0/hdmf_common_base.py index 0ee3b97..2fc6f4d 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_6_0/hdmf_common_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_6_0/hdmf_common_base.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator metamodel_version = "None" @@ -29,7 +29,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -51,12 +51,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -67,13 +62,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -85,12 +75,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -156,10 +171,10 @@ class SimpleMultiContainer(Container): {"from_schema": "hdmf-common.base", "tree_root": True} ) + name: str = Field(...) value: Optional[Dict[str, Container]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "Container"}]}} ) - name: str = Field(...) # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_6_0/hdmf_common_sparse.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_6_0/hdmf_common_sparse.py index a94523d..f27c4ba 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_6_0/hdmf_common_sparse.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_6_0/hdmf_common_sparse.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_6_0.hdmf_common_base import Container @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -54,12 +54,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -70,13 +65,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -88,12 +78,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_6_0/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_6_0/hdmf_common_table.py index 1fd0a39..c7e473b 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_6_0/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_6_0/hdmf_common_table.py @@ -56,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -78,12 +78,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -94,13 +89,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -112,12 +102,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -595,12 +610,19 @@ class DynamicTableMixin(ConfiguredBaseModel): model[key] = to_cast(name=key, description="", value=val) except ValidationError as e: # pragma: no cover raise ValidationError.from_exception_data( - title=f"field {key} cannot be cast to VectorData from {val}", + title="cast_extra_columns", line_errors=[ { - "type": "model_type", + "type": "value_error", "input": val, - } + "loc": ("DynamicTableMixin", "cast_extra_columns"), + "ctx": { + "error": ValueError( + f"field {key} cannot be cast to {to_cast} from {val}" + ) + }, + }, + *e.errors(), ], ) from e return model @@ -663,11 +685,14 @@ class DynamicTableMixin(ConfiguredBaseModel): # should pass if we're supposed to be a VectorData column # don't want to override intention here by insisting that it is # *actually* a VectorData column in case an NDArray has been specified for now + description = cls.model_fields[info.field_name].description + description = description if description is not None else "" + return handler( annotation( val, name=info.field_name, - description=cls.model_fields[info.field_name].description, + description=description, ) ) except Exception: @@ -996,10 +1021,14 @@ class AlignedDynamicTable(AlignedDynamicTableMixin, DynamicTable): {"from_schema": "hdmf-common.table", "tree_root": True} ) + name: str = Field(...) + categories: List[str] = Field( + ..., + description="""The names of the categories in this AlignedDynamicTable. Each category is represented by one DynamicTable stored in the parent group. This attribute should be used to specify an order of categories and the category names must match the names of the corresponding DynamicTable in the group.""", + ) value: Optional[Dict[str, DynamicTable]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "DynamicTable"}]}} ) - name: str = Field(...) colnames: List[str] = Field( ..., description="""The names of the columns in this table. This should be used to specify an order to the columns.""", diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_6_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_6_0/namespace.py index a8f55a0..f3760c9 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_6_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_6_0/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_6_0.hdmf_common_base import Container, Data, SimpleMultiContainer from ...hdmf_common.v1_6_0.hdmf_common_sparse import CSRMatrix @@ -40,7 +40,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -62,12 +62,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -78,13 +73,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -96,12 +86,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_7_0/hdmf_common_base.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_7_0/hdmf_common_base.py index 08c9fda..9fac65b 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_7_0/hdmf_common_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_7_0/hdmf_common_base.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator metamodel_version = "None" @@ -29,7 +29,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -51,12 +51,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -67,13 +62,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -85,12 +75,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -156,10 +171,10 @@ class SimpleMultiContainer(Container): {"from_schema": "hdmf-common.base", "tree_root": True} ) + name: str = Field(...) value: Optional[Dict[str, Container]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "Container"}]}} ) - name: str = Field(...) # Model rebuild diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_7_0/hdmf_common_sparse.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_7_0/hdmf_common_sparse.py index a6cd2db..648335c 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_7_0/hdmf_common_sparse.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_7_0/hdmf_common_sparse.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_7_0.hdmf_common_base import Container @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -54,12 +54,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -70,13 +65,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -88,12 +78,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_7_0/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_7_0/hdmf_common_table.py index a81bd63..ed16d7f 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_7_0/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_7_0/hdmf_common_table.py @@ -56,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -78,12 +78,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -94,13 +89,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -112,12 +102,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -595,12 +610,19 @@ class DynamicTableMixin(ConfiguredBaseModel): model[key] = to_cast(name=key, description="", value=val) except ValidationError as e: # pragma: no cover raise ValidationError.from_exception_data( - title=f"field {key} cannot be cast to VectorData from {val}", + title="cast_extra_columns", line_errors=[ { - "type": "model_type", + "type": "value_error", "input": val, - } + "loc": ("DynamicTableMixin", "cast_extra_columns"), + "ctx": { + "error": ValueError( + f"field {key} cannot be cast to {to_cast} from {val}" + ) + }, + }, + *e.errors(), ], ) from e return model @@ -663,11 +685,14 @@ class DynamicTableMixin(ConfiguredBaseModel): # should pass if we're supposed to be a VectorData column # don't want to override intention here by insisting that it is # *actually* a VectorData column in case an NDArray has been specified for now + description = cls.model_fields[info.field_name].description + description = description if description is not None else "" + return handler( annotation( val, name=info.field_name, - description=cls.model_fields[info.field_name].description, + description=description, ) ) except Exception: @@ -996,10 +1021,14 @@ class AlignedDynamicTable(AlignedDynamicTableMixin, DynamicTable): {"from_schema": "hdmf-common.table", "tree_root": True} ) + name: str = Field(...) + categories: List[str] = Field( + ..., + description="""The names of the categories in this AlignedDynamicTable. Each category is represented by one DynamicTable stored in the parent group. This attribute should be used to specify an order of categories and the category names must match the names of the corresponding DynamicTable in the group.""", + ) value: Optional[Dict[str, DynamicTable]] = Field( None, json_schema_extra={"linkml_meta": {"any_of": [{"range": "DynamicTable"}]}} ) - name: str = Field(...) colnames: List[str] = Field( ..., description="""The names of the columns in this table. This should be used to specify an order to the columns.""", diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_7_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_7_0/namespace.py index ed5ddbe..d698ce2 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_7_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_7_0/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_7_0.hdmf_common_base import Container, Data, SimpleMultiContainer from ...hdmf_common.v1_7_0.hdmf_common_sparse import CSRMatrix @@ -40,7 +40,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -62,12 +62,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -78,13 +73,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -96,12 +86,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_8_0/hdmf_common_base.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_8_0/hdmf_common_base.py index d58cc4b..65064da 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_8_0/hdmf_common_base.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_8_0/hdmf_common_base.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator metamodel_version = "None" @@ -29,7 +29,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -84,6 +84,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_8_0/hdmf_common_sparse.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_8_0/hdmf_common_sparse.py index 09428fa..e89c2c7 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_8_0/hdmf_common_sparse.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_8_0/hdmf_common_sparse.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_8_0.hdmf_common_base import Container @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_8_0/hdmf_common_table.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_8_0/hdmf_common_table.py index 39b7af0..951260f 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_8_0/hdmf_common_table.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_8_0/hdmf_common_table.py @@ -56,7 +56,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -111,6 +111,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_8_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_8_0/namespace.py index 0e792f9..9d92f34 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_8_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_common/v1_8_0/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_8_0.hdmf_common_base import Container, Data, SimpleMultiContainer from ...hdmf_common.v1_8_0.hdmf_common_sparse import CSRMatrix @@ -40,7 +40,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -95,6 +95,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/hdmf_experimental_experimental.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/hdmf_experimental_experimental.py index e265d0c..0de98e0 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/hdmf_experimental_experimental.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/hdmf_experimental_experimental.py @@ -9,9 +9,9 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator -from ...hdmf_common.v1_5_0.hdmf_common_table import VectorData +from ...hdmf_common.v1_4_0.hdmf_common_table import VectorData metamodel_version = "None" @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -114,7 +136,7 @@ linkml_meta = LinkMLMeta( }, "default_prefix": "hdmf-experimental.experimental/", "id": "hdmf-experimental.experimental", - "imports": ["../../hdmf_common/v1_5_0/namespace", "hdmf-experimental.nwb.language"], + "imports": ["../../hdmf_common/v1_4_0/namespace", "hdmf-experimental.nwb.language"], "name": "hdmf-experimental.experimental", } ) diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/hdmf_experimental_resources.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/hdmf_experimental_resources.py index 867c41e..0548377 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/hdmf_experimental_resources.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/hdmf_experimental_resources.py @@ -9,9 +9,9 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator -from ...hdmf_common.v1_5_0.hdmf_common_base import Container, Data +from ...hdmf_common.v1_4_0.hdmf_common_base import Container, Data metamodel_version = "None" @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} @@ -114,7 +136,7 @@ linkml_meta = LinkMLMeta( }, "default_prefix": "hdmf-experimental.resources/", "id": "hdmf-experimental.resources", - "imports": ["../../hdmf_common/v1_5_0/namespace", "hdmf-experimental.nwb.language"], + "imports": ["../../hdmf_common/v1_4_0/namespace", "hdmf-experimental.nwb.language"], "name": "hdmf-experimental.resources", } ) diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/namespace.py index d133165..7b0dc01 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_1_0/namespace.py @@ -8,12 +8,11 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator -from ...hdmf_common.v1_5_0.hdmf_common_base import Container, Data, SimpleMultiContainer -from ...hdmf_common.v1_5_0.hdmf_common_sparse import CSRMatrix -from ...hdmf_common.v1_5_0.hdmf_common_table import ( - AlignedDynamicTable, +from ...hdmf_common.v1_4_0.hdmf_common_base import Container, Data, SimpleMultiContainer +from ...hdmf_common.v1_4_0.hdmf_common_sparse import CSRMatrix +from ...hdmf_common.v1_4_0.hdmf_common_table import ( DynamicTable, DynamicTableRegion, ElementIdentifiers, @@ -49,7 +48,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -104,6 +103,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_2_0/hdmf_experimental_experimental.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_2_0/hdmf_experimental_experimental.py index c48bb0b..300fef7 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_2_0/hdmf_experimental_experimental.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_2_0/hdmf_experimental_experimental.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_5_1.hdmf_common_table import VectorData @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -54,12 +54,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -70,13 +65,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -88,12 +78,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_2_0/hdmf_experimental_resources.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_2_0/hdmf_experimental_resources.py index 0ef8026..936f1aa 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_2_0/hdmf_experimental_resources.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_2_0/hdmf_experimental_resources.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_5_1.hdmf_common_base import Container, Data @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -54,12 +54,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -70,13 +65,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -88,12 +78,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_2_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_2_0/namespace.py index 7be5bf0..14401ff 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_2_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_2_0/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_5_1.hdmf_common_base import Container, Data, SimpleMultiContainer from ...hdmf_common.v1_5_1.hdmf_common_sparse import CSRMatrix @@ -49,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -71,12 +71,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -87,13 +82,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -105,12 +95,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_3_0/hdmf_experimental_experimental.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_3_0/hdmf_experimental_experimental.py index 894b2ab..19e0e47 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_3_0/hdmf_experimental_experimental.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_3_0/hdmf_experimental_experimental.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_6_0.hdmf_common_table import VectorData @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -54,12 +54,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -70,13 +65,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -88,12 +78,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_3_0/hdmf_experimental_resources.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_3_0/hdmf_experimental_resources.py index 81be11e..6321d50 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_3_0/hdmf_experimental_resources.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_3_0/hdmf_experimental_resources.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_6_0.hdmf_common_base import Container, Data @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -54,12 +54,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -70,13 +65,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -88,12 +78,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_3_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_3_0/namespace.py index fcc1422..9ad600b 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_3_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_3_0/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_6_0.hdmf_common_base import Container, Data, SimpleMultiContainer from ...hdmf_common.v1_6_0.hdmf_common_sparse import CSRMatrix @@ -49,7 +49,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -71,12 +71,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -87,13 +82,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -105,12 +95,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_4_0/hdmf_experimental_experimental.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_4_0/hdmf_experimental_experimental.py index 6c9d22b..f1bd5a5 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_4_0/hdmf_experimental_experimental.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_4_0/hdmf_experimental_experimental.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_7_0.hdmf_common_table import VectorData @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -54,12 +54,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -70,13 +65,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -88,12 +78,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_4_0/hdmf_experimental_resources.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_4_0/hdmf_experimental_resources.py index 8f68ec9..4c3c8c0 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_4_0/hdmf_experimental_resources.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_4_0/hdmf_experimental_resources.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_7_0.hdmf_common_base import Container, Data @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -54,12 +54,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -70,13 +65,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -88,12 +78,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_4_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_4_0/namespace.py index c79550d..651428d 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_4_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_4_0/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_7_0.hdmf_common_base import Container, Data, SimpleMultiContainer from ...hdmf_common.v1_7_0.hdmf_common_sparse import CSRMatrix @@ -50,7 +50,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -72,12 +72,7 @@ class ConfiguredBaseModel(BaseModel): try: return handler(v["value"]) except (IndexError, KeyError, TypeError): - raise ValueError( - f"coerce_value: Could not use the value field of {type(v)} " - f"to construct {cls.__name__}.{info.field_name}, " - f"expected type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + raise e1 @field_validator("*", mode="wrap") @classmethod @@ -88,13 +83,8 @@ class ConfiguredBaseModel(BaseModel): except Exception as e1: try: return handler({"value": v}) - except Exception as e2: - raise ValueError( - f"cast_with_value: Could not cast {type(v)} as value field for " - f"{cls.__name__}.{info.field_name}," - f" expected_type: {cls.model_fields[info.field_name].annotation}\n" - f"inner error: {str(e1)}" - ) from e1 + except Exception: + raise e1 @field_validator("*", mode="before") @classmethod @@ -106,12 +96,37 @@ class ConfiguredBaseModel(BaseModel): 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 return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_5_0/hdmf_experimental_experimental.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_5_0/hdmf_experimental_experimental.py index 368d037..259d724 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_5_0/hdmf_experimental_experimental.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_5_0/hdmf_experimental_experimental.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_8_0.hdmf_common_table import VectorData @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_5_0/hdmf_experimental_resources.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_5_0/hdmf_experimental_resources.py index 8402336..c2267b3 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_5_0/hdmf_experimental_resources.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_5_0/hdmf_experimental_resources.py @@ -9,7 +9,7 @@ from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np from numpydantic import NDArray, Shape -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_8_0.hdmf_common_base import Container, Data @@ -32,7 +32,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -87,6 +87,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_5_0/namespace.py b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_5_0/namespace.py index de810ad..e100b9d 100644 --- a/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_5_0/namespace.py +++ b/nwb_models/src/nwb_models/models/pydantic/hdmf_experimental/v0_5_0/namespace.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, ClassVar, Dict, List, Literal, Optional, Union import numpy as np -from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator +from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator, model_validator from ...hdmf_common.v1_8_0.hdmf_common_base import Container, Data, SimpleMultiContainer from ...hdmf_common.v1_8_0.hdmf_common_sparse import CSRMatrix @@ -50,7 +50,7 @@ class ConfiguredBaseModel(BaseModel): ) object_id: Optional[str] = Field(None, description="Unique UUID for each object") - def __getitem__(self, val: Union[int, slice]) -> Any: + def __getitem__(self, val: Union[int, slice, str]) -> Any: """Try and get a value from value or "data" if we have it""" if hasattr(self, "value") and self.value is not None: return self.value[val] @@ -105,6 +105,28 @@ class ConfiguredBaseModel(BaseModel): pass return v + @model_validator(mode="before") + @classmethod + def gather_extra_to_value(cls, v: Any, handler) -> Any: + """ + For classes that don't allow extra fields and have a value slot, + pack those extra kwargs into ``value`` + """ + if ( + cls.model_config["extra"] == "forbid" + and "value" in cls.model_fields + and isinstance(v, dict) + ): + extras = {key: val for key, val in v.items() if key not in cls.model_fields} + if extras: + for k in extras: + del v[k] + if "value" in v: + v["value"].update(extras) + else: + v["value"] = extras + return v + class LinkMLMeta(RootModel): root: Dict[str, Any] = {} diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_3_0/core.nwb.file.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_3_0/core.nwb.file.yaml index be74485..e998eab 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_3_0/core.nwb.file.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_3_0/core.nwb.file.yaml @@ -219,6 +219,10 @@ classes: range: Units inlined: true inlined_as_list: false + specifications: + name: specifications + description: Nested dictionary of schema specifications + range: dict tree_root: true NWBFile__stimulus: name: NWBFile__stimulus @@ -372,14 +376,6 @@ classes: description: Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc. range: text - lab_meta_data: - name: lab_meta_data - description: Place-holder than can be extended so that lab-specific meta-data - can be placed in /general. - range: LabMetaData - multivalued: true - inlined: true - inlined_as_list: false devices: name: devices description: Description of hardware devices used during experiment, e.g., @@ -424,6 +420,14 @@ classes: inlined_as_list: false any_of: - range: ImagingPlane + value: + name: value + description: Place-holder than can be extended so that lab-specific meta-data + can be placed in /general. + range: LabMetaData + multivalued: true + inlined: true + inlined_as_list: false general__source_script: name: general__source_script description: Script file or link to public source code used to create this NWB @@ -456,19 +460,19 @@ classes: range: string required: true equals_string: extracellular_ephys - electrode_group: - name: electrode_group - description: Physical group of electrodes. - range: ElectrodeGroup - multivalued: true - inlined: true - inlined_as_list: false electrodes: name: electrodes description: A table of all electrodes (i.e. channels) used for recording. range: extracellular_ephys__electrodes inlined: true inlined_as_list: true + value: + name: value + description: Physical group of electrodes. + range: ElectrodeGroup + multivalued: true + inlined: true + inlined_as_list: false extracellular_ephys__electrodes: name: extracellular_ephys__electrodes description: A table of all electrodes (i.e. channels) used for recording. @@ -610,19 +614,19 @@ classes: frequency fall-off, etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries. range: text - intracellular_electrode: - name: intracellular_electrode - description: An intracellular electrode. - range: IntracellularElectrode - multivalued: true - inlined: true - inlined_as_list: false sweep_table: name: sweep_table description: The table which groups different PatchClampSeries together. range: SweepTable inlined: true inlined_as_list: false + value: + name: value + description: An intracellular electrode. + range: IntracellularElectrode + multivalued: true + inlined: true + inlined_as_list: false NWBFile__intervals: name: NWBFile__intervals description: Experimental intervals, whether that be logically distinct sub-experiments @@ -655,8 +659,8 @@ classes: range: TimeIntervals inlined: true inlined_as_list: false - time_intervals: - name: time_intervals + value: + name: value description: Optional additional table(s) for describing other experimental time intervals. range: TimeIntervals diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_3_0/core.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_3_0/core.nwb.language.yaml index a921651..e36f824 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_3_0/core.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_3_0/core.nwb.language.yaml @@ -88,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_4_0/core.nwb.file.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_4_0/core.nwb.file.yaml index f11e44b..5157c95 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_4_0/core.nwb.file.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_4_0/core.nwb.file.yaml @@ -219,6 +219,10 @@ classes: range: Units inlined: true inlined_as_list: false + specifications: + name: specifications + description: Nested dictionary of schema specifications + range: dict tree_root: true NWBFile__stimulus: name: NWBFile__stimulus @@ -372,14 +376,6 @@ classes: description: Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc. range: text - lab_meta_data: - name: lab_meta_data - description: Place-holder than can be extended so that lab-specific meta-data - can be placed in /general. - range: LabMetaData - multivalued: true - inlined: true - inlined_as_list: false devices: name: devices description: Description of hardware devices used during experiment, e.g., @@ -424,6 +420,14 @@ classes: inlined_as_list: false any_of: - range: ImagingPlane + value: + name: value + description: Place-holder than can be extended so that lab-specific meta-data + can be placed in /general. + range: LabMetaData + multivalued: true + inlined: true + inlined_as_list: false general__source_script: name: general__source_script description: Script file or link to public source code used to create this NWB @@ -456,19 +460,19 @@ classes: range: string required: true equals_string: extracellular_ephys - electrode_group: - name: electrode_group - description: Physical group of electrodes. - range: ElectrodeGroup - multivalued: true - inlined: true - inlined_as_list: false electrodes: name: electrodes description: A table of all electrodes (i.e. channels) used for recording. range: extracellular_ephys__electrodes inlined: true inlined_as_list: true + value: + name: value + description: Physical group of electrodes. + range: ElectrodeGroup + multivalued: true + inlined: true + inlined_as_list: false extracellular_ephys__electrodes: name: extracellular_ephys__electrodes description: A table of all electrodes (i.e. channels) used for recording. @@ -611,13 +615,6 @@ classes: etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.' range: text - intracellular_electrode: - name: intracellular_electrode - description: An intracellular electrode. - range: IntracellularElectrode - multivalued: true - inlined: true - inlined_as_list: false sweep_table: name: sweep_table description: '[DEPRECATED] Table used to group different PatchClampSeries. @@ -677,6 +674,13 @@ classes: range: ExperimentalConditionsTable inlined: true inlined_as_list: false + value: + name: value + description: An intracellular electrode. + range: IntracellularElectrode + multivalued: true + inlined: true + inlined_as_list: false NWBFile__intervals: name: NWBFile__intervals description: Experimental intervals, whether that be logically distinct sub-experiments @@ -709,8 +713,8 @@ classes: range: TimeIntervals inlined: true inlined_as_list: false - time_intervals: - name: time_intervals + value: + name: value description: Optional additional table(s) for describing other experimental time intervals. range: TimeIntervals diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_4_0/core.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_4_0/core.nwb.language.yaml index a921651..e36f824 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_4_0/core.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_4_0/core.nwb.language.yaml @@ -88,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_5_0/core.nwb.file.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_5_0/core.nwb.file.yaml index e42c8b3..82f7932 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_5_0/core.nwb.file.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_5_0/core.nwb.file.yaml @@ -219,6 +219,10 @@ classes: range: Units inlined: true inlined_as_list: false + specifications: + name: specifications + description: Nested dictionary of schema specifications + range: dict tree_root: true NWBFile__stimulus: name: NWBFile__stimulus @@ -373,14 +377,6 @@ classes: description: Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc. range: text - lab_meta_data: - name: lab_meta_data - description: Place-holder than can be extended so that lab-specific meta-data - can be placed in /general. - range: LabMetaData - multivalued: true - inlined: true - inlined_as_list: false devices: name: devices description: Description of hardware devices used during experiment, e.g., @@ -425,6 +421,14 @@ classes: inlined_as_list: false any_of: - range: ImagingPlane + value: + name: value + description: Place-holder than can be extended so that lab-specific meta-data + can be placed in /general. + range: LabMetaData + multivalued: true + inlined: true + inlined_as_list: false general__source_script: name: general__source_script description: Script file or link to public source code used to create this NWB @@ -457,19 +461,19 @@ classes: range: string required: true equals_string: extracellular_ephys - electrode_group: - name: electrode_group - description: Physical group of electrodes. - range: ElectrodeGroup - multivalued: true - inlined: true - inlined_as_list: false electrodes: name: electrodes description: A table of all electrodes (i.e. channels) used for recording. range: extracellular_ephys__electrodes inlined: true inlined_as_list: true + value: + name: value + description: Physical group of electrodes. + range: ElectrodeGroup + multivalued: true + inlined: true + inlined_as_list: false extracellular_ephys__electrodes: name: extracellular_ephys__electrodes description: A table of all electrodes (i.e. channels) used for recording. @@ -614,13 +618,6 @@ classes: etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.' range: text - intracellular_electrode: - name: intracellular_electrode - description: An intracellular electrode. - range: IntracellularElectrode - multivalued: true - inlined: true - inlined_as_list: false sweep_table: name: sweep_table description: '[DEPRECATED] Table used to group different PatchClampSeries. @@ -680,6 +677,13 @@ classes: range: ExperimentalConditionsTable inlined: true inlined_as_list: false + value: + name: value + description: An intracellular electrode. + range: IntracellularElectrode + multivalued: true + inlined: true + inlined_as_list: false NWBFile__intervals: name: NWBFile__intervals description: Experimental intervals, whether that be logically distinct sub-experiments @@ -712,8 +716,8 @@ classes: range: TimeIntervals inlined: true inlined_as_list: false - time_intervals: - name: time_intervals + value: + name: value description: Optional additional table(s) for describing other experimental time intervals. range: TimeIntervals diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_5_0/core.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_5_0/core.nwb.language.yaml index a921651..e36f824 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_5_0/core.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_5_0/core.nwb.language.yaml @@ -88,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_6_0_alpha/core.nwb.file.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_6_0_alpha/core.nwb.file.yaml index 1a0cf34..85b1f65 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_6_0_alpha/core.nwb.file.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_6_0_alpha/core.nwb.file.yaml @@ -219,6 +219,10 @@ classes: range: Units inlined: true inlined_as_list: false + specifications: + name: specifications + description: Nested dictionary of schema specifications + range: dict tree_root: true NWBFile__stimulus: name: NWBFile__stimulus @@ -373,14 +377,6 @@ classes: description: Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc. range: text - lab_meta_data: - name: lab_meta_data - description: Place-holder than can be extended so that lab-specific meta-data - can be placed in /general. - range: LabMetaData - multivalued: true - inlined: true - inlined_as_list: false devices: name: devices description: Description of hardware devices used during experiment, e.g., @@ -425,6 +421,14 @@ classes: inlined_as_list: false any_of: - range: ImagingPlane + value: + name: value + description: Place-holder than can be extended so that lab-specific meta-data + can be placed in /general. + range: LabMetaData + multivalued: true + inlined: true + inlined_as_list: false general__source_script: name: general__source_script description: Script file or link to public source code used to create this NWB @@ -457,19 +461,19 @@ classes: range: string required: true equals_string: extracellular_ephys - electrode_group: - name: electrode_group - description: Physical group of electrodes. - range: ElectrodeGroup - multivalued: true - inlined: true - inlined_as_list: false electrodes: name: electrodes description: A table of all electrodes (i.e. channels) used for recording. range: extracellular_ephys__electrodes inlined: true inlined_as_list: true + value: + name: value + description: Physical group of electrodes. + range: ElectrodeGroup + multivalued: true + inlined: true + inlined_as_list: false extracellular_ephys__electrodes: name: extracellular_ephys__electrodes description: A table of all electrodes (i.e. channels) used for recording. @@ -614,13 +618,6 @@ classes: etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.' range: text - intracellular_electrode: - name: intracellular_electrode - description: An intracellular electrode. - range: IntracellularElectrode - multivalued: true - inlined: true - inlined_as_list: false sweep_table: name: sweep_table description: '[DEPRECATED] Table used to group different PatchClampSeries. @@ -680,6 +677,13 @@ classes: range: ExperimentalConditionsTable inlined: true inlined_as_list: false + value: + name: value + description: An intracellular electrode. + range: IntracellularElectrode + multivalued: true + inlined: true + inlined_as_list: false NWBFile__intervals: name: NWBFile__intervals description: Experimental intervals, whether that be logically distinct sub-experiments @@ -712,8 +716,8 @@ classes: range: TimeIntervals inlined: true inlined_as_list: false - time_intervals: - name: time_intervals + value: + name: value description: Optional additional table(s) for describing other experimental time intervals. range: TimeIntervals diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_6_0_alpha/core.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_6_0_alpha/core.nwb.language.yaml index a921651..e36f824 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_6_0_alpha/core.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_6_0_alpha/core.nwb.language.yaml @@ -88,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_7_0/core.nwb.file.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_7_0/core.nwb.file.yaml index fcd10dc..35f877e 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_7_0/core.nwb.file.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_7_0/core.nwb.file.yaml @@ -219,6 +219,10 @@ classes: range: Units inlined: true inlined_as_list: false + specifications: + name: specifications + description: Nested dictionary of schema specifications + range: dict tree_root: true NWBFile__stimulus: name: NWBFile__stimulus @@ -375,14 +379,6 @@ classes: description: Information about virus(es) used in experiments, including virus ID, source, date made, injection location, volume, etc. range: text - lab_meta_data: - name: lab_meta_data - description: Place-holder than can be extended so that lab-specific meta-data - can be placed in /general. - range: LabMetaData - multivalued: true - inlined: true - inlined_as_list: false devices: name: devices description: Description of hardware devices used during experiment, e.g., @@ -427,6 +423,14 @@ classes: inlined_as_list: false any_of: - range: ImagingPlane + value: + name: value + description: Place-holder than can be extended so that lab-specific meta-data + can be placed in /general. + range: LabMetaData + multivalued: true + inlined: true + inlined_as_list: false general__source_script: name: general__source_script description: Script file or link to public source code used to create this NWB @@ -459,19 +463,19 @@ classes: range: string required: true equals_string: extracellular_ephys - electrode_group: - name: electrode_group - description: Physical group of electrodes. - range: ElectrodeGroup - multivalued: true - inlined: true - inlined_as_list: false electrodes: name: electrodes description: A table of all electrodes (i.e. channels) used for recording. range: extracellular_ephys__electrodes inlined: true inlined_as_list: true + value: + name: value + description: Physical group of electrodes. + range: ElectrodeGroup + multivalued: true + inlined: true + inlined_as_list: false extracellular_ephys__electrodes: name: extracellular_ephys__electrodes description: A table of all electrodes (i.e. channels) used for recording. @@ -616,13 +620,6 @@ classes: etc. If this changes between TimeSeries, filter description should be stored as a text attribute for each TimeSeries.' range: text - intracellular_electrode: - name: intracellular_electrode - description: An intracellular electrode. - range: IntracellularElectrode - multivalued: true - inlined: true - inlined_as_list: false sweep_table: name: sweep_table description: '[DEPRECATED] Table used to group different PatchClampSeries. @@ -682,6 +679,13 @@ classes: range: ExperimentalConditionsTable inlined: true inlined_as_list: false + value: + name: value + description: An intracellular electrode. + range: IntracellularElectrode + multivalued: true + inlined: true + inlined_as_list: false NWBFile__intervals: name: NWBFile__intervals description: Experimental intervals, whether that be logically distinct sub-experiments @@ -714,8 +718,8 @@ classes: range: TimeIntervals inlined: true inlined_as_list: false - time_intervals: - name: time_intervals + value: + name: value description: Optional additional table(s) for describing other experimental time intervals. range: TimeIntervals diff --git a/nwb_models/src/nwb_models/schema/linkml/core/v2_7_0/core.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/core/v2_7_0/core.nwb.language.yaml index a921651..e36f824 100644 --- a/nwb_models/src/nwb_models/schema/linkml/core/v2_7_0/core.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/core/v2_7_0/core.nwb.language.yaml @@ -88,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_4_0/hdmf-common.base.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_4_0/hdmf-common.base.yaml index 6ba8106..5f37d89 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_4_0/hdmf-common.base.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_4_0/hdmf-common.base.yaml @@ -38,10 +38,16 @@ classes: description: A simple Container for holding onto multiple containers. is_a: Container attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: Container + name: + name: name + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: Container tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_4_0/hdmf-common.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_4_0/hdmf-common.nwb.language.yaml index 9b6bc55..6b8ce10 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_4_0/hdmf-common.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_4_0/hdmf-common.nwb.language.yaml @@ -88,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_5_0/hdmf-common.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_5_0/hdmf-common.nwb.language.yaml index 1842589..6b8ce10 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_5_0/hdmf-common.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_5_0/hdmf-common.nwb.language.yaml @@ -5,7 +5,7 @@ annotations: value: 'False' namespace: tag: namespace - value: core + value: hdmf-experimental description: Adapter objects to mimic the behavior of elements in the nwb-schema-language id: nwb.language imports: @@ -88,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_5_1/hdmf-common.base.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_5_1/hdmf-common.base.yaml index 4fd80e6..4173cbc 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_5_1/hdmf-common.base.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_5_1/hdmf-common.base.yaml @@ -38,10 +38,16 @@ classes: description: A simple Container for holding onto multiple containers. is_a: Container attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: Container + name: + name: name + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: Container tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_5_1/hdmf-common.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_5_1/hdmf-common.nwb.language.yaml index 9b6bc55..6b8ce10 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_5_1/hdmf-common.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_5_1/hdmf-common.nwb.language.yaml @@ -88,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_5_1/hdmf-common.table.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_5_1/hdmf-common.table.yaml index 513a5d4..44a3b23 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_5_1/hdmf-common.table.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_5_1/hdmf-common.table.yaml @@ -189,10 +189,26 @@ classes: by a separate DynamicTable stored within the group. is_a: DynamicTable attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: DynamicTable + name: + name: name + identifier: true + range: string + required: true + categories: + name: categories + description: The names of the categories in this AlignedDynamicTable. Each + category is represented by one DynamicTable stored in the parent group. + This attribute should be used to specify an order of categories and the + category names must match the names of the corresponding DynamicTable in + the group. + range: text + required: true + multivalued: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: DynamicTable tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_6_0/hdmf-common.base.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_6_0/hdmf-common.base.yaml index beb539c..5b2a0ef 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_6_0/hdmf-common.base.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_6_0/hdmf-common.base.yaml @@ -38,10 +38,16 @@ classes: description: A simple Container for holding onto multiple containers. is_a: Container attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: Container + name: + name: name + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: Container tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_6_0/hdmf-common.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_6_0/hdmf-common.nwb.language.yaml index 9b6bc55..6b8ce10 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_6_0/hdmf-common.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_6_0/hdmf-common.nwb.language.yaml @@ -88,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_6_0/hdmf-common.table.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_6_0/hdmf-common.table.yaml index 5613666..d53e72f 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_6_0/hdmf-common.table.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_6_0/hdmf-common.table.yaml @@ -189,10 +189,26 @@ classes: by a separate DynamicTable stored within the group. is_a: DynamicTable attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: DynamicTable + name: + name: name + identifier: true + range: string + required: true + categories: + name: categories + description: The names of the categories in this AlignedDynamicTable. Each + category is represented by one DynamicTable stored in the parent group. + This attribute should be used to specify an order of categories and the + category names must match the names of the corresponding DynamicTable in + the group. + range: text + required: true + multivalued: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: DynamicTable tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_7_0/hdmf-common.base.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_7_0/hdmf-common.base.yaml index f65f22b..652ffad 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_7_0/hdmf-common.base.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_7_0/hdmf-common.base.yaml @@ -38,10 +38,16 @@ classes: description: A simple Container for holding onto multiple containers. is_a: Container attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: Container + name: + name: name + identifier: true + range: string + required: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: Container tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_7_0/hdmf-common.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_7_0/hdmf-common.nwb.language.yaml index 9b6bc55..6b8ce10 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_7_0/hdmf-common.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_7_0/hdmf-common.nwb.language.yaml @@ -88,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_7_0/hdmf-common.table.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_7_0/hdmf-common.table.yaml index 36dd411..274356e 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_7_0/hdmf-common.table.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_7_0/hdmf-common.table.yaml @@ -189,10 +189,26 @@ classes: by a separate DynamicTable stored within the group. is_a: DynamicTable attributes: - - name: value - multivalued: true - inlined: true - inlined_as_list: false - any_of: - - range: DynamicTable + name: + name: name + identifier: true + range: string + required: true + categories: + name: categories + description: The names of the categories in this AlignedDynamicTable. Each + category is represented by one DynamicTable stored in the parent group. + This attribute should be used to specify an order of categories and the + category names must match the names of the corresponding DynamicTable in + the group. + range: text + required: true + multivalued: true + value: + name: value + multivalued: true + inlined: true + inlined_as_list: false + any_of: + - range: DynamicTable tree_root: true diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_8_0/hdmf-common.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_8_0/hdmf-common.nwb.language.yaml index 1842589..6b8ce10 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_8_0/hdmf-common.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_common/v1_8_0/hdmf-common.nwb.language.yaml @@ -5,7 +5,7 @@ annotations: value: 'False' namespace: tag: namespace - value: core + value: hdmf-experimental description: Adapter objects to mimic the behavior of elements in the nwb-schema-language id: nwb.language imports: @@ -88,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.experimental.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.experimental.yaml index b0b87d5..2a10ba2 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.experimental.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.experimental.yaml @@ -9,7 +9,7 @@ annotations: id: hdmf-experimental.experimental version: 0.1.0 imports: -- ../../hdmf_common/v1_5_0/namespace +- ../../hdmf_common/v1_4_0/namespace - hdmf-experimental.nwb.language default_prefix: hdmf-experimental.experimental/ classes: diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.nwb.language.yaml index 650c484..dcf2549 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.nwb.language.yaml @@ -5,7 +5,7 @@ annotations: value: 'False' namespace: tag: namespace - value: core + value: hdmf-experimental description: Adapter objects to mimic the behavior of elements in the nwb-schema-language id: nwb.language imports: @@ -88,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.resources.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.resources.yaml index 9aeb7d0..a8d955d 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.resources.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_1_0/hdmf-experimental.resources.yaml @@ -9,7 +9,7 @@ annotations: id: hdmf-experimental.resources version: 0.1.0 imports: -- ../../hdmf_common/v1_5_0/namespace +- ../../hdmf_common/v1_4_0/namespace - hdmf-experimental.nwb.language default_prefix: hdmf-experimental.resources/ classes: diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_2_0/hdmf-experimental.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_2_0/hdmf-experimental.nwb.language.yaml index b487163..dcf2549 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_2_0/hdmf-experimental.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_2_0/hdmf-experimental.nwb.language.yaml @@ -88,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_3_0/hdmf-experimental.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_3_0/hdmf-experimental.nwb.language.yaml index b487163..dcf2549 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_3_0/hdmf-experimental.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_3_0/hdmf-experimental.nwb.language.yaml @@ -88,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_4_0/hdmf-experimental.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_4_0/hdmf-experimental.nwb.language.yaml index b487163..dcf2549 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_4_0/hdmf-experimental.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_4_0/hdmf-experimental.nwb.language.yaml @@ -88,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_5_0/hdmf-experimental.nwb.language.yaml b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_5_0/hdmf-experimental.nwb.language.yaml index 650c484..dcf2549 100644 --- a/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_5_0/hdmf-experimental.nwb.language.yaml +++ b/nwb_models/src/nwb_models/schema/linkml/hdmf_experimental/v0_5_0/hdmf-experimental.nwb.language.yaml @@ -5,7 +5,7 @@ annotations: value: 'False' namespace: tag: namespace - value: core + value: hdmf-experimental description: Adapter objects to mimic the behavior of elements in the nwb-schema-language id: nwb.language imports: @@ -88,6 +88,9 @@ types: isodatetime: name: isodatetime typeof: datetime + dict: + name: dict + repr: dict classes: AnyType: name: AnyType diff --git a/scripts/generate_core.py b/scripts/generate_core.py index 413b85b..53a7574 100644 --- a/scripts/generate_core.py +++ b/scripts/generate_core.py @@ -19,6 +19,7 @@ from nwb_linkml.providers import LinkMLProvider, PydanticProvider from nwb_linkml.providers.git import NWB_CORE_REPO, HDMF_COMMON_REPO, GitRepo from nwb_linkml.io import schema as io + def make_tmp_dir(clear: bool = False) -> Path: # use a directory underneath this one as the temporary directory rather than # the default hidden one