traits icon indicating copy to clipboard operation
traits copied to clipboard

Sync_trait() does not propagate mutations of Dict traits

Open xamcost opened this issue 2 years ago • 2 comments

Hi there! This issue is to report an un expected behaviour using HasTraits.sync_trait() with Dict traits. In the code snippet below, I have to Dict traits synchronised: when the Dict trait of the parent is reassigned, no problem, the one of the child got modified as well. However, a mutation of the dictionary is not propagated. Is it a known issue ?

from traits.api import Dict, HasStrictTraits, Instance


class Bar(HasStrictTraits):

    bar_dict = Dict()


class Foo(HasStrictTraits):

    foo_dict = Dict()

    bar = Instance(Bar)

    def __init__(self, **traits):
        super().__init__(**traits)

        self.sync_trait('foo_dict', self.bar, 'bar_dict')


if __name__ == "__main__":
    foo = Foo(bar=Bar())

    foo.foo_dict = {"a": 1, "b": 2}
    print(f"Bar dict: {foo.bar.bar_dict}")
    # prints: Bar dict: {'a': 1, 'b': 2}

    foo.foo_dict.update({"c": 3})
    print(f"Bar dict: {foo.bar.bar_dict}")
    # prints: Bar dict: {'a': 1, 'b': 2}

    foo.foo_dict["d"] = 0
    print(f"Bar dict: {foo.bar.bar_dict}")
    # prints: Bar dict: {'a': 1, 'b': 2}

xamcost avatar Jul 22 '21 22:07 xamcost

Known. List traits are the only ones where the *_items is also synced. So more of a feature request than a bug.

rkern avatar Jul 23 '21 03:07 rkern

I've opened #1519 to better document the current state of affairs. A PR that adds the synchronization for Dict and Set would be welcome. Technically that would be a backwards incompatible change that risks breaking existing code, but I'm finding it hard to imagine use-cases where you'd want to synchronize a dict object but not its items.

mdickinson avatar Sep 10 '21 08:09 mdickinson