code: def set_layout(self, value):
          
          # Can't do this with changes_squashed as it will call update_modified
          # from another thread and deadlock. Need RLock.is_owned() from update_*
          part_info = self.run_hooks(
              LayoutHook(p, c, self.port_info, value)
              for p, c in self.create_part_contexts(only_visible=False).items())
          with self.changes_squashed:
              layout_parts = LayoutInfo.filter_parts(part_info)
              name, mri, x, y, visible = [], [], [], [], []
              for part_name, layout_infos in layout_parts.items():
                  for layout_info in layout_infos:
                      name.append(part_name)
                      mri.append(layout_info.mri)
                      x.append(layout_info.x)
                      y.append(layout_info.y)
                      visible.append(layout_info.visible)
              layout_table = LayoutTable(name, mri, x, y, visible)
              try:
                  # Compare the Array seq to get at the numpy array
                  np.testing.assert_equal(
                      layout_table.visible.seq, self.layout.value.visible.seq)
              except AssertionError:
                  visibility_changed = True
              else:
                  visibility_changed = False
              self.layout.set_value(layout_table)
              if self.saved_visibility is None:
                  # First write of table, set layout and exports saves
                  self.saved_visibility = layout_table.visible
                  self.saved_exports = self.exports.value.to_dict()
                  # Force visibility changed so we update_block_endpoints
                  # even if there weren't any visible
                  visibility_changed = True
              if visibility_changed:
                  self.update_modified()
                  self.update_exportable()
                  # Part visibility changed, might have attributes or methods
                  # that we need to hide or show
                  self.update_block_endpoints()
docs: Set the layout table value. Called on attribute put