tksheet 7.4.5__tar.gz → 7.4.6__tar.gz
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.
- {tksheet-7.4.5/tksheet.egg-info → tksheet-7.4.6}/PKG-INFO +1 -1
- {tksheet-7.4.5 → tksheet-7.4.6}/pyproject.toml +1 -1
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet/__init__.py +1 -1
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet/column_headers.py +28 -28
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet/constants.py +4 -3
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet/find_window.py +8 -8
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet/formatters.py +39 -39
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet/functions.py +53 -57
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet/main_table.py +153 -122
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet/other_classes.py +11 -11
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet/row_index.py +27 -27
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet/sheet.py +99 -110
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet/sorting.py +19 -18
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet/text_editor.py +9 -9
- tksheet-7.4.6/tksheet/tksheet_types.py +216 -0
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet/top_left_rectangle.py +13 -12
- {tksheet-7.4.5 → tksheet-7.4.6/tksheet.egg-info}/PKG-INFO +1 -1
- tksheet-7.4.5/tksheet/tksheet_types.py +0 -29
- {tksheet-7.4.5 → tksheet-7.4.6}/LICENSE.txt +0 -0
- {tksheet-7.4.5 → tksheet-7.4.6}/README.md +0 -0
- {tksheet-7.4.5 → tksheet-7.4.6}/setup.cfg +0 -0
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet/colors.py +0 -0
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet/sheet_options.py +0 -0
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet/themes.py +0 -0
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet.egg-info/SOURCES.txt +0 -0
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet.egg-info/dependency_links.txt +0 -0
- {tksheet-7.4.5 → tksheet-7.4.6}/tksheet.egg-info/top_level.txt +0 -0
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
|
|
6
6
|
name = "tksheet"
|
7
7
|
description = "Tkinter table / sheet and treeview widget"
|
8
8
|
readme = "README.md"
|
9
|
-
version = "7.4.
|
9
|
+
version = "7.4.6"
|
10
10
|
authors = [{ name = "ragardner", email = "github@ragardner.simplelogin.com" }]
|
11
11
|
requires-python = ">=3.8"
|
12
12
|
license = {file = "LICENSE.txt"}
|
@@ -7,7 +7,7 @@ from functools import partial
|
|
7
7
|
from itertools import cycle, islice, repeat
|
8
8
|
from math import ceil, floor
|
9
9
|
from operator import itemgetter
|
10
|
-
from typing import Literal
|
10
|
+
from typing import Any, Literal
|
11
11
|
|
12
12
|
from .colors import color_map
|
13
13
|
from .constants import (
|
@@ -166,7 +166,7 @@ class ColumnHeaders(tk.Canvas):
|
|
166
166
|
self.current_height = new_height
|
167
167
|
return expanded
|
168
168
|
|
169
|
-
def rc(self, event:
|
169
|
+
def rc(self, event: Any) -> None:
|
170
170
|
self.mouseclick_outside_editor_or_dropdown_all_canvases(inside=True)
|
171
171
|
self.focus_set()
|
172
172
|
popup_menu = None
|
@@ -193,7 +193,7 @@ class ColumnHeaders(tk.Canvas):
|
|
193
193
|
self.popup_menu_loc = c
|
194
194
|
popup_menu.tk_popup(event.x_root, event.y_root)
|
195
195
|
|
196
|
-
def ctrl_b1_press(self, event:
|
196
|
+
def ctrl_b1_press(self, event: Any) -> None:
|
197
197
|
self.mouseclick_outside_editor_or_dropdown_all_canvases(inside=True)
|
198
198
|
if (
|
199
199
|
(self.drag_and_drop_enabled or self.col_selection_enabled)
|
@@ -216,7 +216,7 @@ class ColumnHeaders(tk.Canvas):
|
|
216
216
|
elif not self.MT.ctrl_select_enabled:
|
217
217
|
self.b1_press(event)
|
218
218
|
|
219
|
-
def ctrl_shift_b1_press(self, event:
|
219
|
+
def ctrl_shift_b1_press(self, event: Any) -> None:
|
220
220
|
self.mouseclick_outside_editor_or_dropdown_all_canvases(inside=True)
|
221
221
|
x = event.x
|
222
222
|
c = self.MT.identify_col(x=x)
|
@@ -252,7 +252,7 @@ class ColumnHeaders(tk.Canvas):
|
|
252
252
|
elif not self.MT.ctrl_select_enabled:
|
253
253
|
self.shift_b1_press(event)
|
254
254
|
|
255
|
-
def shift_b1_press(self, event:
|
255
|
+
def shift_b1_press(self, event: Any) -> None:
|
256
256
|
self.mouseclick_outside_editor_or_dropdown_all_canvases(inside=True)
|
257
257
|
c = self.MT.identify_col(x=event.x)
|
258
258
|
if (
|
@@ -323,7 +323,7 @@ class ColumnHeaders(tk.Canvas):
|
|
323
323
|
if x >= x1 and y >= y1 and x <= x2 and y <= y2:
|
324
324
|
return c
|
325
325
|
|
326
|
-
def mouse_motion(self, event:
|
326
|
+
def mouse_motion(self, event: Any) -> None:
|
327
327
|
if not self.currently_resizing_height and not self.currently_resizing_width:
|
328
328
|
x = self.canvasx(event.x)
|
329
329
|
y = self.canvasy(event.y)
|
@@ -364,7 +364,7 @@ class ColumnHeaders(tk.Canvas):
|
|
364
364
|
self.MT.reset_mouse_motion_creations()
|
365
365
|
try_binding(self.extra_motion_func, event)
|
366
366
|
|
367
|
-
def double_b1(self, event:
|
367
|
+
def double_b1(self, event: Any) -> None:
|
368
368
|
self.mouseclick_outside_editor_or_dropdown_all_canvases(inside=True)
|
369
369
|
self.focus_set()
|
370
370
|
if (
|
@@ -404,7 +404,7 @@ class ColumnHeaders(tk.Canvas):
|
|
404
404
|
self.mouse_motion(event)
|
405
405
|
try_binding(self.extra_double_b1_func, event)
|
406
406
|
|
407
|
-
def b1_press(self, event:
|
407
|
+
def b1_press(self, event: Any) -> None:
|
408
408
|
self.MT.unbind("<MouseWheel>")
|
409
409
|
self.focus_set()
|
410
410
|
self.closed_dropdown = self.mouseclick_outside_editor_or_dropdown_all_canvases(inside=True)
|
@@ -465,7 +465,7 @@ class ColumnHeaders(tk.Canvas):
|
|
465
465
|
self.toggle_select_col(c, redraw=True)
|
466
466
|
try_binding(self.extra_b1_press_func, event)
|
467
467
|
|
468
|
-
def b1_motion(self, event:
|
468
|
+
def b1_motion(self, event: Any) -> None:
|
469
469
|
x1, y1, x2, y2 = self.MT.get_canvas_visible_area()
|
470
470
|
if self.width_resizing_enabled and self.rsz_w is not None and self.currently_resizing_width:
|
471
471
|
x = self.canvasx(event.x)
|
@@ -568,7 +568,7 @@ class ColumnHeaders(tk.Canvas):
|
|
568
568
|
elif end_col < start_col:
|
569
569
|
return 0, end_col, len(self.MT.row_positions) - 1, start_col + 1, "columns"
|
570
570
|
|
571
|
-
def ctrl_b1_motion(self, event:
|
571
|
+
def ctrl_b1_motion(self, event: Any) -> None:
|
572
572
|
x1, y1, x2, y2 = self.MT.get_canvas_visible_area()
|
573
573
|
if (
|
574
574
|
self.drag_and_drop_enabled
|
@@ -622,7 +622,7 @@ class ColumnHeaders(tk.Canvas):
|
|
622
622
|
elif not self.MT.ctrl_select_enabled:
|
623
623
|
self.b1_motion(event)
|
624
624
|
|
625
|
-
def drag_and_drop_motion(self, event:
|
625
|
+
def drag_and_drop_motion(self, event: Any) -> float:
|
626
626
|
x = event.x
|
627
627
|
wend = self.winfo_width()
|
628
628
|
xcheck = self.xview()
|
@@ -690,7 +690,7 @@ class ColumnHeaders(tk.Canvas):
|
|
690
690
|
if ctrl_lines:
|
691
691
|
self.MT.delete_ctrl_outlines()
|
692
692
|
|
693
|
-
def scroll_if_event_offscreen(self, event:
|
693
|
+
def scroll_if_event_offscreen(self, event: Any) -> bool:
|
694
694
|
xcheck = self.xview()
|
695
695
|
need_redraw = False
|
696
696
|
if event.x > self.winfo_width() and len(xcheck) > 1 and xcheck[1] < 1:
|
@@ -720,7 +720,7 @@ class ColumnHeaders(tk.Canvas):
|
|
720
720
|
elif len(xcheck) > 1 and xcheck[1] > 1:
|
721
721
|
self.MT.set_xviews("moveto", 1)
|
722
722
|
|
723
|
-
def event_over_dropdown(self, c: int, datacn: int, event:
|
723
|
+
def event_over_dropdown(self, c: int, datacn: int, event: Any, canvasx: float) -> bool:
|
724
724
|
return (
|
725
725
|
event.y < self.MT.header_txt_height + 5
|
726
726
|
and self.get_cell_kwargs(datacn, key="dropdown")
|
@@ -728,7 +728,7 @@ class ColumnHeaders(tk.Canvas):
|
|
728
728
|
and canvasx > self.MT.col_positions[c + 1] - self.MT.header_txt_height - 4
|
729
729
|
)
|
730
730
|
|
731
|
-
def event_over_checkbox(self, c: int, datacn: int, event:
|
731
|
+
def event_over_checkbox(self, c: int, datacn: int, event: Any, canvasx: float) -> bool:
|
732
732
|
return (
|
733
733
|
event.y < self.MT.header_txt_height + 5
|
734
734
|
and self.get_cell_kwargs(datacn, key="checkbox")
|
@@ -761,7 +761,7 @@ class ColumnHeaders(tk.Canvas):
|
|
761
761
|
)
|
762
762
|
)
|
763
763
|
|
764
|
-
def b1_release(self, event:
|
764
|
+
def b1_release(self, event: Any) -> None:
|
765
765
|
to_hide = self.being_drawn_item
|
766
766
|
if self.being_drawn_item is not None and (to_sel := self.MT.coords_and_type(self.being_drawn_item)):
|
767
767
|
r_to_sel, c_to_sel = self.MT.selected.row, self.MT.selected.column
|
@@ -1717,7 +1717,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1717
1717
|
d[box.type_ if box.type_ != "rows" else "cells"].add(c)
|
1718
1718
|
return d
|
1719
1719
|
|
1720
|
-
def open_cell(self, event:
|
1720
|
+
def open_cell(self, event: Any = None, ignore_existing_editor: bool = False) -> None:
|
1721
1721
|
if not self.MT.anything_selected() or (not ignore_existing_editor and self.text_editor.open):
|
1722
1722
|
return
|
1723
1723
|
if not self.MT.selected:
|
@@ -1747,9 +1747,9 @@ class ColumnHeaders(tk.Canvas):
|
|
1747
1747
|
# c is displayed col
|
1748
1748
|
def open_text_editor(
|
1749
1749
|
self,
|
1750
|
-
event:
|
1750
|
+
event: Any = None,
|
1751
1751
|
c: int = 0,
|
1752
|
-
text:
|
1752
|
+
text: Any = None,
|
1753
1753
|
state: str = "normal",
|
1754
1754
|
dropdown: bool = False,
|
1755
1755
|
) -> bool:
|
@@ -1863,7 +1863,7 @@ class ColumnHeaders(tk.Canvas):
|
|
1863
1863
|
self.coords(self.text_editor.canvas_id, self.MT.col_positions[c] + 1, 0)
|
1864
1864
|
|
1865
1865
|
# displayed indexes
|
1866
|
-
def text_editor_newline_binding(self, event:
|
1866
|
+
def text_editor_newline_binding(self, event: Any = None, check_lines: bool = True) -> None:
|
1867
1867
|
if not self.height_resizing_enabled:
|
1868
1868
|
return
|
1869
1869
|
curr_height = self.text_editor.window.winfo_height()
|
@@ -2050,7 +2050,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2050
2050
|
self.text_editor.autocomplete(self.dropdown.window.search_and_see(event_data))
|
2051
2051
|
return "break"
|
2052
2052
|
|
2053
|
-
def open_dropdown_window(self, c: int, event:
|
2053
|
+
def open_dropdown_window(self, c: int, event: Any = None) -> None:
|
2054
2054
|
self.hide_text_editor()
|
2055
2055
|
kwargs = self.get_cell_kwargs(self.MT.datacn(c), key="dropdown")
|
2056
2056
|
if kwargs["state"] == "disabled":
|
@@ -2120,7 +2120,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2120
2120
|
def close_dropdown_window(
|
2121
2121
|
self,
|
2122
2122
|
c: None | int = None,
|
2123
|
-
selection:
|
2123
|
+
selection: Any = None,
|
2124
2124
|
redraw: bool = True,
|
2125
2125
|
) -> None:
|
2126
2126
|
if c is not None and selection is not None:
|
@@ -2184,7 +2184,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2184
2184
|
self,
|
2185
2185
|
c: int = 0,
|
2186
2186
|
datacn: int | None = None,
|
2187
|
-
value:
|
2187
|
+
value: Any = "",
|
2188
2188
|
cell_resize: bool = True,
|
2189
2189
|
undo: bool = True,
|
2190
2190
|
redraw: bool = True,
|
@@ -2229,7 +2229,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2229
2229
|
self.MT.sheet_modified(event_data)
|
2230
2230
|
return edited
|
2231
2231
|
|
2232
|
-
def set_cell_data(self, datacn: int | None = None, value:
|
2232
|
+
def set_cell_data(self, datacn: int | None = None, value: Any = "") -> None:
|
2233
2233
|
if isinstance(self.MT._headers, int):
|
2234
2234
|
self.MT.set_cell_data(datarn=self.MT._headers, datacn=datacn, value=value)
|
2235
2235
|
else:
|
@@ -2239,7 +2239,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2239
2239
|
else:
|
2240
2240
|
self.MT._headers[datacn] = value
|
2241
2241
|
|
2242
|
-
def input_valid_for_cell(self, datacn: int, value:
|
2242
|
+
def input_valid_for_cell(self, datacn: int, value: Any, check_readonly: bool = True) -> bool:
|
2243
2243
|
kwargs = self.get_cell_kwargs(datacn, key=None)
|
2244
2244
|
if check_readonly and "readonly" in kwargs:
|
2245
2245
|
return False
|
@@ -2253,7 +2253,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2253
2253
|
and value not in kwargs["values"]
|
2254
2254
|
)
|
2255
2255
|
|
2256
|
-
def cell_equal_to(self, datacn: int, value:
|
2256
|
+
def cell_equal_to(self, datacn: int, value: Any) -> bool:
|
2257
2257
|
self.fix_header(datacn)
|
2258
2258
|
if isinstance(self.MT._headers, list):
|
2259
2259
|
return self.MT._headers[datacn] == value
|
@@ -2266,7 +2266,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2266
2266
|
get_displayed: bool = False,
|
2267
2267
|
none_to_empty_str: bool = False,
|
2268
2268
|
redirect_int: bool = False,
|
2269
|
-
) ->
|
2269
|
+
) -> Any:
|
2270
2270
|
if get_displayed:
|
2271
2271
|
return self.get_valid_cell_data_as_str(datacn, fix=False)
|
2272
2272
|
if redirect_int and isinstance(self.MT._headers, int): # internal use
|
@@ -2305,7 +2305,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2305
2305
|
value = get_n2a(datacn, self.ops.default_header)
|
2306
2306
|
return value
|
2307
2307
|
|
2308
|
-
def get_value_for_empty_cell(self, datacn: int, c_ops: bool = True) ->
|
2308
|
+
def get_value_for_empty_cell(self, datacn: int, c_ops: bool = True) -> Any:
|
2309
2309
|
kwargs = self.get_cell_kwargs(datacn, key=None, cell=c_ops)
|
2310
2310
|
if "checkbox" in kwargs:
|
2311
2311
|
return False
|
@@ -2314,7 +2314,7 @@ class ColumnHeaders(tk.Canvas):
|
|
2314
2314
|
else:
|
2315
2315
|
return ""
|
2316
2316
|
|
2317
|
-
def get_empty_header_seq(self, end: int, start: int = 0, c_ops: bool = True) -> list[
|
2317
|
+
def get_empty_header_seq(self, end: int, start: int = 0, c_ops: bool = True) -> list[Any]:
|
2318
2318
|
return [self.get_value_for_empty_cell(datacn, c_ops=c_ops) for datacn in range(start, end)]
|
2319
2319
|
|
2320
2320
|
def fix_header(self, datacn: None | int = None) -> None:
|
@@ -1,14 +1,15 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from platform import system as get_os
|
4
|
+
from typing import Hashable
|
4
5
|
|
5
6
|
USER_OS: str = f"{get_os()}".lower()
|
6
7
|
ctrl_key: str = "Command" if USER_OS == "darwin" else "Control"
|
7
8
|
rc_binding: str = "<2>" if USER_OS == "darwin" else "<3>"
|
8
9
|
symbols_set: set[str] = set("""!#$%&'()*+,-./:;"@[]^_`{|}~>?= \\""")
|
9
|
-
nonelike: set[
|
10
|
-
truthy: set[
|
11
|
-
falsy: set[
|
10
|
+
nonelike: set[Hashable] = {None, "none", ""}
|
11
|
+
truthy: set[Hashable] = {True, "true", "t", "yes", "y", "on", "1"}
|
12
|
+
falsy: set[Hashable] = {False, "false", "f", "no", "n", "off", "0"}
|
12
13
|
_test_str: str = "aiW_-|"
|
13
14
|
|
14
15
|
val_modifying_options: set[str] = {"checkbox", "format", "dropdown"}
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
import tkinter as tk
|
4
4
|
from collections.abc import Callable
|
5
|
-
from typing import Literal
|
5
|
+
from typing import Any, Literal
|
6
6
|
|
7
7
|
from .constants import ctrl_key, rc_binding
|
8
8
|
from .functions import recursive_bind
|
@@ -83,11 +83,11 @@ class FindWindowTkText(tk.Text):
|
|
83
83
|
**menu_kwargs,
|
84
84
|
)
|
85
85
|
|
86
|
-
def rc(self, event:
|
86
|
+
def rc(self, event: Any) -> None:
|
87
87
|
self.focus_set()
|
88
88
|
self.rc_popup_menu.tk_popup(event.x_root, event.y_root)
|
89
89
|
|
90
|
-
def delete_key(self, event:
|
90
|
+
def delete_key(self, event: Any = None) -> None:
|
91
91
|
if self.editor_del_key == "forward":
|
92
92
|
return
|
93
93
|
elif not self.editor_del_key:
|
@@ -100,27 +100,27 @@ class FindWindowTkText(tk.Text):
|
|
100
100
|
self.delete("insert-1c")
|
101
101
|
return "break"
|
102
102
|
|
103
|
-
def select_all(self, event:
|
103
|
+
def select_all(self, event: Any = None) -> Literal["break"]:
|
104
104
|
self.tag_add(tk.SEL, "1.0", tk.END)
|
105
105
|
self.mark_set(tk.INSERT, tk.END)
|
106
106
|
# self.see(tk.INSERT)
|
107
107
|
return "break"
|
108
108
|
|
109
|
-
def cut(self, event:
|
109
|
+
def cut(self, event: Any = None) -> Literal["break"]:
|
110
110
|
self.event_generate(f"<{ctrl_key}-x>")
|
111
111
|
self.event_generate("<KeyRelease>")
|
112
112
|
return "break"
|
113
113
|
|
114
|
-
def copy(self, event:
|
114
|
+
def copy(self, event: Any = None) -> Literal["break"]:
|
115
115
|
self.event_generate(f"<{ctrl_key}-c>")
|
116
116
|
return "break"
|
117
117
|
|
118
|
-
def paste(self, event:
|
118
|
+
def paste(self, event: Any = None) -> Literal["break"]:
|
119
119
|
self.event_generate(f"<{ctrl_key}-v>")
|
120
120
|
self.event_generate("<KeyRelease>")
|
121
121
|
return "break"
|
122
122
|
|
123
|
-
def undo(self, event:
|
123
|
+
def undo(self, event: Any = None) -> Literal["break"]:
|
124
124
|
self.event_generate(f"<{ctrl_key}-z>")
|
125
125
|
self.event_generate("<KeyRelease>")
|
126
126
|
return "break"
|
@@ -2,27 +2,28 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
from collections.abc import Callable
|
4
4
|
from contextlib import suppress
|
5
|
+
from typing import Any
|
5
6
|
|
6
7
|
from .constants import falsy, nonelike, truthy
|
7
8
|
|
8
9
|
|
9
|
-
def is_none_like(o:
|
10
|
+
def is_none_like(o: Any) -> bool:
|
10
11
|
return (isinstance(o, str) and o.lower().replace(" ", "") in nonelike) or o in nonelike
|
11
12
|
|
12
13
|
|
13
|
-
def to_int(o:
|
14
|
+
def to_int(o: Any, **kwargs) -> int:
|
14
15
|
if isinstance(o, int):
|
15
16
|
return o
|
16
17
|
return int(float(o))
|
17
18
|
|
18
19
|
|
19
|
-
def to_float(o:
|
20
|
+
def to_float(o: Any, **kwargs) -> float:
|
20
21
|
if isinstance(o, float):
|
21
22
|
return o
|
22
23
|
return float(o)
|
23
24
|
|
24
25
|
|
25
|
-
def to_percentage(o:
|
26
|
+
def to_percentage(o: Any, **kwargs) -> float:
|
26
27
|
if isinstance(o, float):
|
27
28
|
return o
|
28
29
|
if isinstance(o, str) and o.endswith("%"):
|
@@ -30,7 +31,7 @@ def to_percentage(o: object, **kwargs) -> float:
|
|
30
31
|
return float(o)
|
31
32
|
|
32
33
|
|
33
|
-
def alt_to_percentage(o:
|
34
|
+
def alt_to_percentage(o: Any, **kwargs) -> float:
|
34
35
|
if isinstance(o, float):
|
35
36
|
return o
|
36
37
|
if isinstance(o, str) and o.endswith("%"):
|
@@ -38,7 +39,7 @@ def alt_to_percentage(o: object, **kwargs) -> float:
|
|
38
39
|
return float(o)
|
39
40
|
|
40
41
|
|
41
|
-
def to_bool(val:
|
42
|
+
def to_bool(val: Any, **kwargs) -> bool:
|
42
43
|
if isinstance(val, bool):
|
43
44
|
return val
|
44
45
|
v = val.lower() if isinstance(val, str) else val
|
@@ -51,14 +52,14 @@ def to_bool(val: object, **kwargs) -> bool:
|
|
51
52
|
raise ValueError(f'Cannot map "{val}" to bool.')
|
52
53
|
|
53
54
|
|
54
|
-
def try_to_bool(o:
|
55
|
+
def try_to_bool(o: Any, **kwargs) -> Any:
|
55
56
|
try:
|
56
57
|
return to_bool(o)
|
57
58
|
except Exception:
|
58
59
|
return o
|
59
60
|
|
60
61
|
|
61
|
-
def is_bool_like(o:
|
62
|
+
def is_bool_like(o: Any, **kwargs) -> bool:
|
62
63
|
try:
|
63
64
|
to_bool(o)
|
64
65
|
return True
|
@@ -66,11 +67,11 @@ def is_bool_like(o: object, **kwargs) -> bool:
|
|
66
67
|
return False
|
67
68
|
|
68
69
|
|
69
|
-
def to_str(o:
|
70
|
+
def to_str(o: Any, **kwargs: dict) -> str:
|
70
71
|
return f"{o}"
|
71
72
|
|
72
73
|
|
73
|
-
def float_to_str(v:
|
74
|
+
def float_to_str(v: Any, **kwargs: dict) -> str:
|
74
75
|
if isinstance(v, float):
|
75
76
|
if v.is_integer():
|
76
77
|
return f"{int(v)}"
|
@@ -81,7 +82,7 @@ def float_to_str(v: object, **kwargs: dict) -> str:
|
|
81
82
|
return f"{v}"
|
82
83
|
|
83
84
|
|
84
|
-
def percentage_to_str(v:
|
85
|
+
def percentage_to_str(v: Any, **kwargs: dict) -> str:
|
85
86
|
if isinstance(v, (int, float)):
|
86
87
|
x = v * 100
|
87
88
|
if isinstance(x, float):
|
@@ -95,16 +96,16 @@ def percentage_to_str(v: object, **kwargs: dict) -> str:
|
|
95
96
|
return f"{v}%"
|
96
97
|
|
97
98
|
|
98
|
-
def alt_percentage_to_str(v:
|
99
|
+
def alt_percentage_to_str(v: Any, **kwargs: dict) -> str:
|
99
100
|
return f"{float_to_str(v)}%"
|
100
101
|
|
101
102
|
|
102
|
-
def bool_to_str(v:
|
103
|
+
def bool_to_str(v: Any, **kwargs: dict) -> str:
|
103
104
|
return f"{v}"
|
104
105
|
|
105
106
|
|
106
107
|
def int_formatter(
|
107
|
-
datatypes: tuple[
|
108
|
+
datatypes: tuple[Any] | Any = int,
|
108
109
|
format_function: Callable = to_int,
|
109
110
|
to_str_function: Callable = to_str,
|
110
111
|
**kwargs,
|
@@ -118,7 +119,7 @@ def int_formatter(
|
|
118
119
|
|
119
120
|
|
120
121
|
def float_formatter(
|
121
|
-
datatypes: tuple[
|
122
|
+
datatypes: tuple[Any] | Any = float,
|
122
123
|
format_function: Callable = to_float,
|
123
124
|
to_str_function: Callable = float_to_str,
|
124
125
|
decimals: int = 2,
|
@@ -134,7 +135,7 @@ def float_formatter(
|
|
134
135
|
|
135
136
|
|
136
137
|
def percentage_formatter(
|
137
|
-
datatypes: tuple[
|
138
|
+
datatypes: tuple[Any] | Any = float,
|
138
139
|
format_function: Callable = to_percentage,
|
139
140
|
to_str_function: Callable = percentage_to_str,
|
140
141
|
decimals: int = 2,
|
@@ -150,12 +151,12 @@ def percentage_formatter(
|
|
150
151
|
|
151
152
|
|
152
153
|
def bool_formatter(
|
153
|
-
datatypes: tuple[
|
154
|
+
datatypes: tuple[Any] | Any = bool,
|
154
155
|
format_function: Callable = to_bool,
|
155
156
|
to_str_function: Callable = bool_to_str,
|
156
|
-
invalid_value:
|
157
|
-
truthy_values: set[
|
158
|
-
falsy_values: set[
|
157
|
+
invalid_value: Any = "NA",
|
158
|
+
truthy_values: set[Any] = truthy,
|
159
|
+
falsy_values: set[Any] = falsy,
|
159
160
|
**kwargs,
|
160
161
|
) -> dict:
|
161
162
|
return formatter(
|
@@ -170,10 +171,10 @@ def bool_formatter(
|
|
170
171
|
|
171
172
|
|
172
173
|
def formatter(
|
173
|
-
datatypes: tuple[
|
174
|
+
datatypes: tuple[Any] | Any,
|
174
175
|
format_function: Callable,
|
175
176
|
to_str_function: Callable = to_str,
|
176
|
-
invalid_value:
|
177
|
+
invalid_value: Any = "NaN",
|
177
178
|
nullable: bool = True,
|
178
179
|
pre_format_function: Callable | None = None,
|
179
180
|
post_format_function: Callable | None = None,
|
@@ -196,14 +197,14 @@ def formatter(
|
|
196
197
|
|
197
198
|
|
198
199
|
def format_data(
|
199
|
-
value:
|
200
|
-
datatypes: tuple[
|
200
|
+
value: Any = "",
|
201
|
+
datatypes: tuple[Any] | Any = int,
|
201
202
|
nullable: bool = True,
|
202
203
|
pre_format_function: Callable | None = None,
|
203
204
|
format_function: Callable | None = to_int,
|
204
205
|
post_format_function: Callable | None = None,
|
205
206
|
**kwargs,
|
206
|
-
) ->
|
207
|
+
) -> Any:
|
207
208
|
if pre_format_function:
|
208
209
|
value = pre_format_function(value)
|
209
210
|
if nullable and is_none_like(value):
|
@@ -217,10 +218,10 @@ def format_data(
|
|
217
218
|
|
218
219
|
|
219
220
|
def data_to_str(
|
220
|
-
value:
|
221
|
-
datatypes: tuple[
|
221
|
+
value: Any = "",
|
222
|
+
datatypes: tuple[Any] | Any = int,
|
222
223
|
nullable: bool = True,
|
223
|
-
invalid_value:
|
224
|
+
invalid_value: Any = "NaN",
|
224
225
|
to_str_function: Callable | None = None,
|
225
226
|
**kwargs,
|
226
227
|
) -> str:
|
@@ -231,13 +232,13 @@ def data_to_str(
|
|
231
232
|
return to_str_function(value, **kwargs)
|
232
233
|
|
233
234
|
|
234
|
-
def get_data_with_valid_check(value="", datatypes: tuple[()] | tuple[
|
235
|
+
def get_data_with_valid_check(value="", datatypes: tuple[()] | tuple[Any] | Any = (), invalid_value="NA"):
|
235
236
|
if isinstance(value, datatypes):
|
236
237
|
return value
|
237
238
|
return invalid_value
|
238
239
|
|
239
240
|
|
240
|
-
def get_clipboard_data(value:
|
241
|
+
def get_clipboard_data(value: Any = "", clipboard_function: Callable | None = None, **kwargs: dict) -> Any:
|
241
242
|
if clipboard_function is not None:
|
242
243
|
return clipboard_function(value, **kwargs)
|
243
244
|
if isinstance(value, (str, int, float, bool)):
|
@@ -248,9 +249,8 @@ def get_clipboard_data(value: object = "", clipboard_function: Callable | None =
|
|
248
249
|
class Formatter:
|
249
250
|
def __init__(
|
250
251
|
self,
|
251
|
-
value:
|
252
|
-
datatypes: tuple[
|
253
|
-
object=int,
|
252
|
+
value: Any,
|
253
|
+
datatypes: tuple[Any],
|
254
254
|
format_function: Callable = to_int,
|
255
255
|
to_str_function: Callable = to_str,
|
256
256
|
nullable: bool = True,
|
@@ -281,19 +281,19 @@ class Formatter:
|
|
281
281
|
except Exception:
|
282
282
|
self.value = f"{value}"
|
283
283
|
|
284
|
-
def __str__(self) ->
|
284
|
+
def __str__(self) -> Any:
|
285
285
|
if not self.valid():
|
286
286
|
return self.invalid_value
|
287
287
|
if self.value is None and self.nullable:
|
288
288
|
return ""
|
289
289
|
return self.to_str_function(self.value, **self.kwargs)
|
290
290
|
|
291
|
-
def valid(self, value:
|
291
|
+
def valid(self, value: Any = None) -> bool:
|
292
292
|
if value is None:
|
293
293
|
value = self.value
|
294
294
|
return isinstance(value, self.valid_datatypes)
|
295
295
|
|
296
|
-
def format_data(self, value:
|
296
|
+
def format_data(self, value: Any) -> Any:
|
297
297
|
if self.pre_format_function:
|
298
298
|
value = self.pre_format_function(value)
|
299
299
|
value = None if (self.nullable and is_none_like(value)) else self.format_function(value, **self.kwargs)
|
@@ -301,19 +301,19 @@ class Formatter:
|
|
301
301
|
value = self.post_format_function(value)
|
302
302
|
return value
|
303
303
|
|
304
|
-
def get_data_with_valid_check(self) ->
|
304
|
+
def get_data_with_valid_check(self) -> Any:
|
305
305
|
if self.valid():
|
306
306
|
return self.value
|
307
307
|
return self.invalid_value
|
308
308
|
|
309
|
-
def get_clipboard_data(self) ->
|
309
|
+
def get_clipboard_data(self) -> Any:
|
310
310
|
if self.clipboard_function is not None:
|
311
311
|
return self.clipboard_function(self.value, **self.kwargs)
|
312
312
|
if isinstance(self.value, (int, float, bool)):
|
313
313
|
return self.value
|
314
314
|
return self.__str__()
|
315
315
|
|
316
|
-
def __eq__(self, __value:
|
316
|
+
def __eq__(self, __value: Any) -> bool:
|
317
317
|
# in case of custom formatter class
|
318
318
|
# compare the values
|
319
319
|
try:
|