Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REF-1356] Track changes applied to Base subclass via helper method. #2242

Merged
merged 7 commits into from
May 31, 2024

Conversation

masenf
Copy link
Collaborator

@masenf masenf commented Dec 1, 2023

When a helper method manipulates fields on a Base instance that is associated with a state, recursively wrap the helper method with the MutableProxy so it also tracks changes.

If the helper method returns a mutable object, this object will also be tied back to the same field on the state to allow for "get_*" type functions that still track changes.

Fix #2239

When a helper method manipulates fields on a Base instance that is associated
with a state, recursively wrap the helper method with the MutableProxy so it
also tracks changes.

If the helper method returns a mutable object, this object will also be tied
back to the same field on the state to allow for "get_*" type functions that
still track changes.

Fix #2239
Comment on lines 2331 to 2344
def test_set_base_field_via_setter():
"""When calling a setter on a Base instance, also track changes."""

class BaseFieldSetterState(BaseState):
c1: Custom1 = Custom1(foo="")

bfss = BaseFieldSetterState()
assert "c1" not in bfss.dirty_vars
bfss.c1.double_foo()
assert "c1" not in bfss.dirty_vars
bfss.c1.set_foo("bar")
assert "c1" in bfss.dirty_vars


Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, this covers the issue -- thanks!

I'm now wondering if this will work if using Custom2 to do a nested call to Custom1 (something like a hypothetical c2r.set_c1_foo(), which calls c1r.set_foo()). I do see some terminology around recursion in the function wrapper, so if I had to guess it seems like this is the intent; if so maybe good to also capture in a test case?

Comment on lines 2331 to 2344
def test_set_base_field_via_setter():
"""When calling a setter on a Base instance, also track changes."""

class BaseFieldSetterState(BaseState):
c1: Custom1 = Custom1(foo="")

bfss = BaseFieldSetterState()
assert "c1" not in bfss.dirty_vars
bfss.c1.double_foo()
assert "c1" not in bfss.dirty_vars
bfss.c1.set_foo("bar")
assert "c1" in bfss.dirty_vars


Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also wondering how this works for shared references, too? Something like this:

class State(rx.State):
    a: A()
    b: B()

    def __init__(self):
        c = C()
        a.c = c
        b.c = c

    def trigger_a():
        self.a.update_c() # Does this trigger `b` being dirty?

@masenf masenf marked this pull request as ready for review May 23, 2024 22:32
@masenf masenf changed the title Track changes applied to Base subclass via helper method. [REF-1356] Track changes applied to Base subclass via helper method. May 23, 2024
Copy link

linear bot commented May 23, 2024

@picklelo picklelo merged commit b04e3a6 into main May 31, 2024
47 checks passed
benedikt-bartscher pushed a commit to benedikt-bartscher/reflex that referenced this pull request Jun 3, 2024
@masenf masenf deleted the masenf/track-changes-in-base-helpers branch June 25, 2024 02:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[REF-1356] Updates Custom Var with collection does not trigger re-render
3 participants