Skip to content

Commit

Permalink
Support nested references
Browse files Browse the repository at this point in the history
  • Loading branch information
nulinspiratie committed Dec 11, 2024
1 parent 107f3ab commit 7850564
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 1 deletion.
8 changes: 7 additions & 1 deletion quam/core/quam_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,13 @@ def set_at_reference(self, attr: str, value: Any):
)

parent_obj = self._get_referenced_value(parent_reference)
setattr(parent_obj, ref_attr, value)
raw_referenced_value = parent_obj.get_unreferenced_value(ref_attr)
if string_reference.is_reference(raw_referenced_value) and isinstance(
parent_obj, QuamBase
):
parent_obj.set_at_reference(ref_attr, value)
else:
setattr(parent_obj, ref_attr, value)


# Type annotation for QuamRoot, can be replaced by typing.Self from Python 3.11
Expand Down
79 changes: 79 additions & 0 deletions tests/quam_base/test_set_at_reference.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest
from quam.core.quam_classes import QuamBase, QuamRoot, quam_dataclass
from typing import Optional


@quam_dataclass
Expand Down Expand Up @@ -76,3 +77,81 @@ def test_set_at_absolute_reference_invalid():

with pytest.raises(AttributeError):
root.set_at_reference("abs_ref", 456)


@quam_dataclass
class DoubleChildQuam(ChildQuam):
value: int = 0
child: Optional[ChildQuam] = None

def test_set_double_reference():
"""Test setting a value through a double reference"""
double_child = DoubleChildQuam(child=ChildQuam(value=42), value="#./child/value")
parent = ParentQuam(child=double_child, ref_value="#./child/value")

assert parent.ref_value == 42
assert parent.get_unreferenced_value("ref_value") == "#./child/value"
assert parent.child.get_unreferenced_value("value") == "#./child/value"

# Set value through double reference
parent.set_at_reference("ref_value", 789)

# Check that the value was set correctly in the nested child
assert double_child.child.value == 789
assert double_child.value == 789
assert parent.ref_value == 789

# Reference string should remain unchanged
assert parent.get_unreferenced_value("ref_value") == "#./child/value"
assert double_child.get_unreferenced_value("value") == "#./child/value"


def test_set_nonexistent_double_reference():
"""Test setting a value where the double reference does not exist"""
double_child = DoubleChildQuam(child=ChildQuam(value=42), value="#./child/nonexistent")
parent = ParentQuam(child=double_child, ref_value="#./child/nonexistent")

with pytest.raises(AttributeError):
parent.set_at_reference("ref_value", 789)


def test_set_double_reference_to_nonexistent_item():
"""Test setting a value through a double reference to a nonexistent item"""
double_child = DoubleChildQuam(child=ChildQuam(value=42), value="#./nonexistent/value")
parent = ParentQuam(child=double_child, ref_value="#./nonexistent/value")

with pytest.raises(AttributeError):
parent.set_at_reference("ref_value", 789)


def test_set_double_reference_with_invalid_reference():
"""Test setting a value through a double reference with an invalid reference"""
double_child = DoubleChildQuam(child=ChildQuam(value=42), value="#./child/invalid")
parent = ParentQuam(child=double_child, ref_value="#./child/invalid")

with pytest.raises(AttributeError):
parent.set_at_reference("ref_value", 789)

def test_set_triple_reference():
"""Test setting a value through a triple reference"""
triple_child = DoubleChildQuam(child=DoubleChildQuam(child=ChildQuam(value=42), value="#./child/value"), value="#./child/value")
parent = ParentQuam(child=triple_child, ref_value="#./child/value")

assert parent.ref_value == 42
assert parent.get_unreferenced_value("ref_value") == "#./child/value"
assert parent.child.get_unreferenced_value("value") == "#./child/value"
assert parent.child.child.get_unreferenced_value("value") == "#./child/value"

# Set value through triple reference
parent.set_at_reference("ref_value", 789)

# Check that the value was set correctly in the nested child
assert triple_child.child.child.value == 789
assert triple_child.child.value == 789
assert triple_child.value == 789
assert parent.ref_value == 789

# Reference string should remain unchanged
assert parent.get_unreferenced_value("ref_value") == "#./child/value"
assert triple_child.get_unreferenced_value("value") == "#./child/value"
assert triple_child.child.get_unreferenced_value("value") == "#./child/value"

0 comments on commit 7850564

Please sign in to comment.