nova-mvvm 0.14.0__py3-none-any.whl → 0.15.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,6 +12,8 @@ from ._internal.pydantic_utils import get_nested_pydantic_field
12
12
 
13
13
  logger = logging.getLogger(__name__)
14
14
 
15
+ ERROR_FIELD_NAME = "pydantic_errors"
16
+
15
17
 
16
18
  def get_field_info(field_name: str) -> FieldInfo:
17
19
  """
@@ -28,6 +28,7 @@ from ..interface import (
28
28
  LinkedObjectType,
29
29
  Worker,
30
30
  )
31
+ from ..pydantic_utils import ERROR_FIELD_NAME
31
32
  from .trame_worker import TrameWorker
32
33
 
33
34
 
@@ -176,12 +177,21 @@ class StateConnection:
176
177
  return update
177
178
 
178
179
  def _set_variable_in_state(self, name_in_state: str, value: Any) -> None:
180
+ if "." in name_in_state:
181
+ base_name, name_in_state = name_in_state.split(".", maxsplit=1)
182
+ if self.state[base_name] is None:
183
+ self.state[base_name] = {}
184
+ state_obj = self.state[base_name]
185
+ else:
186
+ base_name = name_in_state
187
+ state_obj = self.state
188
+
179
189
  if is_async():
180
190
  with self.state:
181
- self.state[name_in_state] = value
191
+ state_obj[name_in_state] = value
182
192
  self.state.dirty(name_in_state)
183
193
  else:
184
- self.state[name_in_state] = value
194
+ state_obj[name_in_state] = value
185
195
  self.state.dirty(name_in_state)
186
196
 
187
197
  def _get_name_in_state(self, attribute_name: str) -> str:
@@ -207,6 +217,9 @@ class StateConnection:
207
217
  name_in_state = self._get_name_in_state(attribute_name)
208
218
  self.state.setdefault(name_in_state, None)
209
219
 
220
+ # Set the initial error state.
221
+ self._set_variable_in_state(f"{state_variable_name}.{ERROR_FIELD_NAME}", [])
222
+
210
223
  # this updates ViewModel on state change
211
224
  if self.viewmodel_linked_object:
212
225
  if self.linked_object_attributes:
@@ -234,6 +247,7 @@ class StateConnection:
234
247
  updated = False
235
248
  except ValidationError as e:
236
249
  errors = get_errored_fields_from_validation_error(e)
250
+ self._set_variable_in_state(f"{state_variable_name}.{ERROR_FIELD_NAME}", errors)
237
251
  error = e
238
252
  updated = True
239
253
  self.has_errors = True
@@ -248,6 +262,7 @@ class StateConnection:
248
262
  if self.has_errors and not errors:
249
263
  updated = True
250
264
  self.has_errors = False
265
+ self._set_variable_in_state(f"{state_variable_name}.{ERROR_FIELD_NAME}", [])
251
266
  if updated:
252
267
  await self._handle_callback({"updated": updates, "errored": errors, "error": error})
253
268
 
@@ -260,8 +275,10 @@ class StateConnection:
260
275
  name_in_state = self._get_name_in_state(attribute_name)
261
276
  value_to_change = rgetattr(value, attribute_name)
262
277
  self._set_variable_in_state(name_in_state, value_to_change)
278
+ self._set_variable_in_state(f"{name_in_state}.{ERROR_FIELD_NAME}", [])
263
279
  elif self.state_variable_name:
264
280
  self._set_variable_in_state(self.state_variable_name, value)
281
+ self._set_variable_in_state(f"{self.state_variable_name}.{ERROR_FIELD_NAME}", [])
265
282
 
266
283
  def get_callback(self) -> ConnectCallbackType:
267
284
  return None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nova-mvvm
3
- Version: 0.14.0
3
+ Version: 0.15.0
4
4
  Summary: A Python Package for Model-View-ViewModel pattern
5
5
  Author-email: Sergey Yakubov <yakubovs@ornl.gov>, John Duggan <dugganjw@ornl.gov>, Greg Watson <watsongr@ornl.gov>
6
6
  License-Expression: MIT
@@ -2,7 +2,7 @@ nova/__init__.py,sha256=ED6jHcYiuYpr_0vjGz0zx2lrrmJT9sDJCzIljoDfmlM,65
2
2
  nova/mvvm/__init__.py,sha256=fo1bT27jjUYzVoFJXuwokXcyFtOYj8eQ_BHkPgtI4Rg,149
3
3
  nova/mvvm/bindings_map.py,sha256=SIVNPGHxDf91P9UxcPmuAHx1GNxZk66JUc-fYPcp-kc,417
4
4
  nova/mvvm/interface.py,sha256=l4l339BiB46s6KX-2RH1Q3Hxc8pKYdCvCOkhse4zOkw,5812
5
- nova/mvvm/pydantic_utils.py,sha256=kQ17-Thp_4FMQca6nJ_UNWbctssqHGY3FtZolUIZGQ0,3191
5
+ nova/mvvm/pydantic_utils.py,sha256=t8niOvGoA87TUjT4adbgMdoFL9mDaNjLkV1xXyWlDK8,3229
6
6
  nova/mvvm/_internal/pydantic_utils.py,sha256=anYYyB1Bkg8GgWB3Jn-6iRit0PYR-_2w3paKsD9z4sY,2947
7
7
  nova/mvvm/_internal/pyqt_communicator.py,sha256=G_Srttxn7EEwz9EageFxnOgg_P-gfPPhNpoR55btHd0,3929
8
8
  nova/mvvm/_internal/utils.py,sha256=LpZ3LALcB9BzG1yIh0Qt0kBXGdctacDMVmSm8H8Py1c,3626
@@ -15,9 +15,9 @@ nova/mvvm/pyqt6_binding/__init__.py,sha256=plms0W4kJjFpZReGOC7lE3SYX1ceGTLbdAJ1G
15
15
  nova/mvvm/pyqt6_binding/binding.py,sha256=uZNHx23Pf9DwGf3qKfQdmjOhmaXcppNd8pjkh363WP4,1365
16
16
  nova/mvvm/pyqt6_binding/pyqt6_worker.py,sha256=y8g_mfPC1xIcpyKq7ZZqxrn9Txp5gPJrsBjAwS5FHhY,2133
17
17
  nova/mvvm/trame_binding/__init__.py,sha256=uTdEW9VxtVubSbTLpoD3pC8a-KMgbKkZFlRbucvuQSE,62
18
- nova/mvvm/trame_binding/binding.py,sha256=m3pcadwhDEmcvEQ24BvU65vpUFjX3QoZQlQmeVcPwmg,12481
18
+ nova/mvvm/trame_binding/binding.py,sha256=hKIeIUAp9Zzc4UtGtzD6UBwQltfh5i79pEzpWHLRS7E,13369
19
19
  nova/mvvm/trame_binding/trame_worker.py,sha256=JmrneFU11Hi8TtY558R3yIWW8UGiUeVNO7HvM1uWTVs,3778
20
- nova_mvvm-0.14.0.dist-info/METADATA,sha256=xspULchDL9PyMWCDu2oa2uzpdIhDEQ6yZgIp7ItuV5I,1090
21
- nova_mvvm-0.14.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
22
- nova_mvvm-0.14.0.dist-info/licenses/LICENSE,sha256=MOqZ8tPMKy8ZETJ2-HEvFTZ7dYNlg3gXmBkV-Y9i8bw,1061
23
- nova_mvvm-0.14.0.dist-info/RECORD,,
20
+ nova_mvvm-0.15.0.dist-info/METADATA,sha256=BfmKRWdHZ0gdiOvQXJQ_4YcuWxAYv-LuKQ6rHBhF7Go,1090
21
+ nova_mvvm-0.15.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
22
+ nova_mvvm-0.15.0.dist-info/licenses/LICENSE,sha256=MOqZ8tPMKy8ZETJ2-HEvFTZ7dYNlg3gXmBkV-Y9i8bw,1061
23
+ nova_mvvm-0.15.0.dist-info/RECORD,,