From e7351b594d81365c35aac0e065576eaddb445424 Mon Sep 17 00:00:00 2001 From: Blake Harnden <32446120+bharnden@users.noreply.github.com> Date: Thu, 13 Apr 2023 15:53:16 -0700 Subject: [PATCH] gui: updated core.gui to not use deprecated type hinting --- daemon/core/gui/app.py | 6 +- daemon/core/gui/appconfig.py | 44 +++++++------- daemon/core/gui/coreclient.py | 59 ++++++++++--------- daemon/core/gui/dialogs/alerts.py | 4 +- daemon/core/gui/dialogs/canvaswallpaper.py | 4 +- daemon/core/gui/dialogs/colorpicker.py | 32 ++++++---- .../core/gui/dialogs/configserviceconfig.py | 40 ++++++------- daemon/core/gui/dialogs/copyserviceconfig.py | 4 +- daemon/core/gui/dialogs/customnodes.py | 8 +-- daemon/core/gui/dialogs/emaneconfig.py | 6 +- daemon/core/gui/dialogs/ipdialog.py | 6 +- daemon/core/gui/dialogs/mobilityconfig.py | 4 +- daemon/core/gui/dialogs/nodeconfig.py | 4 +- daemon/core/gui/dialogs/nodeconfigservice.py | 6 +- daemon/core/gui/dialogs/nodeservice.py | 4 +- daemon/core/gui/dialogs/runtool.py | 4 +- daemon/core/gui/dialogs/serviceconfig.py | 34 +++++------ daemon/core/gui/dialogs/sessions.py | 4 +- daemon/core/gui/dialogs/shapemod.py | 8 +-- daemon/core/gui/dialogs/wirelessconfig.py | 6 +- daemon/core/gui/dialogs/wlanconfig.py | 6 +- daemon/core/gui/graph/edges.py | 16 ++--- daemon/core/gui/graph/graph.py | 48 +++++++-------- daemon/core/gui/graph/manager.py | 27 +++++---- daemon/core/gui/graph/node.py | 16 ++--- daemon/core/gui/graph/shape.py | 8 +-- daemon/core/gui/graph/shapeutils.py | 3 +- daemon/core/gui/graph/tags.py | 6 +- daemon/core/gui/graph/tooltip.py | 10 ++-- daemon/core/gui/images.py | 6 +- daemon/core/gui/interface.py | 16 ++--- daemon/core/gui/nodeutils.py | 28 ++++----- daemon/core/gui/observers.py | 4 +- daemon/core/gui/statusbar.py | 4 +- daemon/core/gui/task.py | 6 +- daemon/core/gui/themes.py | 7 +-- daemon/core/gui/toolbar.py | 6 +- daemon/core/gui/tooltip.py | 2 +- daemon/core/gui/validation.py | 3 +- daemon/core/gui/widgets.py | 16 ++--- 40 files changed, 268 insertions(+), 257 deletions(-) diff --git a/daemon/core/gui/app.py b/daemon/core/gui/app.py index d905bff3..4fd1dce5 100644 --- a/daemon/core/gui/app.py +++ b/daemon/core/gui/app.py @@ -3,7 +3,7 @@ import math import tkinter as tk from tkinter import PhotoImage, font, messagebox, ttk from tkinter.ttk import Progressbar -from typing import Any, Dict, Optional, Type +from typing import Any, Optional import grpc @@ -45,7 +45,7 @@ class Application(ttk.Frame): self.show_infobar: tk.BooleanVar = tk.BooleanVar(value=False) # fonts - self.fonts_size: Dict[str, int] = {} + self.fonts_size: dict[str, int] = {} self.icon_text_font: Optional[font.Font] = None self.edge_font: Optional[font.Font] = None @@ -145,7 +145,7 @@ class Application(ttk.Frame): self.statusbar = StatusBar(self.right_frame, self) self.statusbar.grid(sticky=tk.EW, columnspan=2) - def display_info(self, frame_class: Type[InfoFrameBase], **kwargs: Any) -> None: + def display_info(self, frame_class: type[InfoFrameBase], **kwargs: Any) -> None: if not self.show_infobar.get(): return self.clear_info() diff --git a/daemon/core/gui/appconfig.py b/daemon/core/gui/appconfig.py index 04f2fdcb..0a5ae76b 100644 --- a/daemon/core/gui/appconfig.py +++ b/daemon/core/gui/appconfig.py @@ -1,7 +1,7 @@ import os import shutil from pathlib import Path -from typing import Dict, List, Optional, Type +from typing import Optional import yaml @@ -26,7 +26,7 @@ LOCAL_XMLS_PATH: Path = DATA_PATH.joinpath("xmls").absolute() LOCAL_MOBILITY_PATH: Path = DATA_PATH.joinpath("mobility").absolute() # configuration data -TERMINALS: Dict[str, str] = { +TERMINALS: dict[str, str] = { "xterm": "xterm -e", "aterm": "aterm -e", "eterm": "eterm -e", @@ -36,7 +36,7 @@ TERMINALS: Dict[str, str] = { "xfce4-terminal": "xfce4-terminal -x", "gnome-terminal": "gnome-terminal --window --", } -EDITORS: List[str] = ["$EDITOR", "vim", "emacs", "gedit", "nano", "vi"] +EDITORS: list[str] = ["$EDITOR", "vim", "emacs", "gedit", "nano", "vi"] class IndentDumper(yaml.Dumper): @@ -46,17 +46,17 @@ class IndentDumper(yaml.Dumper): class CustomNode(yaml.YAMLObject): yaml_tag: str = "!CustomNode" - yaml_loader: Type[yaml.SafeLoader] = yaml.SafeLoader + yaml_loader: type[yaml.SafeLoader] = yaml.SafeLoader - def __init__(self, name: str, image: str, services: List[str]) -> None: + def __init__(self, name: str, image: str, services: list[str]) -> None: self.name: str = name self.image: str = image - self.services: List[str] = services + self.services: list[str] = services class CoreServer(yaml.YAMLObject): yaml_tag: str = "!CoreServer" - yaml_loader: Type[yaml.SafeLoader] = yaml.SafeLoader + yaml_loader: type[yaml.SafeLoader] = yaml.SafeLoader def __init__(self, name: str, address: str) -> None: self.name: str = name @@ -65,7 +65,7 @@ class CoreServer(yaml.YAMLObject): class Observer(yaml.YAMLObject): yaml_tag: str = "!Observer" - yaml_loader: Type[yaml.SafeLoader] = yaml.SafeLoader + yaml_loader: type[yaml.SafeLoader] = yaml.SafeLoader def __init__(self, name: str, cmd: str) -> None: self.name: str = name @@ -74,7 +74,7 @@ class Observer(yaml.YAMLObject): class PreferencesConfig(yaml.YAMLObject): yaml_tag: str = "!PreferencesConfig" - yaml_loader: Type[yaml.SafeLoader] = yaml.SafeLoader + yaml_loader: type[yaml.SafeLoader] = yaml.SafeLoader def __init__( self, @@ -95,7 +95,7 @@ class PreferencesConfig(yaml.YAMLObject): class LocationConfig(yaml.YAMLObject): yaml_tag: str = "!LocationConfig" - yaml_loader: Type[yaml.SafeLoader] = yaml.SafeLoader + yaml_loader: type[yaml.SafeLoader] = yaml.SafeLoader def __init__( self, @@ -118,17 +118,17 @@ class LocationConfig(yaml.YAMLObject): class IpConfigs(yaml.YAMLObject): yaml_tag: str = "!IpConfigs" - yaml_loader: Type[yaml.SafeLoader] = yaml.SafeLoader + yaml_loader: type[yaml.SafeLoader] = yaml.SafeLoader def __init__(self, **kwargs) -> None: self.__setstate__(kwargs) def __setstate__(self, kwargs): - self.ip4s: List[str] = kwargs.get( + self.ip4s: list[str] = kwargs.get( "ip4s", ["10.0.0.0", "192.168.0.0", "172.16.0.0"] ) self.ip4: str = kwargs.get("ip4", self.ip4s[0]) - self.ip6s: List[str] = kwargs.get("ip6s", ["2001::", "2002::", "a::"]) + self.ip6s: list[str] = kwargs.get("ip6s", ["2001::", "2002::", "a::"]) self.ip6: str = kwargs.get("ip6", self.ip6s[0]) self.enable_ip4: bool = kwargs.get("enable_ip4", True) self.enable_ip6: bool = kwargs.get("enable_ip6", True) @@ -136,16 +136,16 @@ class IpConfigs(yaml.YAMLObject): class GuiConfig(yaml.YAMLObject): yaml_tag: str = "!GuiConfig" - yaml_loader: Type[yaml.SafeLoader] = yaml.SafeLoader + yaml_loader: type[yaml.SafeLoader] = yaml.SafeLoader def __init__( self, preferences: PreferencesConfig = None, location: LocationConfig = None, - servers: List[CoreServer] = None, - nodes: List[CustomNode] = None, - recentfiles: List[str] = None, - observers: List[Observer] = None, + servers: list[CoreServer] = None, + nodes: list[CustomNode] = None, + recentfiles: list[str] = None, + observers: list[Observer] = None, scale: float = 1.0, ips: IpConfigs = None, mac: str = "00:00:00:aa:00:00", @@ -158,16 +158,16 @@ class GuiConfig(yaml.YAMLObject): self.location: LocationConfig = location if servers is None: servers = [] - self.servers: List[CoreServer] = servers + self.servers: list[CoreServer] = servers if nodes is None: nodes = [] - self.nodes: List[CustomNode] = nodes + self.nodes: list[CustomNode] = nodes if recentfiles is None: recentfiles = [] - self.recentfiles: List[str] = recentfiles + self.recentfiles: list[str] = recentfiles if observers is None: observers = [] - self.observers: List[Observer] = observers + self.observers: list[Observer] = observers self.scale: float = scale if ips is None: ips = IpConfigs() diff --git a/daemon/core/gui/coreclient.py b/daemon/core/gui/coreclient.py index cd33aeca..5bebe77e 100644 --- a/daemon/core/gui/coreclient.py +++ b/daemon/core/gui/coreclient.py @@ -6,9 +6,10 @@ import json import logging import os import tkinter as tk +from collections.abc import Iterable from pathlib import Path from tkinter import messagebox -from typing import TYPE_CHECKING, Dict, Iterable, List, Optional, Set, Tuple +from typing import TYPE_CHECKING, Optional import grpc @@ -55,7 +56,7 @@ GUI_SOURCE = "gui" CPU_USAGE_DELAY = 3 -def to_dict(config: Dict[str, ConfigOption]) -> Dict[str, str]: +def to_dict(config: dict[str, ConfigOption]) -> dict[str, str]: return {x: y.value for x, y in config.items()} @@ -74,26 +75,26 @@ class CoreClient: self.show_throughputs: tk.BooleanVar = tk.BooleanVar(value=False) # global service settings - self.services: Dict[str, Set[str]] = {} - self.config_services_groups: Dict[str, Set[str]] = {} - self.config_services: Dict[str, ConfigService] = {} + self.services: dict[str, set[str]] = {} + self.config_services_groups: dict[str, set[str]] = {} + self.config_services: dict[str, ConfigService] = {} # loaded configuration data - self.emane_models: List[str] = [] - self.servers: Dict[str, CoreServer] = {} - self.custom_nodes: Dict[str, NodeDraw] = {} - self.custom_observers: Dict[str, Observer] = {} + self.emane_models: list[str] = [] + self.servers: dict[str, CoreServer] = {} + self.custom_nodes: dict[str, NodeDraw] = {} + self.custom_observers: dict[str, Observer] = {} self.read_config() # helpers - self.iface_to_edge: Dict[Tuple[int, ...], CanvasEdge] = {} + self.iface_to_edge: dict[tuple[int, ...], CanvasEdge] = {} self.ifaces_manager: InterfaceManager = InterfaceManager(self.app) self.observer: Optional[str] = None # session data - self.mobility_players: Dict[int, MobilityPlayer] = {} - self.canvas_nodes: Dict[int, CanvasNode] = {} - self.links: Dict[str, CanvasEdge] = {} + self.mobility_players: dict[int, MobilityPlayer] = {} + self.canvas_nodes: dict[int, CanvasNode] = {} + self.links: dict[str, CanvasEdge] = {} self.handling_throughputs: Optional[grpc.Future] = None self.handling_cpu_usage: Optional[grpc.Future] = None self.handling_events: Optional[grpc.Future] = None @@ -372,7 +373,7 @@ class CoreClient: # existing session sessions = self.client.get_sessions() if session_id: - session_ids = set(x.id for x in sessions) + session_ids = {x.id for x in sessions} if session_id not in session_ids: self.app.show_error( "Join Session Error", @@ -401,7 +402,7 @@ class CoreClient: except grpc.RpcError as e: self.app.show_grpc_exception("Edit Node Error", e) - def get_links(self, definition: bool = False) -> List[Link]: + def get_links(self, definition: bool = False) -> list[Link]: if not definition: self.ifaces_manager.set_macs([x.link for x in self.links.values()]) links = [] @@ -419,7 +420,7 @@ class CoreClient: links.append(edge.asymmetric_link) return links - def start_session(self, definition: bool = False) -> Tuple[bool, List[str]]: + def start_session(self, definition: bool = False) -> tuple[bool, list[str]]: self.session.links = self.get_links(definition) self.session.metadata = self.get_metadata() self.session.servers.clear() @@ -461,7 +462,7 @@ class CoreClient: self.mobility_players[node.id] = mobility_player mobility_player.show() - def get_metadata(self) -> Dict[str, str]: + def get_metadata(self) -> dict[str, str]: # create canvas data canvas_config = self.app.manager.get_metadata() canvas_config = json.dumps(canvas_config) @@ -652,7 +653,7 @@ class CoreClient: self.session.nodes[node.id] = node return node - def deleted_canvas_nodes(self, canvas_nodes: List[CanvasNode]) -> None: + def deleted_canvas_nodes(self, canvas_nodes: list[CanvasNode]) -> None: """ remove the nodes selected by the user and anything related to that node such as link, configurations, interfaces @@ -680,7 +681,7 @@ class CoreClient: dst_iface_id = edge.link.iface2.id self.iface_to_edge[(dst_node.id, dst_iface_id)] = edge - def get_wlan_configs(self) -> List[Tuple[int, Dict[str, str]]]: + def get_wlan_configs(self) -> list[tuple[int, dict[str, str]]]: configs = [] for node in self.session.nodes.values(): if node.type != NodeType.WIRELESS_LAN: @@ -691,7 +692,7 @@ class CoreClient: configs.append((node.id, config)) return configs - def get_mobility_configs(self) -> List[Tuple[int, Dict[str, str]]]: + def get_mobility_configs(self) -> list[tuple[int, dict[str, str]]]: configs = [] for node in self.session.nodes.values(): if not nutils.is_mobility(node): @@ -702,7 +703,7 @@ class CoreClient: configs.append((node.id, config)) return configs - def get_emane_model_configs(self) -> List[EmaneModelConfig]: + def get_emane_model_configs(self) -> list[EmaneModelConfig]: configs = [] for node in self.session.nodes.values(): for key, config in node.emane_model_configs.items(): @@ -716,7 +717,7 @@ class CoreClient: configs.append(config) return configs - def get_service_configs(self) -> List[ServiceConfig]: + def get_service_configs(self) -> list[ServiceConfig]: configs = [] for node in self.session.nodes.values(): if not nutils.is_container(node): @@ -736,7 +737,7 @@ class CoreClient: configs.append(config) return configs - def get_service_file_configs(self) -> List[ServiceFileConfig]: + def get_service_file_configs(self) -> list[ServiceFileConfig]: configs = [] for node in self.session.nodes.values(): if not nutils.is_container(node): @@ -749,12 +750,12 @@ class CoreClient: configs.append(config) return configs - def get_config_service_rendered(self, node_id: int, name: str) -> Dict[str, str]: + def get_config_service_rendered(self, node_id: int, name: str) -> dict[str, str]: return self.client.get_config_service_rendered(self.session.id, node_id, name) def get_config_service_configs_proto( self, - ) -> List[configservices_pb2.ConfigServiceConfig]: + ) -> list[configservices_pb2.ConfigServiceConfig]: config_service_protos = [] for node in self.session.nodes.values(): if not nutils.is_container(node): @@ -776,7 +777,7 @@ class CoreClient: _, output = self.client.node_command(self.session.id, node_id, self.observer) return output - def get_wlan_config(self, node_id: int) -> Dict[str, ConfigOption]: + def get_wlan_config(self, node_id: int) -> dict[str, ConfigOption]: config = self.client.get_wlan_config(self.session.id, node_id) logger.debug( "get wlan configuration from node %s, result configuration: %s", @@ -785,10 +786,10 @@ class CoreClient: ) return config - def get_wireless_config(self, node_id: int) -> Dict[str, ConfigOption]: + def get_wireless_config(self, node_id: int) -> dict[str, ConfigOption]: return self.client.get_wireless_config(self.session.id, node_id) - def get_mobility_config(self, node_id: int) -> Dict[str, ConfigOption]: + def get_mobility_config(self, node_id: int) -> dict[str, ConfigOption]: config = self.client.get_mobility_config(self.session.id, node_id) logger.debug( "get mobility config from node %s, result configuration: %s", @@ -799,7 +800,7 @@ class CoreClient: def get_emane_model_config( self, node_id: int, model: str, iface_id: int = None - ) -> Dict[str, ConfigOption]: + ) -> dict[str, ConfigOption]: if iface_id is None: iface_id = -1 config = self.client.get_emane_model_config( diff --git a/daemon/core/gui/dialogs/alerts.py b/daemon/core/gui/dialogs/alerts.py index 9e430214..b13f0797 100644 --- a/daemon/core/gui/dialogs/alerts.py +++ b/daemon/core/gui/dialogs/alerts.py @@ -3,7 +3,7 @@ check engine light """ import tkinter as tk from tkinter import ttk -from typing import TYPE_CHECKING, Dict, Optional +from typing import TYPE_CHECKING, Optional from core.api.grpc.wrappers import ExceptionEvent, ExceptionLevel from core.gui.dialogs.dialog import Dialog @@ -19,7 +19,7 @@ class AlertsDialog(Dialog): super().__init__(app, "Alerts") self.tree: Optional[ttk.Treeview] = None self.codetext: Optional[CodeText] = None - self.alarm_map: Dict[int, ExceptionEvent] = {} + self.alarm_map: dict[int, ExceptionEvent] = {} self.draw() def draw(self) -> None: diff --git a/daemon/core/gui/dialogs/canvaswallpaper.py b/daemon/core/gui/dialogs/canvaswallpaper.py index 0ef294c7..5b0f27b3 100644 --- a/daemon/core/gui/dialogs/canvaswallpaper.py +++ b/daemon/core/gui/dialogs/canvaswallpaper.py @@ -4,7 +4,7 @@ set wallpaper import logging import tkinter as tk from tkinter import ttk -from typing import TYPE_CHECKING, List, Optional +from typing import TYPE_CHECKING, Optional from core.gui import images from core.gui.appconfig import BACKGROUNDS_PATH @@ -32,7 +32,7 @@ class CanvasWallpaperDialog(Dialog): ) self.filename: tk.StringVar = tk.StringVar(value=self.canvas.wallpaper_file) self.image_label: Optional[ttk.Label] = None - self.options: List[ttk.Radiobutton] = [] + self.options: list[ttk.Radiobutton] = [] self.draw() def draw(self) -> None: diff --git a/daemon/core/gui/dialogs/colorpicker.py b/daemon/core/gui/dialogs/colorpicker.py index a2f131d4..2f1c629f 100644 --- a/daemon/core/gui/dialogs/colorpicker.py +++ b/daemon/core/gui/dialogs/colorpicker.py @@ -3,7 +3,7 @@ custom color picker """ import tkinter as tk from tkinter import ttk -from typing import TYPE_CHECKING, Optional, Tuple +from typing import TYPE_CHECKING, Optional from core.gui import validation from core.gui.dialogs.dialog import Dialog @@ -66,7 +66,9 @@ class ColorPickerDialog(Dialog): ) scale.grid(row=0, column=2, sticky=tk.EW, padx=PADX) self.red_label = ttk.Label( - frame, background="#%02x%02x%02x" % (self.red.get(), 0, 0), width=5 + frame, + background="#{:02x}{:02x}{:02x}".format(self.red.get(), 0, 0), + width=5, ) self.red_label.grid(row=0, column=3, sticky=tk.EW) @@ -89,7 +91,9 @@ class ColorPickerDialog(Dialog): ) scale.grid(row=0, column=2, sticky=tk.EW, padx=PADX) self.green_label = ttk.Label( - frame, background="#%02x%02x%02x" % (0, self.green.get(), 0), width=5 + frame, + background="#{:02x}{:02x}{:02x}".format(0, self.green.get(), 0), + width=5, ) self.green_label.grid(row=0, column=3, sticky=tk.EW) @@ -112,7 +116,9 @@ class ColorPickerDialog(Dialog): ) scale.grid(row=0, column=2, sticky=tk.EW, padx=PADX) self.blue_label = ttk.Label( - frame, background="#%02x%02x%02x" % (0, 0, self.blue.get()), width=5 + frame, + background="#{:02x}{:02x}{:02x}".format(0, 0, self.blue.get()), + width=5, ) self.blue_label.grid(row=0, column=3, sticky=tk.EW) @@ -157,7 +163,7 @@ class ColorPickerDialog(Dialog): red = self.red_entry.get() blue = self.blue_entry.get() green = self.green_entry.get() - return "#%02x%02x%02x" % (int(red), int(green), int(blue)) + return "#{:02x}{:02x}{:02x}".format(int(red), int(green), int(blue)) def current_focus(self, focus: str) -> None: self.focus = focus @@ -169,7 +175,7 @@ class ColorPickerDialog(Dialog): green = self.green_entry.get() self.set_scale(red, green, blue) if red and blue and green: - hex_code = "#%02x%02x%02x" % (int(red), int(green), int(blue)) + hex_code = "#{:02x}{:02x}{:02x}".format(int(red), int(green), int(blue)) self.hex.set(hex_code) self.display.config(background=hex_code) self.set_label(red, green, blue) @@ -200,11 +206,17 @@ class ColorPickerDialog(Dialog): self.blue.set(blue) def set_label(self, red: str, green: str, blue: str) -> None: - self.red_label.configure(background="#%02x%02x%02x" % (int(red), 0, 0)) - self.green_label.configure(background="#%02x%02x%02x" % (0, int(green), 0)) - self.blue_label.configure(background="#%02x%02x%02x" % (0, 0, int(blue))) + self.red_label.configure( + background="#{:02x}{:02x}{:02x}".format(int(red), 0, 0) + ) + self.green_label.configure( + background="#{:02x}{:02x}{:02x}".format(0, int(green), 0) + ) + self.blue_label.configure( + background="#{:02x}{:02x}{:02x}".format(0, 0, int(blue)) + ) - def get_rgb(self, hex_code: str) -> Tuple[int, int, int]: + def get_rgb(self, hex_code: str) -> tuple[int, int, int]: """ convert a valid hex code to RGB values """ diff --git a/daemon/core/gui/dialogs/configserviceconfig.py b/daemon/core/gui/dialogs/configserviceconfig.py index 62c0bfc5..e252ec5e 100644 --- a/daemon/core/gui/dialogs/configserviceconfig.py +++ b/daemon/core/gui/dialogs/configserviceconfig.py @@ -4,7 +4,7 @@ Service configuration dialog import logging import tkinter as tk from tkinter import ttk -from typing import TYPE_CHECKING, Dict, List, Optional, Set +from typing import TYPE_CHECKING, Optional import grpc @@ -35,22 +35,22 @@ class ConfigServiceConfigDialog(Dialog): self.node: Node = node self.service_name: str = service_name self.radiovar: tk.IntVar = tk.IntVar(value=2) - self.directories: List[str] = [] - self.templates: List[str] = [] - self.rendered: Dict[str, str] = {} - self.dependencies: List[str] = [] - self.executables: List[str] = [] - self.startup_commands: List[str] = [] - self.validation_commands: List[str] = [] - self.shutdown_commands: List[str] = [] - self.default_startup: List[str] = [] - self.default_validate: List[str] = [] - self.default_shutdown: List[str] = [] + self.directories: list[str] = [] + self.templates: list[str] = [] + self.rendered: dict[str, str] = {} + self.dependencies: list[str] = [] + self.executables: list[str] = [] + self.startup_commands: list[str] = [] + self.validation_commands: list[str] = [] + self.shutdown_commands: list[str] = [] + self.default_startup: list[str] = [] + self.default_validate: list[str] = [] + self.default_shutdown: list[str] = [] self.validation_mode: Optional[ServiceValidationMode] = None self.validation_time: Optional[int] = None self.validation_period: tk.DoubleVar = tk.DoubleVar() - self.modes: List[str] = [] - self.mode_configs: Dict[str, Dict[str, str]] = {} + self.modes: list[str] = [] + self.mode_configs: dict[str, dict[str, str]] = {} self.notebook: Optional[ttk.Notebook] = None self.templates_combobox: Optional[ttk.Combobox] = None self.modes_combobox: Optional[ttk.Combobox] = None @@ -62,12 +62,12 @@ class ConfigServiceConfigDialog(Dialog): self.template_text: Optional[CodeText] = None self.rendered_text: Optional[CodeText] = None self.validation_period_entry: Optional[ttk.Entry] = None - self.original_service_files: Dict[str, str] = {} - self.temp_service_files: Dict[str, str] = {} - self.modified_files: Set[str] = set() + self.original_service_files: dict[str, str] = {} + self.temp_service_files: dict[str, str] = {} + self.modified_files: set[str] = set() self.config_frame: Optional[ConfigFrame] = None - self.default_config: Dict[str, str] = {} - self.config: Dict[str, ConfigOption] = {} + self.default_config: dict[str, str] = {} + self.config: dict[str, ConfigOption] = {} self.has_error: bool = False self.load() if not self.has_error: @@ -405,7 +405,7 @@ class ConfigServiceConfigDialog(Dialog): pass def append_commands( - self, commands: List[str], listbox: tk.Listbox, to_add: List[str] + self, commands: list[str], listbox: tk.Listbox, to_add: list[str] ) -> None: for cmd in to_add: commands.append(cmd) diff --git a/daemon/core/gui/dialogs/copyserviceconfig.py b/daemon/core/gui/dialogs/copyserviceconfig.py index b205e175..6b2f4927 100644 --- a/daemon/core/gui/dialogs/copyserviceconfig.py +++ b/daemon/core/gui/dialogs/copyserviceconfig.py @@ -4,7 +4,7 @@ copy service config dialog import tkinter as tk from tkinter import ttk -from typing import TYPE_CHECKING, Dict, Optional +from typing import TYPE_CHECKING, Optional from core.gui.dialogs.dialog import Dialog from core.gui.themes import PADX, PADY @@ -29,7 +29,7 @@ class CopyServiceConfigDialog(Dialog): self.service: str = service self.file_name: str = file_name self.listbox: Optional[tk.Listbox] = None - self.nodes: Dict[str, int] = {} + self.nodes: dict[str, int] = {} self.draw() def draw(self) -> None: diff --git a/daemon/core/gui/dialogs/customnodes.py b/daemon/core/gui/dialogs/customnodes.py index d6dac44a..ea4421e8 100644 --- a/daemon/core/gui/dialogs/customnodes.py +++ b/daemon/core/gui/dialogs/customnodes.py @@ -2,7 +2,7 @@ import logging import tkinter as tk from pathlib import Path from tkinter import ttk -from typing import TYPE_CHECKING, Optional, Set +from typing import TYPE_CHECKING, Optional from PIL.ImageTk import PhotoImage @@ -21,13 +21,13 @@ if TYPE_CHECKING: class ServicesSelectDialog(Dialog): def __init__( - self, master: tk.BaseWidget, app: "Application", current_services: Set[str] + self, master: tk.BaseWidget, app: "Application", current_services: set[str] ) -> None: super().__init__(app, "Node Config Services", master=master) self.groups: Optional[ListboxScroll] = None self.services: Optional[CheckboxList] = None self.current: Optional[ListboxScroll] = None - self.current_services: Set[str] = current_services + self.current_services: set[str] = current_services self.draw() def draw(self) -> None: @@ -114,7 +114,7 @@ class CustomNodesDialog(Dialog): self.image_button: Optional[ttk.Button] = None self.image: Optional[PhotoImage] = None self.image_file: Optional[str] = None - self.services: Set[str] = set() + self.services: set[str] = set() self.selected: Optional[str] = None self.selected_index: Optional[int] = None self.draw() diff --git a/daemon/core/gui/dialogs/emaneconfig.py b/daemon/core/gui/dialogs/emaneconfig.py index a39720d8..00eda694 100644 --- a/daemon/core/gui/dialogs/emaneconfig.py +++ b/daemon/core/gui/dialogs/emaneconfig.py @@ -4,7 +4,7 @@ emane configuration import tkinter as tk import webbrowser from tkinter import ttk -from typing import TYPE_CHECKING, Dict, List, Optional +from typing import TYPE_CHECKING, Optional import grpc @@ -43,7 +43,7 @@ class EmaneModelDialog(Dialog): config = self.app.core.get_emane_model_config( self.node.id, self.model, self.iface_id ) - self.config: Dict[str, ConfigOption] = config + self.config: dict[str, ConfigOption] = config self.draw() except grpc.RpcError as e: self.app.show_grpc_exception("Get EMANE Config Error", e) @@ -82,7 +82,7 @@ class EmaneConfigDialog(Dialog): self.node: Node = node self.radiovar: tk.IntVar = tk.IntVar() self.radiovar.set(1) - self.emane_models: List[str] = [ + self.emane_models: list[str] = [ x.split("_")[1] for x in self.app.core.emane_models ] model = self.node.emane.split("_")[1] diff --git a/daemon/core/gui/dialogs/ipdialog.py b/daemon/core/gui/dialogs/ipdialog.py index 68b5ab36..99388548 100644 --- a/daemon/core/gui/dialogs/ipdialog.py +++ b/daemon/core/gui/dialogs/ipdialog.py @@ -1,6 +1,6 @@ import tkinter as tk from tkinter import messagebox, ttk -from typing import TYPE_CHECKING, List, Optional +from typing import TYPE_CHECKING, Optional import netaddr @@ -17,8 +17,8 @@ class IpConfigDialog(Dialog): super().__init__(app, "IP Configuration") self.ip4: str = self.app.guiconfig.ips.ip4 self.ip6: str = self.app.guiconfig.ips.ip6 - self.ip4s: List[str] = self.app.guiconfig.ips.ip4s - self.ip6s: List[str] = self.app.guiconfig.ips.ip6s + self.ip4s: list[str] = self.app.guiconfig.ips.ip4s + self.ip6s: list[str] = self.app.guiconfig.ips.ip6s self.ip4_entry: Optional[ttk.Entry] = None self.ip4_listbox: Optional[ListboxScroll] = None self.ip6_entry: Optional[ttk.Entry] = None diff --git a/daemon/core/gui/dialogs/mobilityconfig.py b/daemon/core/gui/dialogs/mobilityconfig.py index b22c5fef..6a2991aa 100644 --- a/daemon/core/gui/dialogs/mobilityconfig.py +++ b/daemon/core/gui/dialogs/mobilityconfig.py @@ -3,7 +3,7 @@ mobility configuration """ import tkinter as tk from tkinter import ttk -from typing import TYPE_CHECKING, Dict, Optional +from typing import TYPE_CHECKING, Optional import grpc @@ -26,7 +26,7 @@ class MobilityConfigDialog(Dialog): config = self.node.mobility_config if not config: config = self.app.core.get_mobility_config(self.node.id) - self.config: Dict[str, ConfigOption] = config + self.config: dict[str, ConfigOption] = config self.draw() except grpc.RpcError as e: self.app.show_grpc_exception("Get Mobility Config Error", e) diff --git a/daemon/core/gui/dialogs/nodeconfig.py b/daemon/core/gui/dialogs/nodeconfig.py index c9ca67f5..162696d4 100644 --- a/daemon/core/gui/dialogs/nodeconfig.py +++ b/daemon/core/gui/dialogs/nodeconfig.py @@ -2,7 +2,7 @@ import logging import tkinter as tk from functools import partial from tkinter import messagebox, ttk -from typing import TYPE_CHECKING, Dict, Optional +from typing import TYPE_CHECKING, Optional import netaddr from PIL.ImageTk import PhotoImage @@ -190,7 +190,7 @@ class NodeConfigDialog(Dialog): if self.node.server: server = self.node.server self.server: tk.StringVar = tk.StringVar(value=server) - self.ifaces: Dict[int, InterfaceData] = {} + self.ifaces: dict[int, InterfaceData] = {} self.draw() def draw(self) -> None: diff --git a/daemon/core/gui/dialogs/nodeconfigservice.py b/daemon/core/gui/dialogs/nodeconfigservice.py index cddbdb03..ce718080 100644 --- a/daemon/core/gui/dialogs/nodeconfigservice.py +++ b/daemon/core/gui/dialogs/nodeconfigservice.py @@ -4,7 +4,7 @@ core node services import logging import tkinter as tk from tkinter import messagebox, ttk -from typing import TYPE_CHECKING, Optional, Set +from typing import TYPE_CHECKING, Optional from core.api.grpc.wrappers import Node from core.gui.dialogs.configserviceconfig import ConfigServiceConfigDialog @@ -20,7 +20,7 @@ if TYPE_CHECKING: class NodeConfigServiceDialog(Dialog): def __init__( - self, app: "Application", node: Node, services: Set[str] = None + self, app: "Application", node: Node, services: set[str] = None ) -> None: title = f"{node.name} Config Services" super().__init__(app, title) @@ -30,7 +30,7 @@ class NodeConfigServiceDialog(Dialog): self.current: Optional[ListboxScroll] = None if services is None: services = set(node.config_services) - self.current_services: Set[str] = services + self.current_services: set[str] = services self.protocol("WM_DELETE_WINDOW", self.click_cancel) self.draw() diff --git a/daemon/core/gui/dialogs/nodeservice.py b/daemon/core/gui/dialogs/nodeservice.py index 431d5c3d..66e83fa4 100644 --- a/daemon/core/gui/dialogs/nodeservice.py +++ b/daemon/core/gui/dialogs/nodeservice.py @@ -3,7 +3,7 @@ core node services """ import tkinter as tk from tkinter import messagebox, ttk -from typing import TYPE_CHECKING, Optional, Set +from typing import TYPE_CHECKING, Optional from core.api.grpc.wrappers import Node from core.gui.dialogs.dialog import Dialog @@ -24,7 +24,7 @@ class NodeServiceDialog(Dialog): self.services: Optional[CheckboxList] = None self.current: Optional[ListboxScroll] = None services = set(node.services) - self.current_services: Set[str] = services + self.current_services: set[str] = services self.protocol("WM_DELETE_WINDOW", self.click_cancel) self.draw() diff --git a/daemon/core/gui/dialogs/runtool.py b/daemon/core/gui/dialogs/runtool.py index 494020e3..75789893 100644 --- a/daemon/core/gui/dialogs/runtool.py +++ b/daemon/core/gui/dialogs/runtool.py @@ -1,6 +1,6 @@ import tkinter as tk from tkinter import ttk -from typing import TYPE_CHECKING, Dict, Optional +from typing import TYPE_CHECKING, Optional from core.gui import nodeutils as nutils from core.gui.dialogs.dialog import Dialog @@ -17,7 +17,7 @@ class RunToolDialog(Dialog): self.cmd: tk.StringVar = tk.StringVar(value="ps ax") self.result: Optional[CodeText] = None self.node_list: Optional[ListboxScroll] = None - self.executable_nodes: Dict[str, int] = {} + self.executable_nodes: dict[str, int] = {} self.store_nodes() self.draw() diff --git a/daemon/core/gui/dialogs/serviceconfig.py b/daemon/core/gui/dialogs/serviceconfig.py index 6f6b0d24..5eec7faf 100644 --- a/daemon/core/gui/dialogs/serviceconfig.py +++ b/daemon/core/gui/dialogs/serviceconfig.py @@ -2,7 +2,7 @@ import logging import tkinter as tk from pathlib import Path from tkinter import filedialog, messagebox, ttk -from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple +from typing import TYPE_CHECKING, Optional import grpc from PIL.ImageTk import PhotoImage @@ -35,21 +35,21 @@ class ServiceConfigDialog(Dialog): self.service_name: str = service_name self.radiovar: tk.IntVar = tk.IntVar(value=2) self.metadata: str = "" - self.filenames: List[str] = [] - self.dependencies: List[str] = [] - self.executables: List[str] = [] - self.startup_commands: List[str] = [] - self.validation_commands: List[str] = [] - self.shutdown_commands: List[str] = [] - self.default_startup: List[str] = [] - self.default_validate: List[str] = [] - self.default_shutdown: List[str] = [] + self.filenames: list[str] = [] + self.dependencies: list[str] = [] + self.executables: list[str] = [] + self.startup_commands: list[str] = [] + self.validation_commands: list[str] = [] + self.shutdown_commands: list[str] = [] + self.default_startup: list[str] = [] + self.default_validate: list[str] = [] + self.default_shutdown: list[str] = [] self.validation_mode: Optional[ServiceValidationMode] = None self.validation_time: Optional[int] = None self.validation_period: Optional[float] = None self.directory_entry: Optional[ttk.Entry] = None - self.default_directories: List[str] = [] - self.temp_directories: List[str] = [] + self.default_directories: list[str] = [] + self.temp_directories: list[str] = [] self.documentnew_img: PhotoImage = self.app.get_enum_icon( ImageEnum.DOCUMENTNEW, width=ICON_SIZE ) @@ -67,10 +67,10 @@ class ServiceConfigDialog(Dialog): self.validation_mode_entry: Optional[ttk.Entry] = None self.service_file_data: Optional[CodeText] = None self.validation_period_entry: Optional[ttk.Entry] = None - self.original_service_files: Dict[str, str] = {} + self.original_service_files: dict[str, str] = {} self.default_config: Optional[NodeServiceData] = None - self.temp_service_files: Dict[str, str] = {} - self.modified_files: Set[str] = set() + self.temp_service_files: dict[str, str] = {} + self.modified_files: set[str] = set() self.has_error: bool = False self.load() if not self.has_error: @@ -558,13 +558,13 @@ class ServiceConfigDialog(Dialog): @classmethod def append_commands( - cls, commands: List[str], listbox: tk.Listbox, to_add: List[str] + cls, commands: list[str], listbox: tk.Listbox, to_add: list[str] ) -> None: for cmd in to_add: commands.append(cmd) listbox.insert(tk.END, cmd) - def get_commands(self) -> Tuple[List[str], List[str], List[str]]: + def get_commands(self) -> tuple[list[str], list[str], list[str]]: startup = self.startup_commands_listbox.get(0, "end") shutdown = self.shutdown_commands_listbox.get(0, "end") validate = self.validate_commands_listbox.get(0, "end") diff --git a/daemon/core/gui/dialogs/sessions.py b/daemon/core/gui/dialogs/sessions.py index deca7404..3ca4fa63 100644 --- a/daemon/core/gui/dialogs/sessions.py +++ b/daemon/core/gui/dialogs/sessions.py @@ -1,7 +1,7 @@ import logging import tkinter as tk from tkinter import messagebox, ttk -from typing import TYPE_CHECKING, List, Optional +from typing import TYPE_CHECKING, Optional import grpc @@ -30,7 +30,7 @@ class SessionsDialog(Dialog): self.protocol("WM_DELETE_WINDOW", self.on_closing) self.draw() - def get_sessions(self) -> List[SessionSummary]: + def get_sessions(self) -> list[SessionSummary]: try: sessions = self.app.core.client.get_sessions() logger.info("sessions: %s", sessions) diff --git a/daemon/core/gui/dialogs/shapemod.py b/daemon/core/gui/dialogs/shapemod.py index d0e200ee..db19ff1a 100644 --- a/daemon/core/gui/dialogs/shapemod.py +++ b/daemon/core/gui/dialogs/shapemod.py @@ -3,7 +3,7 @@ shape input dialog """ import tkinter as tk from tkinter import font, ttk -from typing import TYPE_CHECKING, List, Optional, Union +from typing import TYPE_CHECKING, Optional, Union from core.gui.dialogs.colorpicker import ColorPickerDialog from core.gui.dialogs.dialog import Dialog @@ -16,8 +16,8 @@ if TYPE_CHECKING: from core.gui.graph.graph import CanvasGraph from core.gui.graph.shape import Shape -FONT_SIZES: List[int] = [8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72] -BORDER_WIDTH: List[int] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +FONT_SIZES: list[int] = [8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72] +BORDER_WIDTH: list[int] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] class ShapeDialog(Dialog): @@ -168,7 +168,7 @@ class ShapeDialog(Dialog): self.add_text() self.destroy() - def make_font(self) -> List[Union[int, str]]: + def make_font(self) -> list[Union[int, str]]: """ create font for text or shape label """ diff --git a/daemon/core/gui/dialogs/wirelessconfig.py b/daemon/core/gui/dialogs/wirelessconfig.py index 97e37b5f..b04fbd2c 100644 --- a/daemon/core/gui/dialogs/wirelessconfig.py +++ b/daemon/core/gui/dialogs/wirelessconfig.py @@ -1,6 +1,6 @@ import tkinter as tk from tkinter import ttk -from typing import TYPE_CHECKING, Dict, Optional +from typing import TYPE_CHECKING, Optional import grpc @@ -19,12 +19,12 @@ class WirelessConfigDialog(Dialog): super().__init__(app, f"Wireless Configuration - {canvas_node.core_node.name}") self.node: Node = canvas_node.core_node self.config_frame: Optional[ConfigFrame] = None - self.config: Dict[str, ConfigOption] = {} + self.config: dict[str, ConfigOption] = {} try: config = self.node.wireless_config if not config: config = self.app.core.get_wireless_config(self.node.id) - self.config: Dict[str, ConfigOption] = config + self.config: dict[str, ConfigOption] = config self.draw() except grpc.RpcError as e: self.app.show_grpc_exception("Wireless Config Error", e) diff --git a/daemon/core/gui/dialogs/wlanconfig.py b/daemon/core/gui/dialogs/wlanconfig.py index 237ca8a5..c382d3c8 100644 --- a/daemon/core/gui/dialogs/wlanconfig.py +++ b/daemon/core/gui/dialogs/wlanconfig.py @@ -1,6 +1,6 @@ import tkinter as tk from tkinter import ttk -from typing import TYPE_CHECKING, Dict, Optional +from typing import TYPE_CHECKING, Optional import grpc @@ -27,13 +27,13 @@ class WlanConfigDialog(Dialog): self.config_frame: Optional[ConfigFrame] = None self.range_entry: Optional[ttk.Entry] = None self.has_error: bool = False - self.ranges: Dict[int, int] = {} + self.ranges: dict[int, int] = {} self.positive_int: int = self.app.master.register(self.validate_and_update) try: config = self.node.wlan_config if not config: config = self.app.core.get_wlan_config(self.node.id) - self.config: Dict[str, ConfigOption] = config + self.config: dict[str, ConfigOption] = config self.init_draw_range() self.draw() except grpc.RpcError as e: diff --git a/daemon/core/gui/graph/edges.py b/daemon/core/gui/graph/edges.py index 0e56781d..e5a4c97b 100644 --- a/daemon/core/gui/graph/edges.py +++ b/daemon/core/gui/graph/edges.py @@ -2,7 +2,7 @@ import functools import logging import math import tkinter as tk -from typing import TYPE_CHECKING, Optional, Tuple, Union +from typing import TYPE_CHECKING, Optional, Union from core.api.grpc.wrappers import Interface, Link from core.gui import nodeutils, themes @@ -54,7 +54,7 @@ def create_edge_token(link: Link) -> str: def node_label_positions( src_x: int, src_y: int, dst_x: int, dst_y: int -) -> Tuple[Tuple[float, float], Tuple[float, float]]: +) -> tuple[tuple[float, float], tuple[float, float]]: v_x, v_y = dst_x - src_x, dst_y - src_y v_len = math.sqrt(v_x**2 + v_y**2) if v_len == 0: @@ -128,8 +128,8 @@ class Edge: return self.width * self.app.app_scale def _get_arcpoint( - self, src_pos: Tuple[float, float], dst_pos: Tuple[float, float] - ) -> Tuple[float, float]: + self, src_pos: tuple[float, float], dst_pos: tuple[float, float] + ) -> tuple[float, float]: src_x, src_y = src_pos dst_x, dst_y = dst_pos mp_x = (src_x + dst_x) / 2 @@ -317,7 +317,7 @@ class Edge: if self.dst_label2: self.dst.canvas.itemconfig(self.dst_label2, text=text) - def drawing(self, pos: Tuple[float, float]) -> None: + def drawing(self, pos: tuple[float, float]) -> None: src_x, src_y, _, _, _, _ = self.src.canvas.coords(self.id) src_pos = src_x, src_y self.moved(src_pos, pos) @@ -368,7 +368,7 @@ class Edge: dst_pos = dst_x, dst_y self.moved(self.src.position(), dst_pos) - def moved(self, src_pos: Tuple[float, float], dst_pos: Tuple[float, float]) -> None: + def moved(self, src_pos: tuple[float, float], dst_pos: tuple[float, float]) -> None: arc_pos = self._get_arcpoint(src_pos, dst_pos) self.src.canvas.coords(self.id, *src_pos, *arc_pos, *dst_pos) if self.middle_label: @@ -381,7 +381,7 @@ class Edge: self.src.canvas.coords(self.dst_label, *dst_pos) def moved2( - self, src_pos: Tuple[float, float], dst_pos: Tuple[float, float] + self, src_pos: tuple[float, float], dst_pos: tuple[float, float] ) -> None: arc_pos = self._get_arcpoint(src_pos, dst_pos) self.dst.canvas.coords(self.id2, *src_pos, *arc_pos, *dst_pos) @@ -568,7 +568,7 @@ class CanvasEdge(Edge): label += f"{iface.ip6}/{iface.ip6_mask}" return label - def create_node_labels(self) -> Tuple[str, str]: + def create_node_labels(self) -> tuple[str, str]: label1 = None if self.link.iface1: label1 = self.iface_label(self.link.iface1) diff --git a/daemon/core/gui/graph/graph.py b/daemon/core/gui/graph/graph.py index e3225a4d..1a701239 100644 --- a/daemon/core/gui/graph/graph.py +++ b/daemon/core/gui/graph/graph.py @@ -2,7 +2,7 @@ import logging import tkinter as tk from copy import deepcopy from pathlib import Path -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Tuple +from typing import TYPE_CHECKING, Any, Optional from PIL import Image from PIL.ImageTk import PhotoImage @@ -27,8 +27,8 @@ if TYPE_CHECKING: ZOOM_IN: float = 1.1 ZOOM_OUT: float = 0.9 -MOVE_NODE_MODES: Set[GraphMode] = {GraphMode.NODE, GraphMode.SELECT} -MOVE_SHAPE_MODES: Set[GraphMode] = {GraphMode.ANNOTATION, GraphMode.SELECT} +MOVE_NODE_MODES: set[GraphMode] = {GraphMode.NODE, GraphMode.SELECT} +MOVE_SHAPE_MODES: set[GraphMode] = {GraphMode.ANNOTATION, GraphMode.SELECT} BACKGROUND_COLOR: str = "#cccccc" @@ -40,32 +40,32 @@ class CanvasGraph(tk.Canvas): manager: "CanvasManager", core: "CoreClient", _id: int, - dimensions: Tuple[int, int], + dimensions: tuple[int, int], ) -> None: super().__init__(master, highlightthickness=0, background=BACKGROUND_COLOR) self.id: int = _id self.app: "Application" = app self.manager: "CanvasManager" = manager self.core: "CoreClient" = core - self.selection: Dict[int, int] = {} + self.selection: dict[int, int] = {} self.select_box: Optional[Shape] = None self.selected: Optional[int] = None - self.nodes: Dict[int, CanvasNode] = {} - self.shadow_nodes: Dict[int, ShadowNode] = {} - self.shapes: Dict[int, Shape] = {} - self.shadow_core_nodes: Dict[int, ShadowNode] = {} + self.nodes: dict[int, CanvasNode] = {} + self.shadow_nodes: dict[int, ShadowNode] = {} + self.shapes: dict[int, Shape] = {} + self.shadow_core_nodes: dict[int, ShadowNode] = {} # map wireless/EMANE node to the set of MDRs connected to that node - self.wireless_network: Dict[int, Set[int]] = {} + self.wireless_network: dict[int, set[int]] = {} self.drawing_edge: Optional[CanvasEdge] = None self.rect: Optional[int] = None self.shape_drawing: bool = False - self.current_dimensions: Tuple[int, int] = dimensions + self.current_dimensions: tuple[int, int] = dimensions self.ratio: float = 1.0 - self.offset: Tuple[int, int] = (0, 0) - self.cursor: Tuple[int, int] = (0, 0) - self.to_copy: List[CanvasNode] = [] + self.offset: tuple[int, int] = (0, 0) + self.cursor: tuple[int, int] = (0, 0) + self.to_copy: list[CanvasNode] = [] # background related self.wallpaper_id: Optional[int] = None @@ -82,7 +82,7 @@ class CanvasGraph(tk.Canvas): self.draw_canvas() self.draw_grid() - def draw_canvas(self, dimensions: Tuple[int, int] = None) -> None: + def draw_canvas(self, dimensions: tuple[int, int] = None) -> None: if self.rect is not None: self.delete(self.rect) if not dimensions: @@ -126,23 +126,23 @@ class CanvasGraph(tk.Canvas): shadow_node = ShadowNode(self.app, self, node) return shadow_node - def get_actual_coords(self, x: float, y: float) -> Tuple[float, float]: + def get_actual_coords(self, x: float, y: float) -> tuple[float, float]: actual_x = (x - self.offset[0]) / self.ratio actual_y = (y - self.offset[1]) / self.ratio return actual_x, actual_y - def get_scaled_coords(self, x: float, y: float) -> Tuple[float, float]: + def get_scaled_coords(self, x: float, y: float) -> tuple[float, float]: scaled_x = (x * self.ratio) + self.offset[0] scaled_y = (y * self.ratio) + self.offset[1] return scaled_x, scaled_y - def inside_canvas(self, x: float, y: float) -> Tuple[bool, bool]: + def inside_canvas(self, x: float, y: float) -> tuple[bool, bool]: x1, y1, x2, y2 = self.bbox(self.rect) valid_x = x1 <= x <= x2 valid_y = y1 <= y <= y2 return valid_x and valid_y - def valid_position(self, x1: int, y1: int, x2: int, y2: int) -> Tuple[bool, bool]: + def valid_position(self, x1: int, y1: int, x2: int, y2: int) -> tuple[bool, bool]: valid_topleft = self.inside_canvas(x1, y1) valid_bottomright = self.inside_canvas(x2, y2) return valid_topleft and valid_bottomright @@ -161,7 +161,7 @@ class CanvasGraph(tk.Canvas): self.tag_lower(tags.GRIDLINE) self.tag_lower(self.rect) - def canvas_xy(self, event: tk.Event) -> Tuple[float, float]: + def canvas_xy(self, event: tk.Event) -> tuple[float, float]: """ Convert window coordinate to canvas coordinate """ @@ -516,7 +516,7 @@ class CanvasGraph(tk.Canvas): self.nodes[node.id] = node self.core.set_canvas_node(core_node, node) - def width_and_height(self) -> Tuple[int, int]: + def width_and_height(self) -> tuple[int, int]: """ retrieve canvas width and height in pixels """ @@ -601,7 +601,7 @@ class CanvasGraph(tk.Canvas): self.redraw_canvas((image.width(), image.height())) self.draw_wallpaper(image) - def redraw_canvas(self, dimensions: Tuple[int, int] = None) -> None: + def redraw_canvas(self, dimensions: tuple[int, int] = None) -> None: logger.debug("redrawing canvas to dimensions: %s", dimensions) # reset scale and move back to original position @@ -814,7 +814,7 @@ class CanvasGraph(tk.Canvas): for edge_id in self.find_withtag(tags.EDGE): self.itemconfig(edge_id, width=int(EDGE_WIDTH * self.app.app_scale)) - def get_metadata(self) -> Dict[str, Any]: + def get_metadata(self) -> dict[str, Any]: wallpaper_path = None if self.wallpaper_file: wallpaper = Path(self.wallpaper_file) @@ -830,7 +830,7 @@ class CanvasGraph(tk.Canvas): dimensions=self.current_dimensions, ) - def parse_metadata(self, config: Dict[str, Any]) -> None: + def parse_metadata(self, config: dict[str, Any]) -> None: fit_image = config.get("fit_image", False) self.adjust_to_dim.set(fit_image) wallpaper_style = config.get("wallpaper_style", 1) diff --git a/daemon/core/gui/graph/manager.py b/daemon/core/gui/graph/manager.py index dc0adca9..a0f60754 100644 --- a/daemon/core/gui/graph/manager.py +++ b/daemon/core/gui/graph/manager.py @@ -1,9 +1,10 @@ import json import logging import tkinter as tk +from collections.abc import ValuesView from copy import deepcopy from tkinter import BooleanVar, messagebox, ttk -from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, ValuesView +from typing import TYPE_CHECKING, Any, Optional from core.api.grpc.wrappers import Link, LinkType, Node, Session, ThroughputsEvent from core.gui import nodeutils as nutils @@ -78,14 +79,14 @@ class CanvasManager: self.mode: GraphMode = GraphMode.SELECT self.annotation_type: Optional[ShapeType] = None self.node_draw: Optional[NodeDraw] = None - self.canvases: Dict[int, CanvasGraph] = {} + self.canvases: dict[int, CanvasGraph] = {} # global edge management - self.edges: Dict[str, CanvasEdge] = {} - self.wireless_edges: Dict[str, CanvasWirelessEdge] = {} + self.edges: dict[str, CanvasEdge] = {} + self.wireless_edges: dict[str, CanvasWirelessEdge] = {} # global canvas settings - self.default_dimensions: Tuple[int, int] = ( + self.default_dimensions: tuple[int, int] = ( self.app.guiconfig.preferences.width, self.app.guiconfig.preferences.height, ) @@ -111,8 +112,8 @@ class CanvasManager: # widget self.notebook: Optional[ttk.Notebook] = None - self.canvas_ids: Dict[str, int] = {} - self.unique_ids: Dict[int, str] = {} + self.canvas_ids: dict[str, int] = {} + self.unique_ids: dict[int, str] = {} self.draw() self.setup_bindings() @@ -273,17 +274,17 @@ class CanvasManager: if not self.canvases: self.add_canvas() - def redraw_canvas(self, dimensions: Tuple[int, int]) -> None: + def redraw_canvas(self, dimensions: tuple[int, int]) -> None: canvas = self.current() canvas.redraw_canvas(dimensions) if canvas.wallpaper: canvas.redraw_wallpaper() - def get_metadata(self) -> Dict[str, Any]: + def get_metadata(self) -> dict[str, Any]: canvases = [x.get_metadata() for x in self.all()] return dict(gridlines=self.show_grid.get(), canvases=canvases) - def parse_metadata_canvas(self, metadata: Dict[str, Any]) -> None: + def parse_metadata_canvas(self, metadata: dict[str, Any]) -> None: # canvas setting canvas_config = metadata.get("canvas") logger.debug("canvas metadata: %s", canvas_config) @@ -303,7 +304,7 @@ class CanvasManager: canvas = self.get(canvas_id) canvas.parse_metadata(canvas_config) - def parse_metadata_shapes(self, metadata: Dict[str, Any]) -> None: + def parse_metadata_shapes(self, metadata: dict[str, Any]) -> None: # load saved shapes shapes_config = metadata.get("shapes") if not shapes_config: @@ -313,7 +314,7 @@ class CanvasManager: logger.debug("loading shape: %s", shape_config) Shape.from_metadata(self.app, shape_config) - def parse_metadata_edges(self, metadata: Dict[str, Any]) -> None: + def parse_metadata_edges(self, metadata: dict[str, Any]) -> None: # load edges config edges_config = metadata.get("edges") if not edges_config: @@ -330,7 +331,7 @@ class CanvasManager: else: logger.warning("invalid edge token to configure: %s", edge_token) - def parse_metadata_hidden(self, metadata: Dict[str, Any]) -> None: + def parse_metadata_hidden(self, metadata: dict[str, Any]) -> None: # read hidden nodes hidden_config = metadata.get("hidden") if not hidden_config: diff --git a/daemon/core/gui/graph/node.py b/daemon/core/gui/graph/node.py index b3d0aae9..0cfbf2e9 100644 --- a/daemon/core/gui/graph/node.py +++ b/daemon/core/gui/graph/node.py @@ -2,7 +2,7 @@ import functools import logging import tkinter as tk from pathlib import Path -from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple +from typing import TYPE_CHECKING, Optional import grpc from PIL.ImageTk import PhotoImage @@ -62,17 +62,17 @@ class CanvasNode: state=self.app.manager.show_node_labels.state(), ) self.tooltip: CanvasTooltip = CanvasTooltip(self.canvas) - self.edges: Set[CanvasEdge] = set() - self.ifaces: Dict[int, Interface] = {} - self.wireless_edges: Set[CanvasWirelessEdge] = set() - self.antennas: List[int] = [] - self.antenna_images: Dict[int, PhotoImage] = {} + self.edges: set[CanvasEdge] = set() + self.ifaces: dict[int, Interface] = {} + self.wireless_edges: set[CanvasWirelessEdge] = set() + self.antennas: list[int] = [] + self.antenna_images: dict[int, PhotoImage] = {} self.hidden: bool = False self.setup_bindings() self.context: tk.Menu = tk.Menu(self.canvas) themes.style_menu(self.context) - def position(self) -> Tuple[int, int]: + def position(self) -> tuple[int, int]: return self.canvas.coords(self.id) def next_iface_id(self) -> int: @@ -543,7 +543,7 @@ class ShadowNode: self.canvas.shadow_nodes[self.id] = self self.canvas.shadow_core_nodes[self.node.core_node.id] = self - def position(self) -> Tuple[int, int]: + def position(self) -> tuple[int, int]: return self.canvas.coords(self.id) def should_delete(self) -> bool: diff --git a/daemon/core/gui/graph/shape.py b/daemon/core/gui/graph/shape.py index 7db18b5b..5f243fdf 100644 --- a/daemon/core/gui/graph/shape.py +++ b/daemon/core/gui/graph/shape.py @@ -1,5 +1,5 @@ import logging -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union +from typing import TYPE_CHECKING, Any, Optional, Union from core.gui.dialogs.shapemod import ShapeDialog from core.gui.graph import tags @@ -72,7 +72,7 @@ class Shape: self.draw() @classmethod - def from_metadata(cls, app: "Application", config: Dict[str, Any]) -> None: + def from_metadata(cls, app: "Application", config: dict[str, Any]) -> None: shape_type = config["type"] try: shape_type = ShapeType(shape_type) @@ -144,7 +144,7 @@ class Shape: logger.error("unknown shape type: %s", self.shape_type) self.created = True - def get_font(self) -> List[Union[int, str]]: + def get_font(self) -> list[Union[int, str]]: font = [self.shape_data.font, self.shape_data.font_size] if self.shape_data.bold: font.append("bold") @@ -198,7 +198,7 @@ class Shape: self.canvas.delete(self.id) self.canvas.delete(self.text_id) - def metadata(self) -> Dict[str, Union[str, int, bool]]: + def metadata(self) -> dict[str, Union[str, int, bool]]: coords = self.canvas.coords(self.id) # update coords to actual positions if len(coords) == 4: diff --git a/daemon/core/gui/graph/shapeutils.py b/daemon/core/gui/graph/shapeutils.py index 2b62a46c..ab82ef76 100644 --- a/daemon/core/gui/graph/shapeutils.py +++ b/daemon/core/gui/graph/shapeutils.py @@ -1,5 +1,4 @@ import enum -from typing import Set class ShapeType(enum.Enum): @@ -9,7 +8,7 @@ class ShapeType(enum.Enum): TEXT = "text" -SHAPES: Set[ShapeType] = {ShapeType.OVAL, ShapeType.RECTANGLE} +SHAPES: set[ShapeType] = {ShapeType.OVAL, ShapeType.RECTANGLE} def is_draw_shape(shape_type: ShapeType) -> bool: diff --git a/daemon/core/gui/graph/tags.py b/daemon/core/gui/graph/tags.py index 803b969e..cb1ffc15 100644 --- a/daemon/core/gui/graph/tags.py +++ b/daemon/core/gui/graph/tags.py @@ -1,5 +1,3 @@ -from typing import List - ANNOTATION: str = "annotation" GRIDLINE: str = "gridline" SHAPE: str = "shape" @@ -15,7 +13,7 @@ WALLPAPER: str = "wallpaper" SELECTION: str = "selectednodes" MARKER: str = "marker" HIDDEN: str = "hidden" -ORGANIZE_TAGS: List[str] = [ +ORGANIZE_TAGS: list[str] = [ WALLPAPER, GRIDLINE, SHAPE, @@ -29,7 +27,7 @@ ORGANIZE_TAGS: List[str] = [ SELECTION, MARKER, ] -RESET_TAGS: List[str] = [ +RESET_TAGS: list[str] = [ EDGE, NODE, NODE_LABEL, diff --git a/daemon/core/gui/graph/tooltip.py b/daemon/core/gui/graph/tooltip.py index 6e4aa62f..37e7ac5d 100644 --- a/daemon/core/gui/graph/tooltip.py +++ b/daemon/core/gui/graph/tooltip.py @@ -1,6 +1,6 @@ import tkinter as tk from tkinter import ttk -from typing import TYPE_CHECKING, Optional, Tuple +from typing import TYPE_CHECKING, Optional from core.gui.themes import Styles @@ -27,7 +27,7 @@ class CanvasTooltip: self, canvas: "CanvasGraph", *, - pad: Tuple[int, int, int, int] = (5, 3, 5, 3), + pad: tuple[int, int, int, int] = (5, 3, 5, 3), waittime: int = 400, wraplength: int = 600 ) -> None: @@ -37,7 +37,7 @@ class CanvasTooltip: self.wraplength: int = wraplength self.canvas: "CanvasGraph" = canvas self.text: tk.StringVar = tk.StringVar() - self.pad: Tuple[int, int, int, int] = pad + self.pad: tuple[int, int, int, int] = pad self.id: Optional[str] = None self.tw: Optional[tk.Toplevel] = None @@ -63,8 +63,8 @@ class CanvasTooltip: canvas: "CanvasGraph", label: ttk.Label, *, - tip_delta: Tuple[int, int] = (10, 5), - pad: Tuple[int, int, int, int] = (5, 3, 5, 3) + tip_delta: tuple[int, int] = (10, 5), + pad: tuple[int, int, int, int] = (5, 3, 5, 3) ): c = canvas s_width, s_height = c.winfo_screenwidth(), c.winfo_screenheight() diff --git a/daemon/core/gui/images.py b/daemon/core/gui/images.py index aed4cfcc..b1832c1e 100644 --- a/daemon/core/gui/images.py +++ b/daemon/core/gui/images.py @@ -1,5 +1,5 @@ from enum import Enum -from typing import Dict, Optional, Tuple +from typing import Optional from PIL import Image from PIL.ImageTk import PhotoImage @@ -12,7 +12,7 @@ ANTENNA_SIZE: int = 32 BUTTON_SIZE: int = 16 ERROR_SIZE: int = 24 DIALOG_SIZE: int = 16 -IMAGES: Dict[str, str] = {} +IMAGES: dict[str, str] = {} def load_all() -> None: @@ -87,7 +87,7 @@ class ImageEnum(Enum): SHADOW = "shadow" -TYPE_MAP: Dict[Tuple[NodeType, str], ImageEnum] = { +TYPE_MAP: dict[tuple[NodeType, str], ImageEnum] = { (NodeType.DEFAULT, "router"): ImageEnum.ROUTER, (NodeType.DEFAULT, "PC"): ImageEnum.PC, (NodeType.DEFAULT, "host"): ImageEnum.HOST, diff --git a/daemon/core/gui/interface.py b/daemon/core/gui/interface.py index 83fba104..9ebea3c1 100644 --- a/daemon/core/gui/interface.py +++ b/daemon/core/gui/interface.py @@ -1,5 +1,5 @@ import logging -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Tuple +from typing import TYPE_CHECKING, Any, Optional import netaddr from netaddr import EUI, IPNetwork @@ -43,7 +43,7 @@ class Subnets: def __hash__(self) -> int: return hash(self.key()) - def key(self) -> Tuple[IPNetwork, IPNetwork]: + def key(self) -> tuple[IPNetwork, IPNetwork]: return self.ip4, self.ip6 def next(self) -> "Subnets": @@ -61,8 +61,8 @@ class InterfaceManager: self.mac: EUI = EUI(mac, dialect=netaddr.mac_unix_expanded) self.current_mac: Optional[EUI] = None self.current_subnets: Optional[Subnets] = None - self.used_subnets: Dict[Tuple[IPNetwork, IPNetwork], Subnets] = {} - self.used_macs: Set[str] = set() + self.used_subnets: dict[tuple[IPNetwork, IPNetwork], Subnets] = {} + self.used_macs: set[str] = set() def update_ips(self, ip4: str, ip6: str) -> None: self.reset() @@ -91,7 +91,7 @@ class InterfaceManager: self.current_subnets = None self.used_subnets.clear() - def removed(self, links: List[Link]) -> None: + def removed(self, links: list[Link]) -> None: # get remaining subnets remaining_subnets = set() for edge in self.app.core.links.values(): @@ -121,7 +121,7 @@ class InterfaceManager: subnets.used_indexes.discard(index) self.current_subnets = None - def set_macs(self, links: List[Link]) -> None: + def set_macs(self, links: list[Link]) -> None: self.current_mac = self.mac self.used_macs.clear() for link in links: @@ -130,7 +130,7 @@ class InterfaceManager: if link.iface2: self.used_macs.add(link.iface2.mac) - def joined(self, links: List[Link]) -> None: + def joined(self, links: list[Link]) -> None: ifaces = [] for link in links: if link.iface1: @@ -208,7 +208,7 @@ class InterfaceManager: logger.info("ignoring subnet change for link between network nodes") def find_subnets( - self, canvas_node: CanvasNode, visited: Set[int] = None + self, canvas_node: CanvasNode, visited: set[int] = None ) -> Optional[IPNetwork]: logger.info("finding subnet for node: %s", canvas_node.core_node.name) subnets = None diff --git a/daemon/core/gui/nodeutils.py b/daemon/core/gui/nodeutils.py index 0357f23d..0201aa9d 100644 --- a/daemon/core/gui/nodeutils.py +++ b/daemon/core/gui/nodeutils.py @@ -1,5 +1,5 @@ import logging -from typing import TYPE_CHECKING, List, Optional, Set +from typing import TYPE_CHECKING, Optional from PIL.ImageTk import PhotoImage @@ -13,22 +13,22 @@ logger = logging.getLogger(__name__) if TYPE_CHECKING: from core.gui.app import Application -NODES: List["NodeDraw"] = [] -NETWORK_NODES: List["NodeDraw"] = [] +NODES: list["NodeDraw"] = [] +NETWORK_NODES: list["NodeDraw"] = [] NODE_ICONS = {} -CONTAINER_NODES: Set[NodeType] = {NodeType.DEFAULT, NodeType.DOCKER, NodeType.LXC} -IMAGE_NODES: Set[NodeType] = {NodeType.DOCKER, NodeType.LXC} -WIRELESS_NODES: Set[NodeType] = { +CONTAINER_NODES: set[NodeType] = {NodeType.DEFAULT, NodeType.DOCKER, NodeType.LXC} +IMAGE_NODES: set[NodeType] = {NodeType.DOCKER, NodeType.LXC} +WIRELESS_NODES: set[NodeType] = { NodeType.WIRELESS_LAN, NodeType.EMANE, NodeType.WIRELESS, } -RJ45_NODES: Set[NodeType] = {NodeType.RJ45} -BRIDGE_NODES: Set[NodeType] = {NodeType.HUB, NodeType.SWITCH} -IGNORE_NODES: Set[NodeType] = {NodeType.CONTROL_NET} -MOBILITY_NODES: Set[NodeType] = {NodeType.WIRELESS_LAN, NodeType.EMANE} -NODE_MODELS: Set[str] = {"router", "PC", "mdr", "prouter"} -ROUTER_NODES: Set[str] = {"router", "mdr"} +RJ45_NODES: set[NodeType] = {NodeType.RJ45} +BRIDGE_NODES: set[NodeType] = {NodeType.HUB, NodeType.SWITCH} +IGNORE_NODES: set[NodeType] = {NodeType.CONTROL_NET} +MOBILITY_NODES: set[NodeType] = {NodeType.WIRELESS_LAN, NodeType.EMANE} +NODE_MODELS: set[str] = {"router", "PC", "mdr", "prouter"} +ROUTER_NODES: set[str] = {"router", "mdr"} ANTENNA_ICON: Optional[PhotoImage] = None @@ -106,7 +106,7 @@ def is_iface_node(node: Node) -> bool: return is_container(node) or is_bridge(node) -def get_custom_services(gui_config: GuiConfig, name: str) -> List[str]: +def get_custom_services(gui_config: GuiConfig, name: str) -> list[str]: for custom_node in gui_config.nodes: if custom_node.name == name: return custom_node.services @@ -154,7 +154,7 @@ class NodeDraw: self.image_file: Optional[str] = None self.node_type: Optional[NodeType] = None self.model: Optional[str] = None - self.services: Set[str] = set() + self.services: set[str] = set() self.label: Optional[str] = None @classmethod diff --git a/daemon/core/gui/observers.py b/daemon/core/gui/observers.py index 7879494b..8cf026bd 100644 --- a/daemon/core/gui/observers.py +++ b/daemon/core/gui/observers.py @@ -1,13 +1,13 @@ import tkinter as tk from functools import partial -from typing import TYPE_CHECKING, Dict +from typing import TYPE_CHECKING from core.gui.dialogs.observers import ObserverDialog if TYPE_CHECKING: from core.gui.app import Application -OBSERVERS: Dict[str, str] = { +OBSERVERS: dict[str, str] = { "List Processes": "ps", "Show Interfaces": "ip address", "IPV4 Routes": "ip -4 route", diff --git a/daemon/core/gui/statusbar.py b/daemon/core/gui/statusbar.py index 441213f2..a4967cd6 100644 --- a/daemon/core/gui/statusbar.py +++ b/daemon/core/gui/statusbar.py @@ -3,7 +3,7 @@ status bar """ import tkinter as tk from tkinter import ttk -from typing import TYPE_CHECKING, List, Optional +from typing import TYPE_CHECKING, Optional from core.api.grpc.wrappers import ExceptionEvent, ExceptionLevel from core.gui.dialogs.alerts import AlertsDialog @@ -24,7 +24,7 @@ class StatusBar(ttk.Frame): self.alerts_button: Optional[ttk.Button] = None self.alert_style = Styles.no_alert self.running: bool = False - self.core_alarms: List[ExceptionEvent] = [] + self.core_alarms: list[ExceptionEvent] = [] self.draw() def draw(self) -> None: diff --git a/daemon/core/gui/task.py b/daemon/core/gui/task.py index 2623136d..6bbeb70f 100644 --- a/daemon/core/gui/task.py +++ b/daemon/core/gui/task.py @@ -2,7 +2,7 @@ import logging import threading import time import tkinter as tk -from typing import TYPE_CHECKING, Any, Callable, Optional, Tuple +from typing import TYPE_CHECKING, Any, Callable, Optional logger = logging.getLogger(__name__) @@ -17,7 +17,7 @@ class ProgressTask: title: str, task: Callable, callback: Callable = None, - args: Tuple[Any] = None, + args: tuple[Any] = None, ): self.app: "Application" = app self.title: str = title @@ -25,7 +25,7 @@ class ProgressTask: self.callback: Callable = callback if args is None: args = () - self.args: Tuple[Any] = args + self.args: tuple[Any] = args self.time: Optional[float] = None def start(self) -> None: diff --git a/daemon/core/gui/themes.py b/daemon/core/gui/themes.py index 45b109f0..cb6280e5 100644 --- a/daemon/core/gui/themes.py +++ b/daemon/core/gui/themes.py @@ -1,10 +1,9 @@ import tkinter as tk from tkinter import font, ttk -from typing import Dict, Tuple THEME_DARK: str = "black" -PADX: Tuple[int, int] = (0, 5) -PADY: Tuple[int, int] = (0, 5) +PADX: tuple[int, int] = (0, 5) +PADY: tuple[int, int] = (0, 5) FRAME_PAD: int = 5 DIALOG_PAD: int = 5 @@ -201,7 +200,7 @@ def theme_change(event: tk.Event) -> None: _alert_style(style, Styles.red_alert, "red") -def scale_fonts(fonts_size: Dict[str, int], scale: float) -> None: +def scale_fonts(fonts_size: dict[str, int], scale: float) -> None: for name in font.names(): f = font.nametofont(name) if name in fonts_size: diff --git a/daemon/core/gui/toolbar.py b/daemon/core/gui/toolbar.py index 7392071d..7c32c0af 100644 --- a/daemon/core/gui/toolbar.py +++ b/daemon/core/gui/toolbar.py @@ -3,7 +3,7 @@ import tkinter as tk from enum import Enum from functools import partial from tkinter import ttk -from typing import TYPE_CHECKING, Callable, List, Optional +from typing import TYPE_CHECKING, Callable, Optional from PIL.ImageTk import PhotoImage @@ -90,7 +90,7 @@ class ButtonBar(ttk.Frame): def __init__(self, master: tk.Widget, app: "Application") -> None: super().__init__(master) self.app: "Application" = app - self.radio_buttons: List[ttk.Button] = [] + self.radio_buttons: list[ttk.Button] = [] def create_button( self, image_enum: ImageEnum, func: Callable, tooltip: str, radio: bool = False @@ -303,7 +303,7 @@ class Toolbar(ttk.Frame): ) task.start() - def start_callback(self, result: bool, exceptions: List[str]) -> None: + def start_callback(self, result: bool, exceptions: list[str]) -> None: self.set_runtime() self.app.core.show_mobility_players() if not result and exceptions: diff --git a/daemon/core/gui/tooltip.py b/daemon/core/gui/tooltip.py index 84a3178f..f80dbe3f 100644 --- a/daemon/core/gui/tooltip.py +++ b/daemon/core/gui/tooltip.py @@ -5,7 +5,7 @@ from typing import Optional from core.gui.themes import Styles -class Tooltip(object): +class Tooltip: """ Create tool tip for a given widget """ diff --git a/daemon/core/gui/validation.py b/daemon/core/gui/validation.py index 2360ab0b..61500e84 100644 --- a/daemon/core/gui/validation.py +++ b/daemon/core/gui/validation.py @@ -3,8 +3,9 @@ input validation """ import re import tkinter as tk +from re import Pattern from tkinter import ttk -from typing import Any, Optional, Pattern +from typing import Any, Optional SMALLEST_SCALE: float = 0.5 LARGEST_SCALE: float = 5.0 diff --git a/daemon/core/gui/widgets.py b/daemon/core/gui/widgets.py index 7dfd2666..902f1132 100644 --- a/daemon/core/gui/widgets.py +++ b/daemon/core/gui/widgets.py @@ -3,7 +3,7 @@ import tkinter as tk from functools import partial from pathlib import Path from tkinter import filedialog, font, ttk -from typing import TYPE_CHECKING, Any, Callable, Dict, Set, Type +from typing import TYPE_CHECKING, Any, Callable from core.api.grpc.wrappers import ConfigOption, ConfigOptionType from core.gui import appconfig, themes, validation @@ -15,7 +15,7 @@ logger = logging.getLogger(__name__) if TYPE_CHECKING: from core.gui.app import Application -INT_TYPES: Set[ConfigOptionType] = { +INT_TYPES: set[ConfigOptionType] = { ConfigOptionType.UINT8, ConfigOptionType.UINT16, ConfigOptionType.UINT32, @@ -40,7 +40,7 @@ class FrameScroll(ttk.Frame): self, master: tk.Widget, app: "Application", - _cls: Type[ttk.Frame] = ttk.Frame, + _cls: type[ttk.Frame] = ttk.Frame, **kw: Any ) -> None: super().__init__(master, **kw) @@ -86,14 +86,14 @@ class ConfigFrame(ttk.Notebook): self, master: tk.Widget, app: "Application", - config: Dict[str, ConfigOption], + config: dict[str, ConfigOption], enabled: bool = True, **kw: Any ) -> None: super().__init__(master, **kw) self.app: "Application" = app - self.config: Dict[str, ConfigOption] = config - self.values: Dict[str, tk.StringVar] = {} + self.config: dict[str, ConfigOption] = config + self.values: dict[str, tk.StringVar] = {} self.enabled: bool = enabled def draw_config(self) -> None: @@ -166,7 +166,7 @@ class ConfigFrame(ttk.Notebook): logger.error("unhandled config option type: %s", option.type) self.values[option.name] = value - def parse_config(self) -> Dict[str, str]: + def parse_config(self) -> dict[str, str]: for key in self.config: option = self.config[key] value = self.values[key] @@ -180,7 +180,7 @@ class ConfigFrame(ttk.Notebook): option.value = config_value return {x: self.config[x].value for x in self.config} - def set_values(self, config: Dict[str, str]) -> None: + def set_values(self, config: dict[str, str]) -> None: for name, data in config.items(): option = self.config[name] value = self.values[name]