1
0
mirror of https://github.com/arsenetar/dupeguru.git synced 2026-01-22 14:41:39 +00:00

Additional type hints in hscommon

This commit is contained in:
2022-05-11 00:50:34 -05:00
parent 7865e4aeac
commit d5eeab4a17
6 changed files with 133 additions and 111 deletions

View File

@@ -7,8 +7,10 @@
# http://www.gnu.org/licenses/gpl-3.0.html
import copy
from typing import Any, List, Tuple, Union
from hscommon.gui.base import GUIObject
from hscommon.gui.table import GUITable
class Column:
@@ -17,7 +19,7 @@ class Column:
These attributes are then used to correctly configure the column on the "view" side.
"""
def __init__(self, name, display="", visible=True, optional=False):
def __init__(self, name: str, display: str = "", visible: bool = True, optional: bool = False) -> None:
#: "programmatical" (not for display) name. Used as a reference in a couple of place, such
#: as :meth:`Columns.column_by_name`.
self.name = name
@@ -52,14 +54,14 @@ class ColumnsView:
callbacks.
"""
def restore_columns(self):
def restore_columns(self) -> None:
"""Update all columns according to the model.
When this is called, our view has to update the columns title, order and visibility of all
columns.
"""
def set_column_visible(self, colname, visible):
def set_column_visible(self, colname: str, visible: bool) -> None:
"""Update visibility of column ``colname``.
Called when the user toggles the visibility of a column, we must update the column
@@ -73,13 +75,13 @@ class PrefAccessInterface:
*Not actually used in the code. For documentation purposes only.*
"""
def get_default(self, key, fallback_value):
def get_default(self, key: str, fallback_value: Union[Any, None]) -> Any:
"""Retrieve the value for ``key`` in the currently running app's preference store.
If the key doesn't exist, return ``fallback_value``.
"""
def set_default(self, key, value):
def set_default(self, key: str, value: Any) -> None:
"""Set the value ``value`` for ``key`` in the currently running app's preference store."""
@@ -104,65 +106,65 @@ class Columns(GUIObject):
have that same prefix.
"""
def __init__(self, table, prefaccess=None, savename=None):
def __init__(self, table: GUITable, prefaccess=None, savename: Union[str, None] = None):
GUIObject.__init__(self)
self.table = table
self.prefaccess = prefaccess
self.savename = savename
# We use copy here for test isolation. If we don't, changing a column affects all tests.
self.column_list = list(map(copy.copy, table.COLUMNS))
self.column_list: List[Column] = list(map(copy.copy, table.COLUMNS))
for i, column in enumerate(self.column_list):
column.logical_index = i
column.ordered_index = i
self.coldata = {col.name: col for col in self.column_list}
# --- Private
def _get_colname_attr(self, colname, attrname, default):
def _get_colname_attr(self, colname: str, attrname: str, default: Any) -> Any:
try:
return getattr(self.coldata[colname], attrname)
except KeyError:
return default
def _set_colname_attr(self, colname, attrname, value):
def _set_colname_attr(self, colname: str, attrname: str, value: Any) -> None:
try:
col = self.coldata[colname]
setattr(col, attrname, value)
except KeyError:
pass
def _optional_columns(self):
def _optional_columns(self) -> List[Column]:
return [c for c in self.column_list if c.optional]
# --- Override
def _view_updated(self):
def _view_updated(self) -> None:
self.restore_columns()
# --- Public
def column_by_index(self, index):
def column_by_index(self, index: int):
"""Return the :class:`Column` having the :attr:`~Column.logical_index` ``index``."""
return self.column_list[index]
def column_by_name(self, name):
def column_by_name(self, name: str):
"""Return the :class:`Column` having the :attr:`~Column.name` ``name``."""
return self.coldata[name]
def columns_count(self):
def columns_count(self) -> int:
"""Returns the number of columns in our set."""
return len(self.column_list)
def column_display(self, colname):
def column_display(self, colname: str) -> str:
"""Returns display name for column named ``colname``, or ``''`` if there's none."""
return self._get_colname_attr(colname, "display", "")
def column_is_visible(self, colname):
def column_is_visible(self, colname: str) -> bool:
"""Returns visibility for column named ``colname``, or ``True`` if there's none."""
return self._get_colname_attr(colname, "visible", True)
def column_width(self, colname):
def column_width(self, colname: str) -> int:
"""Returns width for column named ``colname``, or ``0`` if there's none."""
return self._get_colname_attr(colname, "width", 0)
def columns_to_right(self, colname):
def columns_to_right(self, colname: str) -> List[str]:
"""Returns the list of all columns to the right of ``colname``.
"right" meaning "having a higher :attr:`Column.ordered_index`" in our left-to-right
@@ -172,7 +174,7 @@ class Columns(GUIObject):
index = column.ordered_index
return [col.name for col in self.column_list if (col.visible and col.ordered_index > index)]
def menu_items(self):
def menu_items(self) -> List[Tuple[str, bool]]:
"""Returns a list of items convenient for quick visibility menu generation.
Returns a list of ``(display_name, is_marked)`` items for each optional column in the
@@ -184,7 +186,7 @@ class Columns(GUIObject):
"""
return [(c.display, c.visible) for c in self._optional_columns()]
def move_column(self, colname, index):
def move_column(self, colname: str, index: int) -> None:
"""Moves column ``colname`` to ``index``.
The column will be placed just in front of the column currently having that index, or to the
@@ -195,7 +197,7 @@ class Columns(GUIObject):
colnames.insert(index, colname)
self.set_column_order(colnames)
def reset_to_defaults(self):
def reset_to_defaults(self) -> None:
"""Reset all columns' width and visibility to their default values."""
self.set_column_order([col.name for col in self.column_list])
for col in self._optional_columns():
@@ -203,11 +205,11 @@ class Columns(GUIObject):
col.width = col.default_width
self.view.restore_columns()
def resize_column(self, colname, newwidth):
def resize_column(self, colname: str, newwidth: int) -> None:
"""Set column ``colname``'s width to ``newwidth``."""
self._set_colname_attr(colname, "width", newwidth)
def restore_columns(self):
def restore_columns(self) -> None:
"""Restore's column persistent attributes from the last :meth:`save_columns`."""
if not (self.prefaccess and self.savename and self.coldata):
if (not self.savename) and (self.coldata):
@@ -226,7 +228,7 @@ class Columns(GUIObject):
col.visible = coldata["visible"]
self.view.restore_columns()
def save_columns(self):
def save_columns(self) -> None:
"""Save column attributes in persistent storage for restoration in :meth:`restore_columns`."""
if not (self.prefaccess and self.savename and self.coldata):
return
@@ -237,7 +239,8 @@ class Columns(GUIObject):
coldata["visible"] = col.visible
self.prefaccess.set_default(pref_name, coldata)
def set_column_order(self, colnames):
# TODO annotate colnames
def set_column_order(self, colnames) -> None:
"""Change the columns order so it matches the order in ``colnames``.
:param colnames: A list of column names in the desired order.
@@ -247,17 +250,17 @@ class Columns(GUIObject):
col = self.coldata[colname]
col.ordered_index = i
def set_column_visible(self, colname, visible):
def set_column_visible(self, colname: str, visible: bool) -> None:
"""Set the visibility of column ``colname``."""
self.table.save_edits() # the table on the GUI side will stop editing when the columns change
self._set_colname_attr(colname, "visible", visible)
self.view.set_column_visible(colname, visible)
def set_default_width(self, colname, width):
def set_default_width(self, colname: str, width: int) -> None:
"""Set the default width or column ``colname``."""
self._set_colname_attr(colname, "default_width", width)
def toggle_menu_item(self, index):
def toggle_menu_item(self, index: int) -> bool:
"""Toggles the visibility of an optional column.
You know, that optional column menu you've generated in :meth:`menu_items`? Well, ``index``
@@ -271,11 +274,11 @@ class Columns(GUIObject):
# --- Properties
@property
def ordered_columns(self):
def ordered_columns(self) -> List[Column]:
"""List of :class:`Column` in visible order."""
return [col for col in sorted(self.column_list, key=lambda col: col.ordered_index)]
@property
def colnames(self):
def colnames(self) -> List[str]:
"""List of column names in visible order."""
return [col.name for col in self.ordered_columns]