_bind_property_to raises TypeError when the reference field is inherited from a base class
@plamen-neykov is already working on this.
Since Sep 16, 2026.
Assessment
This issue has not been assessed yet.
Description
Bug Report
_bind_property_to raises TypeError when the reference field is inherited from a base class
Steps to Reproduce
- Clone the repository and set up the development environment:
git clone https://github.com/finos/rune-python-runtime
cd rune-python-runtime
./dev_clean_setup.sh
source .pydevenv/bin/activate
- Run the following self-contained script (no external dependencies beyond the runtime itself):
import json
from typing_extensions import Annotated
from pydantic import Field
from rune.runtime.base_data_class import BaseDataClass
# A keyed type — instances can be registered under an external key
class Location(BaseDataClass):
_ALLOWED_METADATA = {'@key:external'}
name: str = Field(..., description='location name')
# Base class declares the reference field
class EntityBase(BaseDataClass):
location: Annotated[
Location,
Location.serializer(),
Location.validator(allowed_meta=('@ref:external',))
] = Field(None, description='reference to location')
_KEY_REF_CONSTRAINTS = {'location': {'@ref:external'}}
# Subclass inherits 'location' — it is NOT in Entity.__annotations__
class Entity(EntityBase):
label: str = Field(..., description='entity label')
# Container holds both the key targets and the referencing objects
class Container(BaseDataClass):
locations: list[Location] = Field(..., description='locations')
entities: list[Entity] = Field(..., description='entities')
data = json.dumps({
"locations": [
{"@key:external": "loc1", "name": "New York"}
],
"entities": [
{"label": "Desk A", "location": {"@ref:external": "loc1"}}
]
})
c = Container.rune_deserialize(data, validate_model=False)
Expected Result
Deserialization completes and c.entities[0].location is a resolved Location instance.
Actual Result
resolve_references raises TypeError:
File ".../rune/runtime/base_data_class.py:343: in resolve_references
self._bind_property_to(prop_nm, ref)
File ".../rune/runtime/metadata.py:304: in _bind_property_to
or isinstance(ref.target, allowed_type)):
TypeError: isinstance() arg 2 must be a type, a tuple of types, or a union
Root Cause
_bind_property_to in metadata.py looks up the field's type annotation using self.__class__.__annotations__:
field_type = self.__class__.__annotations__.get(property_nm) # line 301
allowed_type = _get_basic_type(field_type)
if not (isinstance(allowed_type, str)
or isinstance(ref.target, allowed_type)): # line 303-304
Python's __annotations__ only contains annotations declared directly on the class — not those inherited from a base class. When property_nm is defined on a parent class, .get() returns None. _get_basic_type(None) also returns None, and isinstance(ref.target, None) raises TypeError.
Environment
rune-python-runtimeversion: currentmain- Python: 3.12+
- OS: macOS Darwin 25.6.0
Additional Context
Recommended fix — guard against None before the isinstance call. A missing annotation means the field type cannot be determined (it is inherited), so the type check should be skipped:
field_type = self.__class__.__annotations__.get(property_nm)
allowed_type = _get_basic_type(field_type)
if allowed_type is not None and not (isinstance(allowed_type, str)
or isinstance(ref.target, allowed_type)):
raise ValueError("Can't set reference. Incompatible types: "
f"expected {allowed_type}, "
f"got {ref.target.__class__}")
A more complete fix would replace self.__class__.__annotations__ with typing.get_type_hints(self.__class__), which traverses the MRO and resolves forward references. However, get_type_hints() can raise when forward references cannot be resolved in the current scope, so the None-guard is the safer immediate change.
- Dominant language
- Python
- Stars
- 0
- Forks
- 3
- Avg merge
- 5m
- Merged PRs (30d)
- 1
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from finos/rune-python-runtime
-
Difficulty 3/5 1-2 days Newbie friendliness 62/100
finos/rune-python-runtime#27 ·
-
Difficulty 5/5 Over a week Newbie friendliness 25/100
finos/rune-python-runtime#16 ·
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
finos/rune-python-runtime#15 · 1 comment ·
All issues in finos/rune-python-runtime
Similar issues
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
use-agent-os/agent-os#3314 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
BasedHardware/omi#15662 · 1 comment ·
-
documentation help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
AiursoftWeb/AnduinOS-2#19 ·