Просмотр исходного кода

Closes #10699: Remove custom import_object() function

jeremystretch 3 лет назад
Родитель
Сommit
85a4b1f881

+ 1 - 0
docs/release-notes/version-3.4.md

@@ -40,6 +40,7 @@ A new `PluginMenu` class has been introduced, which enables a plugin to inject a
 * [#9045](https://github.com/netbox-community/netbox/issues/9045) - Remove legacy ASN field from provider model
 * [#9046](https://github.com/netbox-community/netbox/issues/9046) - Remove legacy contact fields from provider model
 * [#10358](https://github.com/netbox-community/netbox/issues/10358) - Raise minimum required PostgreSQL version from 10 to 11
+* [#10699](https://github.com/netbox-community/netbox/issues/10699) - Remove custom `import_object()` function
 
 ### REST API Changes
 

+ 29 - 14
netbox/extras/plugins/__init__.py

@@ -5,8 +5,8 @@ from packaging import version
 from django.apps import AppConfig
 from django.core.exceptions import ImproperlyConfigured
 from django.template.loader import get_template
+from django.utils.module_loading import import_string
 
-from extras.plugins.utils import import_object
 from extras.registry import registry
 from netbox.navigation import MenuGroup
 from netbox.search import register_search
@@ -71,31 +71,46 @@ class PluginConfig(AppConfig):
     def ready(self):
         plugin_name = self.name.rsplit('.', 1)[-1]
 
-        # Search extensions
-        search_indexes = import_object(f"{self.__module__}.{self.search_indexes}") or []
-        for idx in search_indexes:
-            register_search()(idx)
+        # Register search extensions (if defined)
+        try:
+            search_indexes = import_string(f"{self.__module__}.{self.search_indexes}")
+            for idx in search_indexes:
+                register_search()(idx)
+        except ImportError:
+            pass
 
         # Register template content (if defined)
-        template_extensions = import_object(f"{self.__module__}.{self.template_extensions}")
-        if template_extensions is not None:
+        try:
+            template_extensions = import_string(f"{self.__module__}.{self.template_extensions}")
             register_template_extensions(template_extensions)
+        except ImportError:
+            pass
 
-        # Register navigation menu or menu items (if defined)
-        if menu := import_object(f"{self.__module__}.{self.menu}"):
+        # Register navigation menu and/or menu items (if defined)
+        try:
+            menu = import_string(f"{self.__module__}.{self.menu}")
             register_menu(menu)
-        if menu_items := import_object(f"{self.__module__}.{self.menu_items}"):
+        except ImportError:
+            pass
+        try:
+            menu_items = import_string(f"{self.__module__}.{self.menu_items}")
             register_menu_items(self.verbose_name, menu_items)
+        except ImportError:
+            pass
 
         # Register GraphQL schema (if defined)
-        graphql_schema = import_object(f"{self.__module__}.{self.graphql_schema}")
-        if graphql_schema is not None:
+        try:
+            graphql_schema = import_string(f"{self.__module__}.{self.graphql_schema}")
             register_graphql_schema(graphql_schema)
+        except ImportError:
+            pass
 
         # Register user preferences (if defined)
-        user_preferences = import_object(f"{self.__module__}.{self.user_preferences}")
-        if user_preferences is not None:
+        try:
+            user_preferences = import_string(f"{self.__module__}.{self.user_preferences}")
             register_user_preferences(plugin_name, user_preferences)
+        except ImportError:
+            pass
 
     @classmethod
     def validate(cls, user_config, netbox_version):

+ 9 - 6
netbox/extras/plugins/urls.py

@@ -3,8 +3,7 @@ from django.conf import settings
 from django.conf.urls import include
 from django.contrib.admin.views.decorators import staff_member_required
 from django.urls import path
-
-from extras.plugins.utils import import_object
+from django.utils.module_loading import import_string
 
 from . import views
 
@@ -25,15 +24,19 @@ for plugin_path in settings.PLUGINS:
     base_url = getattr(app, 'base_url') or app.label
 
     # Check if the plugin specifies any base URLs
-    urlpatterns = import_object(f"{plugin_path}.urls.urlpatterns")
-    if urlpatterns is not None:
+    try:
+        urlpatterns = import_string(f"{plugin_path}.urls.urlpatterns")
         plugin_patterns.append(
             path(f"{base_url}/", include((urlpatterns, app.label)))
         )
+    except ImportError:
+        pass
 
     # Check if the plugin specifies any API URLs
-    urlpatterns = import_object(f"{plugin_path}.api.urls.urlpatterns")
-    if urlpatterns is not None:
+    try:
+        urlpatterns = import_string(f"{plugin_path}.api.urls.urlpatterns")
         plugin_api_patterns.append(
             path(f"{base_url}/", include((urlpatterns, f"{app.label}-api")))
         )
+    except ImportError:
+        pass

+ 0 - 33
netbox/extras/plugins/utils.py

@@ -1,33 +0,0 @@
-import importlib.util
-import sys
-
-
-def import_object(module_and_object):
-    """
-    Import a specific object from a specific module by name, such as "extras.plugins.utils.import_object".
-
-    Returns the imported object, or None if it doesn't exist.
-    """
-    target_module_name, object_name = module_and_object.rsplit('.', 1)
-    module_hierarchy = target_module_name.split('.')
-
-    # Iterate through the module hierarchy, checking for the existence of each successive submodule.
-    # We have to do this rather than jumping directly to calling find_spec(target_module_name)
-    # because find_spec will raise a ModuleNotFoundError if any parent module of target_module_name does not exist.
-    module_name = ""
-    for module_component in module_hierarchy:
-        module_name = f"{module_name}.{module_component}" if module_name else module_component
-        spec = importlib.util.find_spec(module_name)
-        if spec is None:
-            # No such module
-            return None
-
-    # Okay, target_module_name exists. Load it if not already loaded
-    if target_module_name in sys.modules:
-        module = sys.modules[target_module_name]
-    else:
-        module = importlib.util.module_from_spec(spec)
-        sys.modules[target_module_name] = module
-        spec.loader.exec_module(module)
-
-    return getattr(module, object_name, None)