From 29a611c7293741100f3e5351243dffbae8e5b481 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 1 Aug 2022 16:51:44 -0400 Subject: [PATCH] Closes #9896: Discontinue arbitrary use of OrderedDict --- netbox/dcim/api/views.py | 3 +- netbox/dcim/views.py | 44 +++++++++++----------- netbox/extras/reports.py | 17 ++++----- netbox/extras/scripts.py | 5 +-- netbox/extras/templatetags/custom_links.py | 4 +- netbox/ipam/api/serializers.py | 32 ++++++++-------- netbox/netbox/api/fields.py | 10 ++--- netbox/netbox/api/views.py | 25 ++++++------ netbox/utilities/utils.py | 3 +- 9 files changed, 65 insertions(+), 78 deletions(-) diff --git a/netbox/dcim/api/views.py b/netbox/dcim/api/views.py index 32cc3dbba..c18eab01f 100644 --- a/netbox/dcim/api/views.py +++ b/netbox/dcim/api/views.py @@ -1,5 +1,4 @@ import socket -from collections import OrderedDict from django.http import Http404, HttpResponse, HttpResponseForbidden from django.shortcuts import get_object_or_404 @@ -484,7 +483,7 @@ class DeviceViewSet(ConfigContextQuerySetMixin, NetBoxModelViewSet): return HttpResponseForbidden() napalm_methods = request.GET.getlist('method') - response = OrderedDict([(m, None) for m in napalm_methods]) + response = {m: None for m in napalm_methods} config = get_config() username = config.NAPALM_USERNAME diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 6daecb3a6..4480bee6e 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1,5 +1,3 @@ -from collections import OrderedDict - from django.contrib import messages from django.contrib.contenttypes.models import ContentType from django.core.paginator import EmptyPage, PageNotAnInteger @@ -945,18 +943,18 @@ class DeviceTypeImportView(generic.ObjectImportView): ] queryset = DeviceType.objects.all() model_form = forms.DeviceTypeImportForm - related_object_forms = OrderedDict(( - ('console-ports', forms.ConsolePortTemplateImportForm), - ('console-server-ports', forms.ConsoleServerPortTemplateImportForm), - ('power-ports', forms.PowerPortTemplateImportForm), - ('power-outlets', forms.PowerOutletTemplateImportForm), - ('interfaces', forms.InterfaceTemplateImportForm), - ('rear-ports', forms.RearPortTemplateImportForm), - ('front-ports', forms.FrontPortTemplateImportForm), - ('module-bays', forms.ModuleBayTemplateImportForm), - ('device-bays', forms.DeviceBayTemplateImportForm), - ('inventory-items', forms.InventoryItemTemplateImportForm), - )) + related_object_forms = { + 'console-ports': forms.ConsolePortTemplateImportForm, + 'console-server-ports': forms.ConsoleServerPortTemplateImportForm, + 'power-ports': forms.PowerPortTemplateImportForm, + 'power-outlets': forms.PowerOutletTemplateImportForm, + 'interfaces': forms.InterfaceTemplateImportForm, + 'rear-ports': forms.RearPortTemplateImportForm, + 'front-ports': forms.FrontPortTemplateImportForm, + 'module-bays': forms.ModuleBayTemplateImportForm, + 'device-bays': forms.DeviceBayTemplateImportForm, + 'inventory-items': forms.InventoryItemTemplateImportForm, + } def prep_related_object_data(self, parent, data): data.update({'device_type': parent}) @@ -1075,15 +1073,15 @@ class ModuleTypeImportView(generic.ObjectImportView): ] queryset = ModuleType.objects.all() model_form = forms.ModuleTypeImportForm - related_object_forms = OrderedDict(( - ('console-ports', forms.ConsolePortTemplateImportForm), - ('console-server-ports', forms.ConsoleServerPortTemplateImportForm), - ('power-ports', forms.PowerPortTemplateImportForm), - ('power-outlets', forms.PowerOutletTemplateImportForm), - ('interfaces', forms.InterfaceTemplateImportForm), - ('rear-ports', forms.RearPortTemplateImportForm), - ('front-ports', forms.FrontPortTemplateImportForm), - )) + related_object_forms = { + 'console-ports': forms.ConsolePortTemplateImportForm, + 'console-server-ports': forms.ConsoleServerPortTemplateImportForm, + 'power-ports': forms.PowerPortTemplateImportForm, + 'power-outlets': forms.PowerOutletTemplateImportForm, + 'interfaces': forms.InterfaceTemplateImportForm, + 'rear-ports': forms.RearPortTemplateImportForm, + 'front-ports': forms.FrontPortTemplateImportForm, + } def prep_related_object_data(self, parent, data): data.update({'module_type': parent}) diff --git a/netbox/extras/reports.py b/netbox/extras/reports.py index 0a8a8d89b..43d916aff 100644 --- a/netbox/extras/reports.py +++ b/netbox/extras/reports.py @@ -3,7 +3,6 @@ import inspect import logging import pkgutil import traceback -from collections import OrderedDict from django.conf import settings from django.utils import timezone @@ -114,7 +113,7 @@ class Report(object): def __init__(self): - self._results = OrderedDict() + self._results = {} self.active_test = None self.failed = False @@ -125,13 +124,13 @@ class Report(object): for method in dir(self): if method.startswith('test_') and callable(getattr(self, method)): test_methods.append(method) - self._results[method] = OrderedDict([ - ('success', 0), - ('info', 0), - ('warning', 0), - ('failure', 0), - ('log', []), - ]) + self._results[method] = { + 'success': 0, + 'info': 0, + 'warning': 0, + 'failure': 0, + 'log': [], + } if not test_methods: raise Exception("A report must contain at least one test method.") self.test_methods = test_methods diff --git a/netbox/extras/scripts.py b/netbox/extras/scripts.py index cee264878..6e4478304 100644 --- a/netbox/extras/scripts.py +++ b/netbox/extras/scripts.py @@ -6,7 +6,6 @@ import pkgutil import sys import traceback import threading -from collections import OrderedDict import yaml from django import forms @@ -496,7 +495,7 @@ def get_scripts(use_names=False): Return a dict of dicts mapping all scripts to their modules. Set use_names to True to use each module's human- defined name in place of the actual module name. """ - scripts = OrderedDict() + scripts = {} # Iterate through all modules within the scripts path. These are the user-created files in which reports are # defined. for importer, module_name, _ in pkgutil.iter_modules([settings.SCRIPTS_ROOT]): @@ -510,7 +509,7 @@ def get_scripts(use_names=False): if use_names and hasattr(module, 'name'): module_name = module.name - module_scripts = OrderedDict() + module_scripts = {} script_order = getattr(module, "script_order", ()) ordered_scripts = [cls for cls in script_order if is_script(cls)] unordered_scripts = [cls for _, cls in inspect.getmembers(module, is_script) if cls not in script_order] diff --git a/netbox/extras/templatetags/custom_links.py b/netbox/extras/templatetags/custom_links.py index d963bd25a..a73eb3fb4 100644 --- a/netbox/extras/templatetags/custom_links.py +++ b/netbox/extras/templatetags/custom_links.py @@ -1,5 +1,3 @@ -from collections import OrderedDict - from django import template from django.contrib.contenttypes.models import ContentType from django.utils.safestring import mark_safe @@ -50,7 +48,7 @@ def custom_links(context, obj): 'perms': context['perms'], # django.contrib.auth.context_processors.auth } template_code = '' - group_names = OrderedDict() + group_names = {} for cl in custom_links: diff --git a/netbox/ipam/api/serializers.py b/netbox/ipam/api/serializers.py index b3a3589fd..91a81d3b2 100644 --- a/netbox/ipam/api/serializers.py +++ b/netbox/ipam/api/serializers.py @@ -1,5 +1,3 @@ -from collections import OrderedDict - from django.contrib.contenttypes.models import ContentType from drf_yasg.utils import swagger_serializer_method from rest_framework import serializers @@ -227,13 +225,13 @@ class AvailableVLANSerializer(serializers.Serializer): group = NestedVLANGroupSerializer(read_only=True) def to_representation(self, instance): - return OrderedDict([ - ('vid', instance), - ('group', NestedVLANGroupSerializer( + return { + 'vid': instance, + 'group': NestedVLANGroupSerializer( self.context['group'], context={'request': self.context['request']} - ).data), - ]) + ).data, + } class CreateAvailableVLANSerializer(NetBoxModelSerializer): @@ -318,11 +316,11 @@ class AvailablePrefixSerializer(serializers.Serializer): vrf = NestedVRFSerializer(self.context['vrf'], context={'request': self.context['request']}).data else: vrf = None - return OrderedDict([ - ('family', instance.version), - ('prefix', str(instance)), - ('vrf', vrf), - ]) + return { + 'family': instance.version, + 'prefix': str(instance), + 'vrf': vrf, + } # @@ -397,11 +395,11 @@ class AvailableIPSerializer(serializers.Serializer): vrf = NestedVRFSerializer(self.context['vrf'], context={'request': self.context['request']}).data else: vrf = None - return OrderedDict([ - ('family', self.context['parent'].family), - ('address', f"{instance}/{self.context['parent'].mask_length}"), - ('vrf', vrf), - ]) + return { + 'family': self.context['parent'].family, + 'address': f"{instance}/{self.context['parent'].mask_length}", + 'vrf': vrf, + } # diff --git a/netbox/netbox/api/fields.py b/netbox/netbox/api/fields.py index 1f3c40dc2..52343c2f6 100644 --- a/netbox/netbox/api/fields.py +++ b/netbox/netbox/api/fields.py @@ -1,5 +1,3 @@ -from collections import OrderedDict - from django.core.exceptions import ObjectDoesNotExist from netaddr import IPNetwork from rest_framework import serializers @@ -48,10 +46,10 @@ class ChoiceField(serializers.Field): def to_representation(self, obj): if obj == '': return None - return OrderedDict([ - ('value', obj), - ('label', self._choices[obj]) - ]) + return { + 'value': obj, + 'label': self._choices[obj], + } def to_internal_value(self, data): if data == '': diff --git a/netbox/netbox/api/views.py b/netbox/netbox/api/views.py index 835ebc6a9..6c6083959 100644 --- a/netbox/netbox/api/views.py +++ b/netbox/netbox/api/views.py @@ -1,5 +1,4 @@ import platform -from collections import OrderedDict from django import __version__ as DJANGO_VERSION from django.apps import apps @@ -26,18 +25,18 @@ class APIRootView(APIView): def get(self, request, format=None): - return Response(OrderedDict(( - ('circuits', reverse('circuits-api:api-root', request=request, format=format)), - ('dcim', reverse('dcim-api:api-root', request=request, format=format)), - ('extras', reverse('extras-api:api-root', request=request, format=format)), - ('ipam', reverse('ipam-api:api-root', request=request, format=format)), - ('plugins', reverse('plugins-api:api-root', request=request, format=format)), - ('status', reverse('api-status', request=request, format=format)), - ('tenancy', reverse('tenancy-api:api-root', request=request, format=format)), - ('users', reverse('users-api:api-root', request=request, format=format)), - ('virtualization', reverse('virtualization-api:api-root', request=request, format=format)), - ('wireless', reverse('wireless-api:api-root', request=request, format=format)), - ))) + return Response({ + 'circuits': reverse('circuits-api:api-root', request=request, format=format), + 'dcim': reverse('dcim-api:api-root', request=request, format=format), + 'extras': reverse('extras-api:api-root', request=request, format=format), + 'ipam': reverse('ipam-api:api-root', request=request, format=format), + 'plugins': reverse('plugins-api:api-root', request=request, format=format), + 'status': reverse('api-status', request=request, format=format), + 'tenancy': reverse('tenancy-api:api-root', request=request, format=format), + 'users': reverse('users-api:api-root', request=request, format=format), + 'virtualization': reverse('virtualization-api:api-root', request=request, format=format), + 'wireless': reverse('wireless-api:api-root', request=request, format=format), + }) class StatusView(APIView): diff --git a/netbox/utilities/utils.py b/netbox/utilities/utils.py index fa0534ec0..1dece76c8 100644 --- a/netbox/utilities/utils.py +++ b/netbox/utilities/utils.py @@ -1,7 +1,6 @@ import datetime import decimal import json -from collections import OrderedDict from decimal import Decimal from itertools import count, groupby @@ -218,7 +217,7 @@ def deepmerge(original, new): """ Deep merge two dictionaries (new into original) and return a new dict """ - merged = OrderedDict(original) + merged = dict(original) for key, val in new.items(): if key in original and isinstance(original[key], dict) and val and isinstance(val, dict): merged[key] = deepmerge(original[key], val)