Skip to content

Commit 7cee054

Browse files
committed
Fix default not being used when multi prop with default is not set.
1 parent 462e0e9 commit 7cee054

File tree

3 files changed

+70
-13
lines changed

3 files changed

+70
-13
lines changed

gel/_internal/_qbmodel/_pydantic/_fields.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,14 +278,22 @@ def __gel_resolve_dlist__( # type: ignore [override]
278278
def _validate(
279279
cls,
280280
value: Any,
281-
generic_args: tuple[type[Any], type[Any]],
282-
) -> _tracked_list.DowncastingTrackedList[_ST_co, _BT_co]:
281+
generic_args: tuple[type[_ST_co], type[_BT_co]],
282+
) -> (
283+
_tracked_list.DowncastingTrackedList[_ST_co, _BT_co]
284+
| _abstract.DefaultValue
285+
):
283286
lt: type[_tracked_list.DowncastingTrackedList[_ST_co, _BT_co]] = (
284287
_tracked_list.DowncastingTrackedList[
285-
generic_args[0], # type: ignore [valid-type]
286-
generic_args[1], # type: ignore [valid-type]
288+
generic_args[0],
289+
generic_args[1],
287290
]
288291
)
292+
if isinstance(value, _tracked_list.DefaultList):
293+
# Convert the pydantic generated default into
294+
# the internal DEFAULT_VALUE
295+
return _abstract.DEFAULT_VALUE
296+
289297
return LinkSet.__gel_validate__(lt, value)
290298

291299

gel/_internal/_save.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,12 @@ def make_plan(
818818

819819
assert is_prop_list(val)
820820

821-
if mp_added := val.__gel_get_added__():
821+
if (
822+
(mp_added := val.__gel_get_added__())
823+
# Even if there are no added values, push the change if
824+
# there is a default value we want to override.
825+
or (is_new and prop.has_default)
826+
):
822827
push_change(
823828
requireds,
824829
sched,

tests/test_model_sync.py

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,22 @@ class TestModelSyncMultiProp(tb.ModelTestCase):
14161416
type C {
14171417
multi val: tuple<str, int64>;
14181418
};
1419+
1420+
type Az {
1421+
multi val: int64 {
1422+
default := {-1, -2, -3};
1423+
};
1424+
};
1425+
type Bz {
1426+
multi val: array<int64> {
1427+
default := {[-1], [-2, -2], [-3, -3, -3]};
1428+
};
1429+
};
1430+
type Cz {
1431+
multi val: tuple<str, int64> {
1432+
default := {('.', -1), ('.', -2), ('.', -3)};
1433+
};
1434+
};
14191435
"""
14201436

14211437
def _base_change_testcase(
@@ -1469,27 +1485,55 @@ def test_model_sync_multi_prop_01(self):
14691485
def _testcase(
14701486
model_type: typing.Type[GelModel],
14711487
val: typing.Any,
1488+
*,
1489+
default_val: typing.Any | None = None,
14721490
) -> None:
1491+
if default_val is None:
1492+
default_val = []
1493+
1494+
# sync one at a time
14731495
with_val = model_type(val=val)
1474-
without_val = model_type()
1496+
self.client.sync(with_val)
1497+
self.assertEqual(with_val.val, val)
14751498

1476-
self.client.sync(with_val, without_val)
1499+
with_unset = model_type()
1500+
self.client.sync(with_unset)
1501+
self.assertEqual(with_unset.val, default_val)
1502+
1503+
with_empty = model_type(val=[])
1504+
self.client.sync(with_empty)
1505+
self.assertEqual(with_empty.val, [])
1506+
1507+
# sync all together
1508+
with_val = model_type(val=val)
1509+
with_unset = model_type()
1510+
with_empty = model_type(val=[])
1511+
1512+
self.client.sync(with_val, with_unset, with_empty)
14771513

14781514
self.assertEqual(with_val.val, val)
1479-
self.assertEqual(without_val.val, [])
1515+
self.assertEqual(with_unset.val, default_val)
1516+
self.assertEqual(with_empty.val, [])
14801517

14811518
# cleanup
14821519
self.client.query(model_type.delete())
14831520

1484-
_testcase(default.A, [])
1485-
_testcase(default.B, [])
1486-
_testcase(default.C, [])
1487-
14881521
_testcase(default.A, [1, 2, 3])
1489-
_testcase(default.B, [[]])
14901522
_testcase(default.B, [[1], [2, 2], [3, 3, 3]])
14911523
_testcase(default.C, [("a", 1), ("b", 2), ("c", 3)])
14921524

1525+
_testcase(default.Az, [1, 2, 3], default_val=[-1, -2, -3])
1526+
_testcase(
1527+
default.Bz,
1528+
[[1], [2, 2], [3, 3, 3]],
1529+
default_val=[[-1], [-2, -2], [-3, -3, -3]],
1530+
)
1531+
_testcase(
1532+
default.Cz,
1533+
[("a", 1), ("b", 2), ("c", 3)],
1534+
default_val=[(".", -1), (".", -2), (".", -3)],
1535+
)
1536+
14931537
def test_model_sync_multi_prop_02(self):
14941538
# Updating existing objects with multi props
14951539
# Set prop to new value

0 commit comments

Comments
 (0)