Skip to content

Commit 05dad38

Browse files
committed
better test
1 parent 6888754 commit 05dad38

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

src/textual/dom.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import re
1010
import threading
11+
from copy import copy
1112
from functools import lru_cache, partial
1213
from inspect import getfile
1314
from typing import (
@@ -334,7 +335,10 @@ def setter(value: object) -> None:
334335
"""Set bound data."""
335336
_rich_traceback_omit = True
336337
Reactive._initialize_object(self)
337-
setattr(self, variable_name, _Mutated(value))
338+
# Copy the bound value
339+
# Sharing the same instance with mutable objects can lead to confusing behavior
340+
# Wrap the value in `_Mutated` so the setter knows to invoke watchers etc
341+
setattr(self, variable_name, _Mutated(copy(value)))
338342

339343
return setter
340344

tests/test_reactive.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,12 +804,25 @@ def compose(self) -> ComposeResult:
804804
yield TestWidget().data_bind(TestApp.messages)
805805

806806
app = TestApp()
807-
async with app.run_test() as pilot:
807+
async with app.run_test():
808+
test_widget = app.query_one(TestWidget)
808809
assert widget_messages == [[]]
810+
assert test_widget.messages == []
811+
812+
# Previously setting a mutable object would lead to shared references
813+
assert app.messages is not test_widget.messages
814+
815+
# Mutate app
809816
app.messages.append("foo")
810817
# Mutations aren't detected
811818
assert widget_messages == [[]]
819+
assert app.messages == ["foo"]
820+
assert test_widget.messages == []
812821
# Explicitly mutate app reactive
813822
app.mutate_reactive(TestApp.messages)
814823
# Mutating app, will also invoke watchers on any data binds
815824
assert widget_messages == [[], ["foo"]]
825+
assert app.messages == ["foo"]
826+
assert test_widget.messages == ["foo"]
827+
828+
assert app.messages is not test_widget.messages

0 commit comments

Comments
 (0)