mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
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:
parent
35577fad41
commit
8807492db6
@ -8,7 +8,7 @@ import os
|
|||||||
import os.path
|
import os.path
|
||||||
import re
|
import re
|
||||||
from decimal import Decimal, InvalidOperation
|
from decimal import Decimal, InvalidOperation
|
||||||
from typing import Set, Type, TypeVar
|
from typing import TypeVar
|
||||||
from wsgiref.util import FileWrapper
|
from wsgiref.util import FileWrapper
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -889,7 +889,7 @@ def get_objectreference(
|
|||||||
Inheritors_T = TypeVar('Inheritors_T')
|
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."""
|
"""Return all classes that are subclasses from the supplied cls."""
|
||||||
subcls = set()
|
subcls = set()
|
||||||
work = [cls]
|
work = [cls]
|
||||||
|
@ -9,7 +9,7 @@ import time
|
|||||||
import warnings
|
import warnings
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import Callable, List
|
from typing import Callable
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import AppRegistryNotReady
|
from django.core.exceptions import AppRegistryNotReady
|
||||||
@ -291,7 +291,7 @@ class ScheduledTask:
|
|||||||
class TaskRegister:
|
class TaskRegister:
|
||||||
"""Registry for periodic tasks."""
|
"""Registry for periodic tasks."""
|
||||||
|
|
||||||
task_list: List[ScheduledTask] = []
|
task_list: list[ScheduledTask] = []
|
||||||
|
|
||||||
def register(self, task, schedule, minutes: int = None):
|
def register(self, task, schedule, minutes: int = None):
|
||||||
"""Register a task with the que."""
|
"""Register a task with the que."""
|
||||||
|
@ -16,7 +16,7 @@ import uuid
|
|||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from secrets import compare_digest
|
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.apps import apps
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -157,7 +157,7 @@ class SettingsKeyType(TypedDict, total=False):
|
|||||||
units: Units of the particular setting (optional)
|
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, ...)
|
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)
|
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)
|
hidden: Hide this setting from settings page (optional)
|
||||||
before_save: Function that gets called after save with *args, **kwargs (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)
|
after_save: Function that gets called after save with *args, **kwargs (optional)
|
||||||
@ -169,9 +169,9 @@ class SettingsKeyType(TypedDict, total=False):
|
|||||||
name: str
|
name: str
|
||||||
description: str
|
description: str
|
||||||
units: str
|
units: str
|
||||||
validator: Union[Callable, List[Callable], Tuple[Callable]]
|
validator: Union[Callable, list[Callable], tuple[Callable]]
|
||||||
default: Union[Callable, Any]
|
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
|
hidden: bool
|
||||||
before_save: Callable[..., None]
|
before_save: Callable[..., None]
|
||||||
after_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
|
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:
|
class Meta:
|
||||||
"""Meta options for BaseInvenTreeSetting -> abstract stops creation of database entry."""
|
"""Meta options for BaseInvenTreeSetting -> abstract stops creation of database entry."""
|
||||||
@ -332,7 +332,7 @@ class BaseInvenTreeSetting(models.Model):
|
|||||||
cls,
|
cls,
|
||||||
*,
|
*,
|
||||||
exclude_hidden=False,
|
exclude_hidden=False,
|
||||||
settings_definition: Union[Dict[str, SettingsKeyType], None] = None,
|
settings_definition: Union[dict[str, SettingsKeyType], None] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Return a list of "all" defined settings.
|
"""Return a list of "all" defined settings.
|
||||||
@ -352,7 +352,7 @@ class BaseInvenTreeSetting(models.Model):
|
|||||||
# Optionally filter by other keys
|
# Optionally filter by other keys
|
||||||
results = results.filter(**filters)
|
results = results.filter(**filters)
|
||||||
|
|
||||||
settings: Dict[str, BaseInvenTreeSetting] = {}
|
settings: dict[str, BaseInvenTreeSetting] = {}
|
||||||
|
|
||||||
# Query the database
|
# Query the database
|
||||||
for setting in results:
|
for setting in results:
|
||||||
@ -394,7 +394,7 @@ class BaseInvenTreeSetting(models.Model):
|
|||||||
cls,
|
cls,
|
||||||
*,
|
*,
|
||||||
exclude_hidden=False,
|
exclude_hidden=False,
|
||||||
settings_definition: Union[Dict[str, SettingsKeyType], None] = None,
|
settings_definition: Union[dict[str, SettingsKeyType], None] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Return a dict of "all" defined global settings.
|
"""Return a dict of "all" defined global settings.
|
||||||
@ -409,7 +409,7 @@ class BaseInvenTreeSetting(models.Model):
|
|||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
|
|
||||||
settings: Dict[str, Any] = {}
|
settings: dict[str, Any] = {}
|
||||||
|
|
||||||
for key, setting in all_settings.items():
|
for key, setting in all_settings.items():
|
||||||
settings[key] = setting.value
|
settings[key] = setting.value
|
||||||
@ -421,7 +421,7 @@ class BaseInvenTreeSetting(models.Model):
|
|||||||
cls,
|
cls,
|
||||||
*,
|
*,
|
||||||
exclude_hidden=False,
|
exclude_hidden=False,
|
||||||
settings_definition: Union[Dict[str, SettingsKeyType], None] = None,
|
settings_definition: Union[dict[str, SettingsKeyType], None] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Check if all required settings are set by definition.
|
"""Check if all required settings are set by definition.
|
||||||
@ -436,7 +436,7 @@ class BaseInvenTreeSetting(models.Model):
|
|||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
|
|
||||||
missing_settings: List[str] = []
|
missing_settings: list[str] = []
|
||||||
|
|
||||||
for setting in all_settings.values():
|
for setting in all_settings.values():
|
||||||
if setting.required:
|
if setting.required:
|
||||||
@ -1171,6 +1171,16 @@ def reload_plugin_registry(setting):
|
|||||||
registry.reload_plugins(full_reload=True, force_reload=True, collect=True)
|
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):
|
class InvenTreeSetting(BaseInvenTreeSetting):
|
||||||
"""An InvenTreeSetting object is a key:value pair used for storing single values (e.g. one-off settings values).
|
"""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.
|
even if that key does not exist.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
SETTINGS: dict[str, InvenTreeSettingsKeyType]
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Meta options for InvenTreeSetting."""
|
"""Meta options for InvenTreeSetting."""
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
"""Base machine type/base driver."""
|
"""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 generic.states import StatusCode
|
||||||
from InvenTree.helpers_mixin import ClassProviderMixin, ClassValidationMixin
|
from InvenTree.helpers_mixin import ClassProviderMixin, ClassValidationMixin
|
||||||
@ -59,7 +59,7 @@ class BaseDriver(ClassValidationMixin, ClassProviderMixin):
|
|||||||
NAME: str
|
NAME: str
|
||||||
DESCRIPTION: str
|
DESCRIPTION: str
|
||||||
|
|
||||||
MACHINE_SETTINGS: Dict[str, SettingsKeyType]
|
MACHINE_SETTINGS: dict[str, SettingsKeyType]
|
||||||
|
|
||||||
machine_type: str
|
machine_type: str
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ class BaseDriver(ClassValidationMixin, ClassProviderMixin):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def update_machine(
|
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.
|
"""This method gets called for each update of a machine.
|
||||||
|
|
||||||
@ -156,11 +156,11 @@ class BaseMachineType(ClassValidationMixin, ClassProviderMixin):
|
|||||||
NAME: str
|
NAME: str
|
||||||
DESCRIPTION: 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
|
default_machine_status: MachineStatus
|
||||||
|
|
||||||
# used by the ClassValidationMixin
|
# used by the ClassValidationMixin
|
||||||
@ -194,15 +194,15 @@ class BaseMachineType(ClassValidationMixin, ClassProviderMixin):
|
|||||||
f"'{self.driver.NAME}' is incompatible with machine type '{self.NAME}'"
|
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, 'MACHINE_SETTINGS', {}
|
||||||
)
|
)
|
||||||
self.driver_settings: Dict[str, SettingsKeyType] = getattr(
|
self.driver_settings: dict[str, SettingsKeyType] = getattr(
|
||||||
self.driver, 'MACHINE_SETTINGS', {}
|
self.driver, 'MACHINE_SETTINGS', {}
|
||||||
)
|
)
|
||||||
|
|
||||||
self.setting_types: List[
|
self.setting_types: list[
|
||||||
Tuple[Dict[str, SettingsKeyType], MachineSetting.ConfigType]
|
tuple[dict[str, SettingsKeyType], MachineSetting.ConfigType]
|
||||||
] = [
|
] = [
|
||||||
(self.machine_settings, MachineSetting.ConfigType.MACHINE),
|
(self.machine_settings, MachineSetting.ConfigType.MACHINE),
|
||||||
(self.driver_settings, MachineSetting.ConfigType.DRIVER),
|
(self.driver_settings, MachineSetting.ConfigType.DRIVER),
|
||||||
@ -339,11 +339,11 @@ class BaseMachineType(ClassValidationMixin, ClassProviderMixin):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
is_valid: Are all required settings defined
|
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
|
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:
|
for settings, config_type in self.setting_types:
|
||||||
is_valid, missing = MachineSetting.check_all_settings(
|
is_valid, missing = MachineSetting.check_all_settings(
|
||||||
settings_definition=settings,
|
settings_definition=settings,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Machine registry."""
|
"""Machine registry."""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict, List, Set, Type, Union
|
from typing import Union
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from machine.machine_type import BaseDriver, BaseMachineType
|
from machine.machine_type import BaseDriver, BaseMachineType
|
||||||
@ -17,12 +17,12 @@ class MachineRegistry:
|
|||||||
|
|
||||||
Set up all needed references for internal and external states.
|
Set up all needed references for internal and external states.
|
||||||
"""
|
"""
|
||||||
self.machine_types: Dict[str, Type[BaseMachineType]] = {}
|
self.machine_types: dict[str, type[BaseMachineType]] = {}
|
||||||
self.drivers: Dict[str, Type[BaseDriver]] = {}
|
self.drivers: dict[str, type[BaseDriver]] = {}
|
||||||
self.driver_instances: Dict[str, BaseDriver] = {}
|
self.driver_instances: dict[str, BaseDriver] = {}
|
||||||
self.machines: Dict[str, BaseMachineType] = {}
|
self.machines: dict[str, BaseMachineType] = {}
|
||||||
|
|
||||||
self.base_drivers: List[Type[BaseDriver]] = []
|
self.base_drivers: list[type[BaseDriver]] = []
|
||||||
self.errors: list[Union[str, Exception]] = []
|
self.errors: list[Union[str, Exception]] = []
|
||||||
|
|
||||||
def handle_error(self, error: Union[Exception, str]):
|
def handle_error(self, error: Union[Exception, str]):
|
||||||
@ -41,10 +41,10 @@ class MachineRegistry:
|
|||||||
|
|
||||||
logger.debug('Collecting machine types')
|
logger.debug('Collecting machine types')
|
||||||
|
|
||||||
machine_types: Dict[str, Type[BaseMachineType]] = {}
|
machine_types: dict[str, type[BaseMachineType]] = {}
|
||||||
base_drivers: List[Type[BaseDriver]] = []
|
base_drivers: list[type[BaseDriver]] = []
|
||||||
|
|
||||||
discovered_machine_types: Set[Type[BaseMachineType]] = (
|
discovered_machine_types: set[type[BaseMachineType]] = (
|
||||||
InvenTree.helpers.inheritors(BaseMachineType)
|
InvenTree.helpers.inheritors(BaseMachineType)
|
||||||
)
|
)
|
||||||
for machine_type in discovered_machine_types:
|
for machine_type in discovered_machine_types:
|
||||||
@ -74,9 +74,9 @@ class MachineRegistry:
|
|||||||
|
|
||||||
logger.debug('Collecting machine drivers')
|
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
|
BaseDriver
|
||||||
)
|
)
|
||||||
for driver in discovered_drivers:
|
for driver in discovered_drivers:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
"""Serializers for the machine app."""
|
"""Serializers for the machine app."""
|
||||||
|
|
||||||
from typing import List, Union
|
from typing import Union
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ class MachineConfigSerializer(serializers.ModelSerializer):
|
|||||||
"""Serializer method for the status text field."""
|
"""Serializer method for the status text field."""
|
||||||
return getattr(obj.machine, 'status_text', '')
|
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."""
|
"""Serializer method for the errors field."""
|
||||||
return [str(err) for err in obj.errors]
|
return [str(err) for err in obj.errors]
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ class MachineDriverSerializer(BaseMachineClassSerializer):
|
|||||||
|
|
||||||
driver_errors = serializers.SerializerMethodField('get_errors')
|
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."""
|
"""Serializer method for the errors field."""
|
||||||
driver_instance = registry.driver_instances.get(obj.SLUG, None)
|
driver_instance = registry.driver_instances.get(obj.SLUG, None)
|
||||||
if driver_instance is None:
|
if driver_instance is None:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Plugin mixin class for SettingsMixin."""
|
"""Plugin mixin class for SettingsMixin."""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from typing import TYPE_CHECKING, Dict
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from django.db.utils import OperationalError, ProgrammingError
|
from django.db.utils import OperationalError, ProgrammingError
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ else:
|
|||||||
class SettingsMixin:
|
class SettingsMixin:
|
||||||
"""Mixin that enables global settings for the plugin."""
|
"""Mixin that enables global settings for the plugin."""
|
||||||
|
|
||||||
SETTINGS: Dict[str, SettingsKeyType] = {}
|
SETTINGS: dict[str, SettingsKeyType] = {}
|
||||||
|
|
||||||
class MixinMeta:
|
class MixinMeta:
|
||||||
"""Meta for mixin."""
|
"""Meta for mixin."""
|
||||||
|
@ -9,9 +9,10 @@ import importlib
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
from collections import OrderedDict
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
from typing import Any, Dict, List, OrderedDict
|
from typing import Any
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -52,19 +53,19 @@ class PluginsRegistry:
|
|||||||
Set up all needed references for internal and external states.
|
Set up all needed references for internal and external states.
|
||||||
"""
|
"""
|
||||||
# plugin registry
|
# plugin registry
|
||||||
self.plugins: Dict[str, InvenTreePlugin] = {} # List of active instances
|
self.plugins: dict[str, InvenTreePlugin] = {} # List of active instances
|
||||||
self.plugins_inactive: Dict[
|
self.plugins_inactive: dict[
|
||||||
str, InvenTreePlugin
|
str, InvenTreePlugin
|
||||||
] = {} # List of inactive instances
|
] = {} # List of inactive instances
|
||||||
self.plugins_full: Dict[
|
self.plugins_full: dict[
|
||||||
str, InvenTreePlugin
|
str, InvenTreePlugin
|
||||||
] = {} # List of all plugin instances
|
] = {} # List of all plugin instances
|
||||||
|
|
||||||
# Keep an internal hash of the plugin registry state
|
# Keep an internal hash of the plugin registry state
|
||||||
self.registry_hash = None
|
self.registry_hash = None
|
||||||
|
|
||||||
self.plugin_modules: List[InvenTreePlugin] = [] # Holds all discovered plugins
|
self.plugin_modules: list[InvenTreePlugin] = [] # Holds all discovered plugins
|
||||||
self.mixin_modules: Dict[str, Any] = {} # Holds all discovered mixins
|
self.mixin_modules: dict[str, Any] = {} # Holds all discovered mixins
|
||||||
|
|
||||||
self.errors = {} # Holds discovering errors
|
self.errors = {} # Holds discovering errors
|
||||||
|
|
||||||
@ -682,9 +683,9 @@ class PluginsRegistry:
|
|||||||
|
|
||||||
def _clean_registry(self):
|
def _clean_registry(self):
|
||||||
"""Remove all plugins from registry."""
|
"""Remove all plugins from registry."""
|
||||||
self.plugins: Dict[str, InvenTreePlugin] = {}
|
self.plugins: dict[str, InvenTreePlugin] = {}
|
||||||
self.plugins_inactive: Dict[str, InvenTreePlugin] = {}
|
self.plugins_inactive: dict[str, InvenTreePlugin] = {}
|
||||||
self.plugins_full: Dict[str, InvenTreePlugin] = {}
|
self.plugins_full: dict[str, InvenTreePlugin] = {}
|
||||||
|
|
||||||
def _update_urls(self):
|
def _update_urls(self):
|
||||||
"""Due to the order in which plugins are loaded, the patterns in urls.py may be out of date.
|
"""Due to the order in which plugins are loaded, the patterns in urls.py may be out of date.
|
||||||
|
Loading…
Reference in New Issue
Block a user