Description
When a subclass overrides a field that has range metadata (used by LinkedBaseModel.__init__ to handle IRI strings), the range information from the parent's Field() is lost. This causes:
- IRI strings passed to the field raise
ValidationError: value is not a valid dict - Object refs don't get their IRI extracted to
__iris__
Root cause
In LinkedBaseModel.__init__, IRI handling checks field.field_info.extra for a "range" key. When a subclass overrides a field with a plain annotation (e.g. tool: list[Child] | None = None), pydantic v1 creates a new FieldInfo without the parent's extra kwargs, so "range" is absent.
Minimal reproduction
frompydantic.v1importFieldfromoold.model.v1importLinkedBaseModelfromoold.backend.document_storeimportSimpleDictDocumentStorefromoold.backend.interfaceimportset_backend, SetBackendParambackend=SimpleDictDocumentStore()
set_backend(SetBackendParam(iri="Item", backend=backend))
classParent(LinkedBaseModel):
classConfig:
schema_extra= {"uuid": "00000000-0000-0000-0000-000000000001"}
type: list[str] |None= ["Category:OSW00000000000000000000000000000001"]
id: str="Item:OSW00000000000000000000000000000001"name: str="parent"classProcessBase(LinkedBaseModel):
classConfig:
schema_extra= {"uuid": "00000000-0000-0000-0000-000000000010"}
tool: list[Parent] |None=Field(None, range="Category:Parent")
classGoodSubclass(ProcessBase):
"""Inherits tool with range metadata — works"""classConfig:
schema_extra= {"uuid": "00000000-0000-0000-0000-000000000011"}
classBadSubclass(ProcessBase):
"""Overrides tool, loses range metadata — breaks"""classConfig:
schema_extra= {"uuid": "00000000-0000-0000-0000-000000000012"}
tool: list[Parent] |None=Noneparent=Parent(name="test_parent")
parent_iri=parent.get_iri()
backend._store[parent_iri] =parent.dict()
# GoodSubclass: IRI resolved correctlygood=GoodSubclass(tool=[parent_iri])
print(good.__iris__.get("tool")) # ['Item:OSW...'] ✓print(good.tool[0].name) # 'test_parent' ✓# BadSubclass: ValidationErrorbad=BadSubclass(tool=[parent_iri]) # ✗ raises ValidationErrorOutput:
['Item:OSW00000000000000000000000000000001']
test_parent
ValidationError: 1 validation error for BadSubclass
tool -> 0
value is not a valid dict (type=type_error.dict)
Workaround
Re-declare the field with explicit range in the subclass:
classFixedSubclass(ProcessBase):
tool: list[Parent] |None=Field(None, range="Category:Parent")
Suggestion
LinkedBaseModel.__init__ could fall back to checking parent class field extras when range is not found in the overriding field. Alternatively, the metaclass could propagate range metadata to subclass field overrides automatically.
Environment
- oold: 0.16.2
- pydantic: v1 compat mode (pydantic 2.x with
pydantic.v1) - Python: 3.11
Description
When a subclass overrides a field that has
rangemetadata (used byLinkedBaseModel.__init__to handle IRI strings), therangeinformation from the parent'sField()is lost. This causes:ValidationError: value is not a valid dict__iris__Root cause
In
LinkedBaseModel.__init__, IRI handling checksfield.field_info.extrafor a"range"key. When a subclass overrides a field with a plain annotation (e.g.tool: list[Child] | None = None), pydantic v1 creates a newFieldInfowithout the parent's extra kwargs, so"range"is absent.Minimal reproduction
Output:
Workaround
Re-declare the field with explicit
rangein the subclass:Suggestion
LinkedBaseModel.__init__could fall back to checking parent class field extras whenrangeis not found in the overriding field. Alternatively, the metaclass could propagaterangemetadata to subclass field overrides automatically.Environment
pydantic.v1)