Skip to content

Commit 56934b8

Browse files
committed
Automatically wrap multilinks too.
1 parent 906e37a commit 56934b8

File tree

2 files changed

+74
-5
lines changed

2 files changed

+74
-5
lines changed

gel/_internal/_qbmodel/_abstract/_link_set.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,7 @@ def __gel_extend__(self, values: Iterable[_PT_co | _BMT_co]) -> None:
954954

955955
self._ensure_snapshot()
956956

957+
linked_type = type(self).type
957958
proxy_type = type(self).proxytype
958959

959960
assert self._tracking_index is not None
@@ -963,14 +964,29 @@ def __gel_extend__(self, values: Iterable[_PT_co | _BMT_co]) -> None:
963964
# of slow iterative appends.
964965
empty_items = not self._items
965966

966-
for v in values:
967-
existing = self._find_proxy(v)
967+
for val in values:
968+
proxy_val: _PT_co | _BMT_co
969+
if (
970+
isinstance(val, linked_type)
971+
and not isinstance(val, proxy_type)
972+
):
973+
# The value is the correct target, but has not yet been wrapped
974+
# in a proxy model.
975+
proxy_val = proxy_type.__gel_proxy_construct__(
976+
val,
977+
dict.fromkeys(proxy_type.__linkprops__.__gel_reflection__.pointers.keys())
978+
)
979+
980+
else:
981+
proxy_val = val
982+
983+
existing = self._find_proxy(proxy_val)
968984

969985
proxy = cast(
970986
"_PT_co",
971987
proxy_link(
972988
existing=existing,
973-
new=v,
989+
new=proxy_val,
974990
proxy_type=proxy_type,
975991
),
976992
)

tests/test_model_sync.py

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2978,13 +2978,17 @@ def test_model_sync_multi_link_01(self):
29782978
def _testcase(
29792979
model_type: typing.Type[GelModel],
29802980
initial_targets: typing.Collection[typing.Any],
2981+
expected_targets: typing.Collection[typing.Any] | None = None,
29812982
) -> None:
2983+
if expected_targets is None:
2984+
expected_targets = initial_targets
2985+
29822986
with_targets = model_type(targets=initial_targets)
29832987
without_targets = model_type()
29842988

29852989
self.client.sync(with_targets, without_targets)
29862990

2987-
self._check_multilinks_equal(with_targets.targets, initial_targets)
2991+
self._check_multilinks_equal(with_targets.targets, expected_targets)
29882992
self._check_multilinks_equal(without_targets.targets, [])
29892993

29902994
# cleanup
@@ -2996,6 +3000,15 @@ def _testcase(
29963000

29973001
# With linkprops
29983002
_testcase(default.SourceWithProp, [])
3003+
_testcase(
3004+
default.SourceWithProp,
3005+
[target_a, target_b, target_c],
3006+
[
3007+
default.SourceWithProp.targets.link(target_a),
3008+
default.SourceWithProp.targets.link(target_b),
3009+
default.SourceWithProp.targets.link(target_c),
3010+
],
3011+
)
29993012
_testcase(
30003013
default.SourceWithProp,
30013014
[
@@ -3026,12 +3039,16 @@ def _testcase_assign(
30263039
model_type: typing.Type[GelModel],
30273040
initial_targets: typing.Collection[typing.Any],
30283041
changed_targets: typing.Collection[typing.Any],
3042+
expected_targets: typing.Collection[typing.Any] | None = None,
30293043
) -> None:
3044+
if expected_targets is None:
3045+
expected_targets = changed_targets
3046+
30303047
self._base_testcase(
30313048
model_type,
30323049
initial_targets,
30333050
self._get_assign_targets_func(changed_targets),
3034-
changed_targets,
3051+
expected_targets,
30353052
)
30363053

30373054
def test_model_sync_multi_link_02(self):
@@ -3089,6 +3106,16 @@ def test_model_sync_multi_link_02(self):
30893106

30903107
# With linkprops
30913108
self._testcase_assign(default.SourceWithProp, [], [])
3109+
self._testcase_assign(
3110+
default.SourceWithProp,
3111+
[],
3112+
[target_a, target_b, target_c],
3113+
[
3114+
default.SourceWithProp.targets.link(target_a),
3115+
default.SourceWithProp.targets.link(target_b),
3116+
default.SourceWithProp.targets.link(target_c),
3117+
],
3118+
)
30923119
self._testcase_assign(
30933120
default.SourceWithProp,
30943121
[],
@@ -3117,6 +3144,20 @@ def test_model_sync_multi_link_02(self):
31173144
],
31183145
[],
31193146
)
3147+
self._testcase_assign(
3148+
default.SourceWithProp,
3149+
[
3150+
default.SourceWithProp.targets.link(target_a),
3151+
default.SourceWithProp.targets.link(target_b),
3152+
default.SourceWithProp.targets.link(target_c),
3153+
],
3154+
[target_a, target_b, target_c],
3155+
[
3156+
default.SourceWithProp.targets.link(target_a),
3157+
default.SourceWithProp.targets.link(target_b),
3158+
default.SourceWithProp.targets.link(target_c),
3159+
],
3160+
)
31203161
self._testcase_assign(
31213162
default.SourceWithProp,
31223163
[
@@ -3194,6 +3235,18 @@ def test_model_sync_multi_link_02(self):
31943235
],
31953236
)
31963237

3238+
self._testcase_assign(
3239+
default.SourceWithProp,
3240+
[
3241+
default.SourceWithProp.targets.link(target_a),
3242+
default.SourceWithProp.targets.link(target_b),
3243+
],
3244+
[target_c, target_d],
3245+
[
3246+
default.SourceWithProp.targets.link(target_c),
3247+
default.SourceWithProp.targets.link(target_d),
3248+
],
3249+
)
31973250
self._testcase_assign(
31983251
default.SourceWithProp,
31993252
[

0 commit comments

Comments
 (0)