diff --git a/modules/extensions.py b/modules/extensions.py index 9a3e1f7f6..1063e5eb7 100644 --- a/modules/extensions.py +++ b/modules/extensions.py @@ -1,3 +1,4 @@ +from __future__ import annotations import os from datetime import datetime import git @@ -5,7 +6,7 @@ from modules import shared, errors from modules.paths import extensions_dir, extensions_builtin_dir -extensions = [] +extensions: list[Extension] = [] if not os.path.exists(extensions_dir): os.makedirs(extensions_dir) diff --git a/modules/options.py b/modules/options.py index 49dc1f9ad..6e31c8660 100644 --- a/modules/options.py +++ b/modules/options.py @@ -1,8 +1,18 @@ +from __future__ import annotations from dataclasses import dataclass +from typing import TYPE_CHECKING, Any from installer import log -def options_section(section_identifier, options_dict): +if TYPE_CHECKING: + from collections.abc import Callable + from gradio.components import Component + from modules.shared_legacy import LegacyOption + from modules.ui_components import DropdownEditable + + +def options_section(section_identifier: tuple[str, str], options_dict: dict[str, OptionInfo | LegacyOption]): + """Set the `section` value for all OptionInfo/LegacyOption items""" for v in options_dict.values(): v.section = section_identifier return options_dict @@ -11,14 +21,14 @@ def options_section(section_identifier, options_dict): class OptionInfo: def __init__( self, - default=None, + default: Any | None = None, label="", - component=None, - component_args=None, - onchange=None, - section=None, - refresh=None, - folder=None, + component: type[Component] | type[DropdownEditable] | None = None, + component_args: dict | Callable[..., dict] | None = None, + onchange: Callable | None = None, + section: tuple[str, ...] | None = None, + refresh: Callable | None = None, + folder=False, submit=None, comment_before='', comment_after='', @@ -40,7 +50,7 @@ class OptionInfo: self.exclude = ['sd_model_checkpoint', 'sd_model_refiner', 'sd_vae', 'sd_unet', 'sd_text_encoder'] self.dynamic = callable(component_args) args = {} if self.dynamic else (component_args or {}) # executing callable here is too expensive - self.visible = args.get('visible', True) and len(self.label) > 2 + self.visible = args.get('visible', True) and len(self.label) > 2 # type: ignore - Type checking only sees the value of self.dynamic, not the `callable` check def needs_reload_ui(self): return self diff --git a/modules/options_handler.py b/modules/options_handler.py index a8538a383..6d7ae67c6 100644 --- a/modules/options_handler.py +++ b/modules/options_handler.py @@ -1,3 +1,4 @@ +from __future__ import annotations import os import json import threading @@ -6,10 +7,12 @@ from modules import cmd_args, errors from modules.json_helpers import readfile, writefile from modules.shared_legacy import LegacyOption from installer import log -if TYPE_CHECKING: - from modules.options import OptionInfo +if TYPE_CHECKING: + from collections.abc import Callable + from modules.options import OptionInfo + cmd_opts = cmd_args.parse_args() compatibility_opts = ['clip_skip', 'uni_pc_lower_order_final', 'uni_pc_order'] @@ -21,7 +24,9 @@ class Options(): typemap = {int: float} debug = os.environ.get('SD_CONFIG_DEBUG', None) is not None - def __init__(self, options_templates:dict={}, restricted_opts:dict={}): + def __init__(self, options_templates: dict[str, OptionInfo | LegacyOption] = {}, restricted_opts: set[str] | None = None): + if restricted_opts is None: + restricted_opts = set() self.data_labels = options_templates self.restricted_opts = restricted_opts self.data = {k: v.default for k, v in self.data_labels.items()} @@ -168,7 +173,7 @@ class Options(): self.data['quicksettings_list'] = [i.strip() for i in self.data.get('quicksettings').split(',')] unknown_settings = [] for k, v in self.data.items(): - info: OptionInfo = self.data_labels.get(k, None) + info: OptionInfo | None = self.data_labels.get(k, None) if info is not None: if not info.validate(k, v): self.data[k] = info.default @@ -180,7 +185,7 @@ class Options(): if len(unknown_settings) > 0: log.warning(f"Setting validation: unknown={unknown_settings}") - def onchange(self, key, func, call=True): + def onchange(self, key, func: Callable, call=True): item = self.data_labels.get(key) item.onchange = func if call: diff --git a/modules/shared.py b/modules/shared.py index 1ac08ab9a..16a4a0797 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -27,7 +27,8 @@ from installer import log, print_dict, console, get_version # pylint: disable=un if TYPE_CHECKING: # Behavior modified by __future__.annotations from diffusers import DiffusionPipeline - from ui_extra_networks import ExtraNetworksPage + from modules.shared_legacy import LegacyOption + from modules.ui_extra_networks import ExtraNetworksPage class Backend(Enum): @@ -51,7 +52,7 @@ face_restorers = [] yolo = None tab_names = [] extra_networks: list[ExtraNetworksPage] = [] -options_templates = {} +options_templates: dict[str, OptionInfo | LegacyOption] = {} hypernetworks = {} settings_components = {} restricted_opts = { diff --git a/modules/ui_extensions.py b/modules/ui_extensions.py index 836fe5db6..a44211d7b 100644 --- a/modules/ui_extensions.py +++ b/modules/ui_extensions.py @@ -29,8 +29,8 @@ sort_ordering = { } -def get_installed(ext) -> extensions.Extension: - installed: extensions.Extension = [e for e in extensions.extensions if (e.remote or '').startswith(ext['url'].replace('.git', ''))] +def get_installed(ext): + installed = [e for e in extensions.extensions if (e.remote or '').startswith(ext['url'].replace('.git', ''))] return installed[0] if len(installed) > 0 else None diff --git a/modules/ui_settings.py b/modules/ui_settings.py index 2f4bcaa2d..fc6bfa1e2 100644 --- a/modules/ui_settings.py +++ b/modules/ui_settings.py @@ -84,7 +84,7 @@ def create_setting_component(key, is_quicksettings=False): with gr.Row(): res = comp(label=info.label, value=fun(), elem_id=elem_id, **args) ui_common.create_refresh_button(res, info.refresh, info.component_args, f"settings_{key}_refresh") - elif info.folder is not None: + elif info.folder: with gr.Row(): res = comp(label=info.label, value=fun(), elem_id=elem_id, elem_classes="folder-selector", **args) else: