state: _init_mutable_fields for backend vars as well (#1729)

This commit is contained in:
Masen Furer 2023-08-31 15:50:20 -07:00 committed by GitHub
parent ca4724cec8
commit 97869136bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -127,28 +127,33 @@ class State(Base, ABC, extra=pydantic.Extra.allow):
parent_state.parent_state,
)
# Initialize the mutable fields.
self._init_mutable_fields()
# Create a fresh copy of the backend variables for this instance
self._backend_vars = copy.deepcopy(self.backend_vars)
# Initialize the mutable fields.
self._init_mutable_fields()
def _init_mutable_fields(self):
"""Initialize mutable fields.
So that mutation to them can be detected by the app:
* list
Allow mutation to dict, list, and set to be detected by the app.
"""
for field in self.base_vars.values():
value = getattr(self, field.name)
value_in_rx_data = _convert_mutable_datatypes(
value, self._reassign_field, field.name
)
if types._issubclass(field.type_, Union[List, Dict]):
if types._issubclass(field.type_, Union[List, Dict, Set]):
value_in_rx_data = _convert_mutable_datatypes(
value, self._reassign_field, field.name
)
setattr(self, field.name, value_in_rx_data)
for field_name, value in self._backend_vars.items():
if isinstance(value, (list, dict, set)):
value_in_rx_data = _convert_mutable_datatypes(
value, self._reassign_field, field_name
)
self._backend_vars[field_name] = value_in_rx_data
self._clean()
def _init_event_handlers(self, state: State | None = None):
@ -651,16 +656,18 @@ class State(Base, ABC, extra=pydantic.Extra.allow):
setattr(self.parent_state, name, value)
return
# Make sure lists and dicts are converted to ReflexList, ReflexDict and ReflexSet.
if name in (*self.base_vars, *self.backend_vars) and types._isinstance(
value, Union[List, Dict, Set]
):
value = _convert_mutable_datatypes(value, self._reassign_field, name)
if types.is_backend_variable(name) and name != "_backend_vars":
self._backend_vars.__setitem__(name, value)
self.dirty_vars.add(name)
self._mark_dirty()
return
# Make sure lists and dicts are converted to ReflexList, ReflexDict and ReflexSet.
if name in self.vars and types._isinstance(value, Union[List, Dict, Set]):
value = _convert_mutable_datatypes(value, self._reassign_field, name)
# Set the attribute.
super().__setattr__(name, value)