Skip to content

Data Formatting Requiring Hashable Values when Nullable is True #314

@matheuskknd

Description

@matheuskknd

Hey there, @ragardner. How are you?

Well, I have recently used tksheet to render arbitrarylly complex n-dimensional data structures. This is being accomplished by inserting dataclasses and lists with dataclasses right into a single tksheet table cell. Then using very specialized format_functions, to_str_functions and clipboard_function. As well as using thkeet event binding to handle events on these cells allowing the user to get a popup (expanded) view and manipulate whatever complex data is inside that cell properly...

In this complex context, there is a specific scenario where it seems that I touch a non-documented tksheet limitation/restriction when I try to use "nullable=true" in the formatter parameters for certain span, and this same span has values of "non-hashable" types (like python's list).

Sample code that generates the exception only for the second column: unhashable type: 'list'

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

import weakref
from tkinter import messagebox, simpledialog
from typing import Any, Callable, Literal, cast

import customtkinter as ctk
import tksheet


class TableFrame(ctk.CTkFrame):

	def __init__(self, master: Any, **kwargs: Any) -> None:
		super().__init__(master, **kwargs)

		# Creating the spreadsheet as an attribute
		self.sheet: tksheet.Sheet = tksheet.Sheet(
			self,
			headers=["A", "B"],
			data=[[list(), None], [list(), list()]],
		)
		self.sheet.pack(expand=True, fill="both")
		self.sheet.enable_bindings("all")

		# Makes the spreadsheet readonly for simplicity
		self.sheet.span(table=True, index=True, header=True).readonly(True)

		format_function = lambda o, **kwargs: o  # type: ignore
		to_str_function = lambda o, **kwargs: "" if o is None else "[ ... ]"  # type: ignore
		clipboard_function = lambda o, **kwargs: "Too complex to reproduct here..."  # type: ignore

		# Make the first column to BE NOT nullable. NOTE: here "hashable" IS NOT required by tksheet!
		self.sheet.named_span(
			self.sheet.span(
				tksheet.num2alpha(0),
				type_="format",
				### Sheet.format arguments
				formatter_options=tksheet.formatter(
					datatypes=(list, ),
					format_function=format_function,
					to_str_function=to_str_function,
					nullable=False,
					clipboard_function=clipboard_function,
				),
				redraw=False,
			))

		# Make the second column to BE nullable. NOTE: here "hashable" IS required by tksheet!
		self.sheet.named_span(
			self.sheet.span(
				tksheet.num2alpha(1),
				type_="format",
				### Sheet.format arguments
				formatter_options=tksheet.formatter(
					datatypes=(list, type(None)),
					format_function=format_function,
					to_str_function=to_str_function,
					nullable=True,
					clipboard_function=clipboard_function,
				),
				redraw=False,
			))


def main():
	ctk.set_appearance_mode("light")
	ctk.set_default_color_theme("blue")

	root = ctk.CTk()
	root.geometry("800x400")
	root.title("customtkinter + tksheet")

	tabela = TableFrame(root)
	tabela.pack(expand=True, fill="both", padx=10, pady=10)

	root.mainloop()


if __name__ == "__main__":
	main()

Tested on: Windows 10, Python 3.12.8 and tksheet 7.5.18

Asking politelly:

  1. Is it possible to remove this limitation/restriction from tksheet?
  2. Could you explain why this limitation/restriction exists only when "nullable=True"?
  3. If this cannot be removed, is there a workaround to allow rendering "non-hashable" values that are possibly None?

Best regards

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions