enthought / enthought/traitsui
Non-live contexts problematic with Controllers and ModelViews
- Dominant language
- Python
- Stars
- 306
- Forks
- 99
- PR merge metrics
- No merged PRs in 30d
Description
Because `Controller`s and `ModelView`s hold state and non-live contexts call clone traits on each and every value in the context, you can end up with multiple independent copies of both the model and the handler, and which one is being accessed at any given time is not at all clear.
See the following code, for example:
```
from traits.api import HasTraits, Int, Property, Unicode, cached_property
from traitsui.api import Controller, ModelView, View, Item
class MyModel(HasTraits):
value = Unicode
class MyModelView(ModelView):
another_value = Unicode
length = Property(Int, depends_on=['another_value', 'model.value'])
def init(self, info):
print(self, info.handler, info.object)
print(self.model, info.model, info.object.model, info.handler.model)
@cached_property
def _get_length(self):
return len(self.another_value) + len(self.model.value)
view = View(
Item('another_value'),
Item('model.value'),
Item('length', style='readonly'),
)
class MyController(Controller):
another_value = Unicode
length = Property(Int, depends_on=['another_value', 'model.value'])
def init(self, info):
print(self, info.handler, info.controller)
print(self.model, info.object, info.controller.model, info.handler.model)
@cached_property
def _get_length(self):
return len(self.another_value) + len(self.model.value)
view = View(
Item('controller.another_value'),
Item('value'),
Item('controller.length', style='readonly'),
)
m = MyModelView(model=MyModel())
m.configure_traits(kind='modal')
m = MyController(model=MyModel())
m.configure_traits(kind='modal')
```
Note that you end up with no less than 4 copies of the model object; also note that the `length` property does not respond to changes in the model's `value` as expected.
This is not a problem for `Handlers` as they don't have any state, so even if a cloned handler gets invoked, you have to go through the context to get any actual values.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the reproduced MyModelView and MyController examples and their configure_traits(kind='modal') entry points. Trace how non-live contexts clone values and compare the model, handler, controller, and object references shown by init. Done means the context has consistent model and handler state and the length property responds to model.value changes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100