maxfordham/ipyautoui

๐Ÿ› MultiIndexEditableGrid Demo not working

Opened this issue ยท 0 comments

Describe the bug
MultiIndexEditableGrid Demo failing to open:

image

See traceback below:

Command Line Output
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/ipywidgets/widgets/widget.py:773, in Widget._handle_msg(self, msg)
    771         if 'buffer_paths' in data:
    772             _put_buffers(state, data['buffer_paths'], msg['buffers'])
--> 773         self.set_state(state)
    775 # Handle a state request.
    776 elif method == 'request_state':

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/ipywidgets/widgets/widget.py:650, in Widget.set_state(self, sync_data)
645 self._send(msg, buffers=echo_buffers)
647 # The order of these context managers is important. Properties must
648 # be locked when the hold_trait_notification context manager is
649 # released and notifications are fired.
--> 650 with self._lock_property(**sync_data), self.hold_trait_notifications():
651 for name in sync_data:
652 if name in self.keys:

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/contextlib.py:144, in _GeneratorContextManager.exit(self, typ, value, traceback)
142 if typ is None:
143 try:
--> 144 next(self.gen)
145 except StopIteration:
146 return False

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:1498, in HasTraits.hold_trait_notifications(self)
1496 for changes in cache.values():
1497 for change in changes:
-> 1498 self.notify_change(change)

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/ipywidgets/widgets/widget.py:701, in Widget.notify_change(self, change)
698 if name in self.keys and self._should_send_property(name, getattr(self, name)):
699 # Send new state to front-end
700 self.send_state(key=name)
--> 701 super().notify_change(change)

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:1513, in HasTraits.notify_change(self, change)
1511 def notify_change(self, change):
1512 """Notify observers of a change event"""
-> 1513 return self._notify_observers(change)

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:1560, in HasTraits._notify_observers(self, event)
1557 elif isinstance(c, EventHandler) and c.name is not None:
1558 c = getattr(self, c.name)
-> 1560 c(event)

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/ipywidgets/widgets/widget_selection.py:236, in _Selection._propagate_index(self, change)
234 self.label = label
235 if self.value is not value:
--> 236 self.value = value

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:729, in TraitType.set(self, obj, value)
727 raise TraitError('The "%s" trait is read-only.' % self.name)
728 else:
--> 729 self.set(obj, value)

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:718, in TraitType.set(self, obj, value)
714 silent = False
715 if silent is not True:
716 # we explicitly compare silent to True just in case the equality
717 # comparison above returns something other than True/False
--> 718 obj._notify_trait(self.name, old_value, new_value)

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:1501, in HasTraits._notify_trait(self, name, old_value, new_value)
1500 def _notify_trait(self, name, old_value, new_value):
-> 1501 self.notify_change(
1502 Bunch(
1503 name=name,
1504 old=old_value,
1505 new=new_value,
1506 owner=self,
1507 type="change",
1508 )
1509 )

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/ipywidgets/widgets/widget.py:701, in Widget.notify_change(self, change)
698 if name in self.keys and self._should_send_property(name, getattr(self, name)):
699 # Send new state to front-end
700 self.send_state(key=name)
--> 701 super().notify_change(change)

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:1513, in HasTraits.notify_change(self, change)
1511 def notify_change(self, change):
1512 """Notify observers of a change event"""
-> 1513 return self._notify_observers(change)

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:1560, in HasTraits._notify_observers(self, event)
1557 elif isinstance(c, EventHandler) and c.name is not None:
1558 c = getattr(self, c.name)
-> 1560 c(event)

File ~/git/MXF/ipyautoui/src/ipyautoui/demo.py:212, in DemoReel._update_demo(self, on_change)
210 model = self.map_name_pydantic_model[self.select.value]
211 if self.demo.pydantic_model != model:
--> 212 self.demo.pydantic_model = model

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:729, in TraitType.set(self, obj, value)
727 raise TraitError('The "%s" trait is read-only.' % self.name)
728 else:
--> 729 self.set(obj, value)

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:718, in TraitType.set(self, obj, value)
714 silent = False
715 if silent is not True:
716 # we explicitly compare silent to True just in case the equality
717 # comparison above returns something other than True/False
--> 718 obj._notify_trait(self.name, old_value, new_value)

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:1501, in HasTraits._notify_trait(self, name, old_value, new_value)
1500 def _notify_trait(self, name, old_value, new_value):
-> 1501 self.notify_change(
1502 Bunch(
1503 name=name,
1504 old=old_value,
1505 new=new_value,
1506 owner=self,
1507 type="change",
1508 )
1509 )

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/ipywidgets/widgets/widget.py:701, in Widget.notify_change(self, change)
698 if name in self.keys and self._should_send_property(name, getattr(self, name)):
699 # Send new state to front-end
700 self.send_state(key=name)
--> 701 super().notify_change(change)

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:1513, in HasTraits.notify_change(self, change)
1511 def notify_change(self, change):
1512 """Notify observers of a change event"""
-> 1513 return self._notify_observers(change)

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:1560, in HasTraits._notify_observers(self, event)
1557 elif isinstance(c, EventHandler) and c.name is not None:
1558 c = getattr(self, c.name)
-> 1560 c(event)

