Fix settings typing and use generics from standard collection (#6487)

* Fix settings typing and use generics from standard collection

* Fix docstring
This commit is contained in:
Lukas 2024-02-15 12:44:32 +01:00 committed by GitHub
parent 35577fad41
commit 8807492db6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 66 additions and 53 deletions

View File

@ -8,7 +8,7 @@ import os
import os.path
import re
from decimal import Decimal, InvalidOperation
from typing import Set, Type, TypeVar
from typing import TypeVar
from wsgiref.util import FileWrapper
from django.conf import settings
@ -889,7 +889,7 @@ def get_objectreference(
Inheritors_T = TypeVar('Inheritors_T')
def inheritors(cls: Type[Inheritors_T]) -> Set[Type[Inheritors_T]]:
def inheritors(cls: type[Inheritors_T]) -> set[type[Inheritors_T]]:
"""Return all classes that are subclasses from the supplied cls."""
subcls = set()
work = [cls]

View File

@ -9,7 +9,7 @@ import time
import warnings
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import Callable, List
from typing import Callable
from django.conf import settings
from django.core.exceptions import AppRegistryNotReady
@ -291,7 +291,7 @@ class ScheduledTask:
class TaskRegister:
"""Registry for periodic tasks."""
task_list: List[ScheduledTask] = []
task_list: list[ScheduledTask] = []
def register(self, task, schedule, minutes: int = None):
"""Register a task with the que."""

View File

@ -16,7 +16,7 @@ import uuid
from datetime import datetime, timedelta, timezone
from enum import Enum
from secrets import compare_digest
from typing import Any, Callable, Dict, List, Tuple, TypedDict, Union
from typing import Any, Callable, TypedDict, Union
from django.apps import apps
from django.conf import settings
@ -157,7 +157,7 @@ class SettingsKeyType(TypedDict, total=False):
units: Units of the particular setting (optional)
validator: Validation function/list of functions for the setting (optional, default: None, e.g: bool, int, str, MinValueValidator, ...)
default: Default value or function that returns default value (optional)
choices: (Function that returns) Tuple[str: key, str: display value] (optional)
choices: Function that returns or value of list[tuple[str: key, str: display value]] (optional)
hidden: Hide this setting from settings page (optional)
before_save: Function that gets called after save with *args, **kwargs (optional)
after_save: Function that gets called after save with *args, **kwargs (optional)
@ -169,9 +169,9 @@ class SettingsKeyType(TypedDict, total=False):
name: str
description: str
units: str
validator: Union[Callable, List[Callable], Tuple[Callable]]
validator: Union[Callable, list[Callable], tuple[Callable]]
default: Union[Callable, Any]
choices: Union[Tuple[str, str], Callable[[], Tuple[str, str]]]
choices: Union[list[tuple[str, str]], Callable[[], list[tuple[str, str]]]]
hidden: bool
before_save: Callable[..., None]
after_save: Callable[..., None]
@ -188,9 +188,9 @@ class BaseInvenTreeSetting(models.Model):
extra_unique_fields: List of extra fields used to be unique, e.g. for PluginConfig -> plugin
"""
SETTINGS: Dict[str, SettingsKeyType] = {}
SETTINGS: dict[str, SettingsKeyType] = {}
extra_unique_fields: List[str] = []
extra_unique_fields: list[str] = []
class Meta:
"""Meta options for BaseInvenTreeSetting -> abstract stops creation of database entry."""
@ -332,7 +332,7 @@ class BaseInvenTreeSetting(models.Model):
cls,
*,
exclude_hidden=False,
settings_definition: Union[Dict[str, SettingsKeyType], None] = None,
settings_definition: Union[dict[str, SettingsKeyType], None] = None,
**kwargs,
):
"""Return a list of "all" defined settings.
@ -352,7 +352,7 @@ class BaseInvenTreeSetting(models.Model):
# Optionally filter by other keys
results = results.filter(**filters)
settings: Dict[str, BaseInvenTreeSetting] = {}
settings: dict[str, BaseInvenTreeSetting] = {}
# Query the database
for setting in results:
@ -394,7 +394,7 @@ class BaseInvenTreeSetting(models.Model):
cls,
*,
exclude_hidden=False,
settings_definition: Union[Dict[str, SettingsKeyType], None] = None,
settings_definition: Union[dict[str, SettingsKeyType], None] = None,
**kwargs,
):
"""Return a dict of "all" defined global settings.
@ -409,7 +409,7 @@ class BaseInvenTreeSetting(models.Model):
**kwargs,
)
settings: Dict[str, Any] = {}
settings: dict[str, Any] = {}
for key, setting in all_settings.items():
settings[key] = setting.value
@ -421,7 +421,7 @@ class BaseInvenTreeSetting(models.Model):
cls,
*,
exclude_hidden=False,
settings_definition: Union[Dict[str, SettingsKeyType], None] = None,
settings_definition: Union[dict[str, SettingsKeyType], None] = None,
**kwargs,
):
"""Check if all required settings are set by definition.
@ -436,7 +436,7 @@ class BaseInvenTreeSetting(models.Model):
**kwargs,
)
missing_settings: List[str] = []
missing_settings: list[str] = []
for setting in all_settings.values():
if setting.required:
@ -1171,6 +1171,16 @@ def reload_plugin_registry(setting):
registry.reload_plugins(full_reload=True, force_reload=True, collect=True)
class InvenTreeSettingsKeyType(SettingsKeyType):
"""InvenTreeSettingsKeyType has additional properties only global settings support.
Attributes:
requires_restart: If True, a server restart is required after changing the setting
"""
requires_restart: bool
class InvenTreeSetting(BaseInvenTreeSetting):
"""An InvenTreeSetting object is a key:value pair used for storing single values (e.g. one-off settings values).
@ -1178,6 +1188,8 @@ class InvenTreeSetting(BaseInvenTreeSetting):
even if that key does not exist.
"""
SETTINGS: dict[str, InvenTreeSettingsKeyType]
class Meta:
"""Meta options for InvenTreeSetting."""

View File

@ -1,6 +1,6 @@
"""Base machine type/base driver."""
from typing import TYPE_CHECKING, Any, Dict, List, Literal, Tuple, Type, Union
from typing import TYPE_CHECKING, Any, Literal, Union
from generic.states import StatusCode
from InvenTree.helpers_mixin import ClassProviderMixin, ClassValidationMixin
@ -59,7 +59,7 @@ class BaseDriver(ClassValidationMixin, ClassProviderMixin):
NAME: str
DESCRIPTION: str
MACHINE_SETTINGS: Dict[str, SettingsKeyType]
MACHINE_SETTINGS: dict[str, SettingsKeyType]
machine_type: str
@ -89,7 +89,7 @@ class BaseDriver(ClassValidationMixin, ClassProviderMixin):
"""
def update_machine(
self, old_machine_state: Dict[str, Any], machine: 'BaseMachineType'
self, old_machine_state: dict[str, Any], machine: 'BaseMachineType'
):
"""This method gets called for each update of a machine.
@ -156,11 +156,11 @@ class BaseMachineType(ClassValidationMixin, ClassProviderMixin):
NAME: str
DESCRIPTION: str
base_driver: Type[BaseDriver]
base_driver: type[BaseDriver]
MACHINE_SETTINGS: Dict[str, SettingsKeyType]
MACHINE_SETTINGS: dict[str, SettingsKeyType]
MACHINE_STATUS: Type[MachineStatus]
MACHINE_STATUS: type[MachineStatus]
default_machine_status: MachineStatus
# used by the ClassValidationMixin
@ -194,15 +194,15 @@ class BaseMachineType(ClassValidationMixin, ClassProviderMixin):
f"'{self.driver.NAME}' is incompatible with machine type '{self.NAME}'"
)
self.machine_settings: Dict[str, SettingsKeyType] = getattr(
self.machine_settings: dict[str, SettingsKeyType] = getattr(
self, 'MACHINE_SETTINGS', {}
)
self.driver_settings: Dict[str, SettingsKeyType] = getattr(
self.driver_settings: dict[str, SettingsKeyType] = getattr(
self.driver, 'MACHINE_SETTINGS', {}
)
self.setting_types: List[
Tuple[Dict[str, SettingsKeyType], MachineSetting.ConfigType]
self.setting_types: list[
tuple[dict[str, SettingsKeyType], MachineSetting.ConfigType]
] = [
(self.machine_settings, MachineSetting.ConfigType.MACHINE),
(self.driver_settings, MachineSetting.ConfigType.DRIVER),
@ -339,11 +339,11 @@ class BaseMachineType(ClassValidationMixin, ClassProviderMixin):
Returns:
is_valid: Are all required settings defined
missing_settings: Dict[ConfigType, List[str]] of all settings that are missing (empty if is_valid is 'True')
missing_settings: dict[ConfigType, list[str]] of all settings that are missing (empty if is_valid is 'True')
"""
from machine.models import MachineSetting
missing_settings: Dict[MachineSetting.ConfigType, List[str]] = {}
missing_settings: dict[MachineSetting.ConfigType, list[str]] = {}
for settings, config_type in self.setting_types:
is_valid, missing = MachineSetting.check_all_settings(
settings_definition=settings,

View File

@ -1,7 +1,7 @@
"""Machine registry."""
import logging
from typing import Dict, List, Set, Type, Union
from typing import Union
from uuid import UUID
from machine.machine_type import BaseDriver, BaseMachineType
@ -17,12 +17,12 @@ class MachineRegistry:
Set up all needed references for internal and external states.
"""
self.machine_types: Dict[str, Type[BaseMachineType]] = {}
self.drivers: Dict[str, Type[BaseDriver]] = {}
self.driver_instances: Dict[str, BaseDriver] = {}
self.machines: Dict[str, BaseMachineType] = {}
self.machine_types: dict[str, type[BaseMachineType]] = {}
self.drivers: dict[str, type[BaseDriver]] = {}
self.driver_instances: dict[str, BaseDriver] = {}
self.machines: dict[str, BaseMachineType] = {}
self.base_drivers: List[Type[BaseDriver]] = []
self.base_drivers: list[type[BaseDriver]] = []
self.errors: list[Union[str, Exception]] = []
def handle_error(self, error: Union[Exception, str]):
@ -41,10 +41,10 @@ class MachineRegistry:
logger.debug('Collecting machine types')
machine_types: Dict[str, Type[BaseMachineType]] = {}
base_drivers: List[Type[BaseDriver]] = []
machine_types: dict[str, type[BaseMachineType]] = {}
base_drivers: list[type[BaseDriver]] = []
discovered_machine_types: Set[Type[BaseMachineType]] = (
discovered_machine_types: set[type[BaseMachineType]] = (
InvenTree.helpers.inheritors(BaseMachineType)
)
for machine_type in discovered_machine_types:
@ -74,9 +74,9 @@ class MachineRegistry:
logger.debug('Collecting machine drivers')
drivers: Dict[str, Type[BaseDriver]] = {}
drivers: dict[str, type[BaseDriver]] = {}
discovered_drivers: Set[Type[BaseDriver]] = InvenTree.helpers.inheritors(
discovered_drivers: set[type[BaseDriver]] = InvenTree.helpers.inheritors(
BaseDriver
)
for driver in discovered_drivers:

View File

@ -1,6 +1,6 @@
"""Serializers for the machine app."""
from typing import List, Union
from typing import Union
from rest_framework import serializers
@ -62,7 +62,7 @@ class MachineConfigSerializer(serializers.ModelSerializer):
"""Serializer method for the status text field."""
return getattr(obj.machine, 'status_text', '')
def get_errors(self, obj: MachineConfig) -> List[str]:
def get_errors(self, obj: MachineConfig) -> list[str]:
"""Serializer method for the errors field."""
return [str(err) for err in obj.errors]
@ -165,7 +165,7 @@ class MachineDriverSerializer(BaseMachineClassSerializer):
driver_errors = serializers.SerializerMethodField('get_errors')
def get_errors(self, obj) -> List[str]:
def get_errors(self, obj) -> list[str]:
"""Serializer method for the errors field."""
driver_instance = registry.driver_instances.get(obj.SLUG, None)
if driver_instance is None:

View File

@ -1,7 +1,7 @@
"""Plugin mixin class for SettingsMixin."""
import logging
from typing import TYPE_CHECKING, Dict
from typing import TYPE_CHECKING
from django.db.utils import OperationalError, ProgrammingError
@ -21,7 +21,7 @@ else:
class SettingsMixin:
"""Mixin that enables global settings for the plugin."""
SETTINGS: Dict[str, SettingsKeyType] = {}
SETTINGS: dict[str, SettingsKeyType] = {}
class MixinMeta:
"""Meta for mixin."""

View File

@ -9,9 +9,10 @@ import importlib
import logging
import os
import time
from collections import OrderedDict
from pathlib import Path
from threading import Lock
from typing import Any, Dict, List, OrderedDict
from typing import Any
from django.apps import apps
from django.conf import settings
@ -52,19 +53,19 @@ class PluginsRegistry:
Set up all needed references for internal and external states.
"""
# plugin registry
self.plugins: Dict[str, InvenTreePlugin] = {} # List of active instances
self.plugins_inactive: Dict[
self.plugins: dict[str, InvenTreePlugin] = {} # List of active instances
self.plugins_inactive: dict[
str, InvenTreePlugin
] = {} # List of inactive instances
self.plugins_full: Dict[
self.plugins_full: dict[
str, InvenTreePlugin
] = {} # List of all plugin instances
# Keep an internal hash of the plugin registry state
self.registry_hash = None
self.plugin_modules: List[InvenTreePlugin] = [] # Holds all discovered plugins
self.mixin_modules: Dict[str, Any] = {} # Holds all discovered mixins
self.plugin_modules: list[InvenTreePlugin] = [] # Holds all discovered plugins
self.mixin_modules: dict[str, Any] = {} # Holds all discovered mixins
self.errors = {} # Holds discovering errors
@ -682,9 +683,9 @@ class PluginsRegistry:
def _clean_registry(self):
"""Remove all plugins from registry."""
self.plugins: Dict[str, InvenTreePlugin] = {}
self.plugins_inactive: Dict[str, InvenTreePlugin] = {}
self.plugins_full: Dict[str, InvenTreePlugin] = {}
self.plugins: dict[str, InvenTreePlugin] = {}
self.plugins_inactive: dict[str, InvenTreePlugin] = {}
self.plugins_full: dict[str, InvenTreePlugin] = {}
def _update_urls(self):
"""Due to the order in which plugins are loaded, the patterns in urls.py may be out of date.