File ~/git/MXF/ipyautoui/src/ipyautoui/demo.py:52, in Demo._observe_pydantic_model(self, change)
47 except:
48 raise ValueError(
49 "for the Demo to work, the pydantic_model must"
50 " be defined in a separate python file."
51 )
---> 52 self._update_autoui()
53 self._update_pydantic()
54 self._update_jsonschema()

File ~/git/MXF/ipyautoui/src/ipyautoui/demo.py:106, in Demo._update_autoui(self)
105 def _update_autoui(self):
--> 106 self.autoui = AutoUi(self.pydantic_model)
107 self._update_pycall()
108 self.vbx_autoui.children = [self.vbx_pycall, self.autoui ]

File ~/git/MXF/ipyautoui/src/ipyautoui/autoui.py:285, in autoui(schema, value, path, **kwargs)
283 ui = get_autoui(schema, **kwargs) # TODO: resolve how path is handled
284 if value is None:
--> 285 return ui(**kwargs)
286 else:
287 return ui(value=value, **kwargs)

File ~/git/MXF/ipyautoui/src/ipyautoui/custom/editgrid.py:291, in EditGrid.from_pydantic_model(cls, model, **kwargs)
289 @classmethod
290 def from_pydantic_model(cls, model: ty.Type[BaseModel], **kwargs):
--> 291 return cls(model, **kwargs)

File ~/git/MXF/ipyautoui/src/ipyautoui/custom/editgrid.py:326, in EditGrid.init(self, schema, value, by_alias, by_title, datahandler, ui_add, ui_edit, ui_delete, ui_copy, warn_on_delete, show_copy_dialogue, close_crud_dialogue_on_action, title, description, show_title, **kwargs)
322 self.datahandler = datahandler
323 getvalue = lambda value: (
324 None if value is None or value == [{}] else pd.DataFrame(value)
325 )
--> 326 self.grid = AutoGrid(
327 schema, data=getvalue(value), by_alias=self.by_alias, **kwargs
328 )
330 self._init_form()
331 if ui_add is None:

File ~/git/MXF/ipyautoui/src/ipyautoui/custom/autogrid.py:713, in AutoGrid.init(self, schema, data, by_alias, by_title, order, **kwargs)
711 self.by_title = by_title
712 self.selection_mode = MAP_TRANSPOSED_SELECTION_MODE[self.transposed]
--> 713 self.model, self.schema = asch._init_model_schema(schema, by_alias=by_alias)
714 # ^ generates gridschema
715 self.gridschema.get_traits = self.datagrid_trait_names

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:729, in TraitType.set(self, obj, value)
727 raise TraitError('The "%s" trait is read-only.' % self.name)
728 else:
--> 729 self.set(obj, value)

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:718, in TraitType.set(self, obj, value)
714 silent = False
715 if silent is not True:
716 # we explicitly compare silent to True just in case the equality
717 # comparison above returns something other than True/False
--> 718 obj._notify_trait(self.name, old_value, new_value)

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:1501, in HasTraits._notify_trait(self, name, old_value, new_value)
1500 def _notify_trait(self, name, old_value, new_value):
-> 1501 self.notify_change(
1502 Bunch(
1503 name=name,
1504 old=old_value,
1505 new=new_value,
1506 owner=self,
1507 type="change",
1508 )
1509 )

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/ipywidgets/widgets/widget.py:701, in Widget.notify_change(self, change)
698 if name in self.keys and self._should_send_property(name, getattr(self, name)):
699 # Send new state to front-end
700 self.send_state(key=name)
--> 701 super().notify_change(change)

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:1513, in HasTraits.notify_change(self, change)
1511 def notify_change(self, change):
1512 """Notify observers of a change event"""
-> 1513 return self._notify_observers(change)

File ~/miniforge3/envs/ipyautoui-dev/lib/python3.12/site-packages/traitlets/traitlets.py:1560, in HasTraits._notify_observers(self, event)
1557 elif isinstance(c, EventHandler) and c.name is not None:
1558 c = getattr(self, c.name)
-> 1560 c(event)

File ~/git/MXF/ipyautoui/src/ipyautoui/custom/autogrid.py:624, in AutoGrid._update_from_schema(self, change)
622 @tr.observe("schema")
623 def _update_from_schema(self, change):
--> 624 self.gridschema = GridSchema(self.schema, **self.kwargs)

File ~/git/MXF/ipyautoui/src/ipyautoui/custom/autogrid.py:206, in GridSchema.init(self, schema, get_traits, **kwargs)
203 self.get_traits = get_traits
205 self.map_name_index = self.get_map_name_index()
--> 206 self.map_index_name = {v: k for k, v in self.map_name_index.items()}
208 self.set_renderers(**kwargs)
210 self.column_widths = get_column_widths_from_schema(
211 schema, self.properties, self.map_name_index, **kwargs
212 )

TypeError: unhashable type: 'list'