diff --git a/netbox/circuits/graphql/schema.py b/netbox/circuits/graphql/schema.py index 63bd7bba6..a73bdbc6d 100644 --- a/netbox/circuits/graphql/schema.py +++ b/netbox/circuits/graphql/schema.py @@ -1,5 +1,3 @@ -from typing import List - import strawberry import strawberry_django @@ -9,34 +7,34 @@ from .types import * @strawberry.type(name="Query") class CircuitsQuery: circuit: CircuitType = strawberry_django.field() - circuit_list: List[CircuitType] = strawberry_django.field() + circuit_list: list[CircuitType] = strawberry_django.field() circuit_termination: CircuitTerminationType = strawberry_django.field() - circuit_termination_list: List[CircuitTerminationType] = strawberry_django.field() + circuit_termination_list: list[CircuitTerminationType] = strawberry_django.field() circuit_type: CircuitTypeType = strawberry_django.field() - circuit_type_list: List[CircuitTypeType] = strawberry_django.field() + circuit_type_list: list[CircuitTypeType] = strawberry_django.field() circuit_group: CircuitGroupType = strawberry_django.field() - circuit_group_list: List[CircuitGroupType] = strawberry_django.field() + circuit_group_list: list[CircuitGroupType] = strawberry_django.field() circuit_group_assignment: CircuitGroupAssignmentType = strawberry_django.field() - circuit_group_assignment_list: List[CircuitGroupAssignmentType] = strawberry_django.field() + circuit_group_assignment_list: list[CircuitGroupAssignmentType] = strawberry_django.field() provider: ProviderType = strawberry_django.field() - provider_list: List[ProviderType] = strawberry_django.field() + provider_list: list[ProviderType] = strawberry_django.field() provider_account: ProviderAccountType = strawberry_django.field() - provider_account_list: List[ProviderAccountType] = strawberry_django.field() + provider_account_list: list[ProviderAccountType] = strawberry_django.field() provider_network: ProviderNetworkType = strawberry_django.field() - provider_network_list: List[ProviderNetworkType] = strawberry_django.field() + provider_network_list: list[ProviderNetworkType] = strawberry_django.field() virtual_circuit: VirtualCircuitType = strawberry_django.field() - virtual_circuit_list: List[VirtualCircuitType] = strawberry_django.field() + virtual_circuit_list: list[VirtualCircuitType] = strawberry_django.field() virtual_circuit_termination: VirtualCircuitTerminationType = strawberry_django.field() - virtual_circuit_termination_list: List[VirtualCircuitTerminationType] = strawberry_django.field() + virtual_circuit_termination_list: list[VirtualCircuitTerminationType] = strawberry_django.field() virtual_circuit_type: VirtualCircuitTypeType = strawberry_django.field() - virtual_circuit_type_list: List[VirtualCircuitTypeType] = strawberry_django.field() + virtual_circuit_type_list: list[VirtualCircuitTypeType] = strawberry_django.field() diff --git a/netbox/circuits/graphql/types.py b/netbox/circuits/graphql/types.py index 92538b498..3da3059b8 100644 --- a/netbox/circuits/graphql/types.py +++ b/netbox/circuits/graphql/types.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Annotated, List, Union +from typing import TYPE_CHECKING, Annotated import strawberry import strawberry_django @@ -37,10 +37,10 @@ __all__ = ( pagination=True ) class ProviderType(ContactsMixin, PrimaryObjectType): - networks: List[Annotated["ProviderNetworkType", strawberry.lazy('circuits.graphql.types')]] - circuits: List[Annotated["CircuitType", strawberry.lazy('circuits.graphql.types')]] - asns: List[Annotated["ASNType", strawberry.lazy('ipam.graphql.types')]] - accounts: List[Annotated["ProviderAccountType", strawberry.lazy('circuits.graphql.types')]] + networks: list[Annotated["ProviderNetworkType", strawberry.lazy('circuits.graphql.types')]] + circuits: list[Annotated["CircuitType", strawberry.lazy('circuits.graphql.types')]] + asns: list[Annotated["ASNType", strawberry.lazy('ipam.graphql.types')]] + accounts: list[Annotated["ProviderAccountType", strawberry.lazy('circuits.graphql.types')]] @strawberry_django.type( @@ -51,7 +51,7 @@ class ProviderType(ContactsMixin, PrimaryObjectType): ) class ProviderAccountType(ContactsMixin, PrimaryObjectType): provider: Annotated["ProviderType", strawberry.lazy('circuits.graphql.types')] - circuits: List[Annotated["CircuitType", strawberry.lazy('circuits.graphql.types')]] + circuits: list[Annotated["CircuitType", strawberry.lazy('circuits.graphql.types')]] @strawberry_django.type( @@ -62,7 +62,7 @@ class ProviderAccountType(ContactsMixin, PrimaryObjectType): ) class ProviderNetworkType(PrimaryObjectType): provider: Annotated["ProviderType", strawberry.lazy('circuits.graphql.types')] - circuit_terminations: List[Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]] + circuit_terminations: list[Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]] @strawberry_django.type( @@ -72,16 +72,17 @@ class ProviderNetworkType(PrimaryObjectType): pagination=True ) class CircuitTerminationType(CustomFieldsMixin, TagsMixin, CabledObjectMixin, ObjectType): - circuit: Annotated["CircuitType", strawberry.lazy('circuits.graphql.types')] + circuit: Annotated['CircuitType', strawberry.lazy('circuits.graphql.types')] @strawberry_django.field - def termination(self) -> Annotated[Union[ - Annotated["LocationType", strawberry.lazy('dcim.graphql.types')], - Annotated["RegionType", strawberry.lazy('dcim.graphql.types')], - Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')], - Annotated["SiteType", strawberry.lazy('dcim.graphql.types')], - Annotated["ProviderNetworkType", strawberry.lazy('circuits.graphql.types')], - ], strawberry.union("CircuitTerminationTerminationType")] | None: + def termination(self) -> Annotated[ + Annotated['LocationType', strawberry.lazy('dcim.graphql.types')] + | Annotated['RegionType', strawberry.lazy('dcim.graphql.types')] + | Annotated['SiteGroupType', strawberry.lazy('dcim.graphql.types')] + | Annotated['SiteType', strawberry.lazy('dcim.graphql.types')] + | Annotated['ProviderNetworkType', strawberry.lazy('circuits.graphql.types')], + strawberry.union('CircuitTerminationTerminationType'), + ] | None: return self.termination @@ -94,7 +95,7 @@ class CircuitTerminationType(CustomFieldsMixin, TagsMixin, CabledObjectMixin, Ob class CircuitTypeType(OrganizationalObjectType): color: str - circuits: List[Annotated["CircuitType", strawberry.lazy('circuits.graphql.types')]] + circuits: list[Annotated["CircuitType", strawberry.lazy('circuits.graphql.types')]] @strawberry_django.type( @@ -110,7 +111,7 @@ class CircuitType(PrimaryObjectType, ContactsMixin): termination_z: CircuitTerminationType | None type: CircuitTypeType tenant: TenantType | None - terminations: List[CircuitTerminationType] + terminations: list[CircuitTerminationType] @strawberry_django.type( @@ -130,13 +131,14 @@ class CircuitGroupType(OrganizationalObjectType): pagination=True ) class CircuitGroupAssignmentType(TagsMixin, BaseObjectType): - group: Annotated["CircuitGroupType", strawberry.lazy('circuits.graphql.types')] + group: Annotated['CircuitGroupType', strawberry.lazy('circuits.graphql.types')] @strawberry_django.field - def member(self) -> Annotated[Union[ - Annotated["CircuitType", strawberry.lazy('circuits.graphql.types')], - Annotated["VirtualCircuitType", strawberry.lazy('circuits.graphql.types')], - ], strawberry.union("CircuitGroupAssignmentMemberType")] | None: + def member(self) -> Annotated[ + Annotated['CircuitType', strawberry.lazy('circuits.graphql.types')] + | Annotated['VirtualCircuitType', strawberry.lazy('circuits.graphql.types')], + strawberry.union('CircuitGroupAssignmentMemberType'), + ] | None: return self.member @@ -149,7 +151,7 @@ class CircuitGroupAssignmentType(TagsMixin, BaseObjectType): class VirtualCircuitTypeType(OrganizationalObjectType): color: str - virtual_circuits: List[Annotated["VirtualCircuitType", strawberry.lazy('circuits.graphql.types')]] + virtual_circuits: list[Annotated["VirtualCircuitType", strawberry.lazy('circuits.graphql.types')]] @strawberry_django.type( @@ -182,4 +184,4 @@ class VirtualCircuitType(PrimaryObjectType): select_related=["type"] ) tenant: TenantType | None - terminations: List[VirtualCircuitTerminationType] + terminations: list[VirtualCircuitTerminationType] diff --git a/netbox/core/graphql/mixins.py b/netbox/core/graphql/mixins.py index 27a9ee9eb..c5067e77c 100644 --- a/netbox/core/graphql/mixins.py +++ b/netbox/core/graphql/mixins.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Annotated, List +from typing import TYPE_CHECKING, Annotated import strawberry import strawberry_django @@ -20,7 +20,7 @@ __all__ = ( class ChangelogMixin: @strawberry_django.field - def changelog(self, info: Info) -> List[Annotated['ObjectChangeType', strawberry.lazy('.types')]]: # noqa: F821 + def changelog(self, info: Info) -> list[Annotated['ObjectChangeType', strawberry.lazy('.types')]]: # noqa: F821 content_type = ContentType.objects.get_for_model(self) object_changes = ObjectChange.objects.filter( changed_object_type=content_type, diff --git a/netbox/core/graphql/schema.py b/netbox/core/graphql/schema.py index a77c57c86..073efec94 100644 --- a/netbox/core/graphql/schema.py +++ b/netbox/core/graphql/schema.py @@ -1,5 +1,3 @@ -from typing import List - import strawberry import strawberry_django @@ -9,7 +7,7 @@ from .types import * @strawberry.type(name="Query") class CoreQuery: data_file: DataFileType = strawberry_django.field() - data_file_list: List[DataFileType] = strawberry_django.field() + data_file_list: list[DataFileType] = strawberry_django.field() data_source: DataSourceType = strawberry_django.field() - data_source_list: List[DataSourceType] = strawberry_django.field() + data_source_list: list[DataSourceType] = strawberry_django.field() diff --git a/netbox/core/graphql/types.py b/netbox/core/graphql/types.py index 98e7aefae..5a5d043d5 100644 --- a/netbox/core/graphql/types.py +++ b/netbox/core/graphql/types.py @@ -1,4 +1,4 @@ -from typing import Annotated, List +from typing import Annotated import strawberry import strawberry_django @@ -34,7 +34,7 @@ class DataFileType(BaseObjectType): pagination=True ) class DataSourceType(PrimaryObjectType): - datafiles: List[Annotated["DataFileType", strawberry.lazy('core.graphql.types')]] + datafiles: list[Annotated["DataFileType", strawberry.lazy('core.graphql.types')]] @strawberry_django.type( diff --git a/netbox/core/plugins.py b/netbox/core/plugins.py index 15f640b86..fd1760362 100644 --- a/netbox/core/plugins.py +++ b/netbox/core/plugins.py @@ -1,7 +1,6 @@ import datetime import importlib from dataclasses import dataclass, field -from typing import Optional import requests from django.conf import settings @@ -55,7 +54,7 @@ class Plugin: tag_line: str = '' description_short: str = '' slug: str = '' - author: Optional[PluginAuthor] = None + author: PluginAuthor | None = None created_at: datetime.datetime = None updated_at: datetime.datetime = None license_type: str = '' diff --git a/netbox/core/tests/test_filtersets.py b/netbox/core/tests/test_filtersets.py index 6659b382b..e9045832a 100644 --- a/netbox/core/tests/test_filtersets.py +++ b/netbox/core/tests/test_filtersets.py @@ -1,5 +1,5 @@ import uuid -from datetime import datetime, timezone +from datetime import UTC, datetime from django.contrib.contenttypes.models import ContentType from django.test import TestCase @@ -100,21 +100,21 @@ class DataFileTestCase(TestCase, ChangeLoggedFilterSetTests): DataFile( source=data_sources[0], path='dir1/file1.txt', - last_updated=datetime(2023, 1, 1, 0, 0, 0, tzinfo=timezone.utc), + last_updated=datetime(2023, 1, 1, 0, 0, 0, tzinfo=UTC), size=1000, hash='442da078f0111cbdf42f21903724f6597c692535f55bdfbbea758a1ae99ad9e1' ), DataFile( source=data_sources[1], path='dir1/file2.txt', - last_updated=datetime(2023, 1, 2, 0, 0, 0, tzinfo=timezone.utc), + last_updated=datetime(2023, 1, 2, 0, 0, 0, tzinfo=UTC), size=2000, hash='a78168c7c97115bafd96450ed03ea43acec495094c5caa28f0d02e20e3a76cc2' ), DataFile( source=data_sources[2], path='dir1/file3.txt', - last_updated=datetime(2023, 1, 3, 0, 0, 0, tzinfo=timezone.utc), + last_updated=datetime(2023, 1, 3, 0, 0, 0, tzinfo=UTC), size=3000, hash='12b8827a14c4d5a2f30b6c6e2b7983063988612391c6cbe8ee7493b59054827a' ), diff --git a/netbox/dcim/api/views.py b/netbox/dcim/api/views.py index da1f2379e..a3bc7386a 100644 --- a/netbox/dcim/api/views.py +++ b/netbox/dcim/api/views.py @@ -36,7 +36,7 @@ class DCIMRootView(APIRootView): # Mixins -class PathEndpointMixin(object): +class PathEndpointMixin: @action(detail=True, url_path='trace') def trace(self, request, pk): @@ -76,7 +76,7 @@ class PathEndpointMixin(object): return Response(path) -class PassThroughPortMixin(object): +class PassThroughPortMixin: @action(detail=True, url_path='paths') def paths(self, request, pk): diff --git a/netbox/dcim/graphql/mixins.py b/netbox/dcim/graphql/mixins.py index de8691889..6af3da586 100644 --- a/netbox/dcim/graphql/mixins.py +++ b/netbox/dcim/graphql/mixins.py @@ -1,7 +1,21 @@ -from typing import Annotated, List, Union +from typing import TYPE_CHECKING, Annotated import strawberry +if TYPE_CHECKING: + from circuits.graphql.types import CircuitTerminationType, ProviderNetworkType, VirtualCircuitTerminationType + from dcim.graphql.types import ( + CableType, + ConsolePortType, + ConsoleServerPortType, + FrontPortType, + InterfaceType, + PowerFeedType, + PowerOutletType, + PowerPortType, + RearPortType, + ) + __all__ = ( 'CabledObjectMixin', 'PathEndpointMixin', @@ -10,34 +24,40 @@ __all__ = ( @strawberry.type class CabledObjectMixin: - cable: Annotated["CableType", strawberry.lazy('dcim.graphql.types')] | None # noqa: F821 + cable: Annotated["CableType", strawberry.lazy('dcim.graphql.types')] | None - link_peers: List[Annotated[Union[ - Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')], # noqa: F821 - Annotated["ConsolePortType", strawberry.lazy('dcim.graphql.types')], # noqa: F821 - Annotated["ConsoleServerPortType", strawberry.lazy('dcim.graphql.types')], # noqa: F821 - Annotated["FrontPortType", strawberry.lazy('dcim.graphql.types')], # noqa: F821 - Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')], # noqa: F821 - Annotated["PowerFeedType", strawberry.lazy('dcim.graphql.types')], # noqa: F821 - Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')], # noqa: F821 - Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')], # noqa: F821 - Annotated["RearPortType", strawberry.lazy('dcim.graphql.types')], # noqa: F821 - ], strawberry.union("LinkPeerType")]] + link_peers: list[ + Annotated[ + Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')] + | Annotated["ConsolePortType", strawberry.lazy('dcim.graphql.types')] + | Annotated["ConsoleServerPortType", strawberry.lazy('dcim.graphql.types')] + | Annotated["FrontPortType", strawberry.lazy('dcim.graphql.types')] + | Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')] + | Annotated["PowerFeedType", strawberry.lazy('dcim.graphql.types')] + | Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')] + | Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')] + | Annotated["RearPortType", strawberry.lazy('dcim.graphql.types')], + strawberry.union("LinkPeerType"), + ] + ] @strawberry.type class PathEndpointMixin: - connected_endpoints: List[Annotated[Union[ - Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')], # noqa: F821 - Annotated["VirtualCircuitTerminationType", strawberry.lazy('circuits.graphql.types')], # noqa: F821 - Annotated["ConsolePortType", strawberry.lazy('dcim.graphql.types')], # noqa: F821 - Annotated["ConsoleServerPortType", strawberry.lazy('dcim.graphql.types')], # noqa: F821 - Annotated["FrontPortType", strawberry.lazy('dcim.graphql.types')], # noqa: F821 - Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')], # noqa: F821 - Annotated["PowerFeedType", strawberry.lazy('dcim.graphql.types')], # noqa: F821 - Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')], # noqa: F821 - Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')], # noqa: F821 - Annotated["ProviderNetworkType", strawberry.lazy('circuits.graphql.types')], # noqa: F821 - Annotated["RearPortType", strawberry.lazy('dcim.graphql.types')], # noqa: F821 - ], strawberry.union("ConnectedEndpointType")]] + connected_endpoints: list[ + Annotated[ + Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')] + | Annotated["VirtualCircuitTerminationType", strawberry.lazy('circuits.graphql.types')] + | Annotated["ConsolePortType", strawberry.lazy('dcim.graphql.types')] + | Annotated["ConsoleServerPortType", strawberry.lazy('dcim.graphql.types')] + | Annotated["FrontPortType", strawberry.lazy('dcim.graphql.types')] + | Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')] + | Annotated["PowerFeedType", strawberry.lazy('dcim.graphql.types')] + | Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')] + | Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')] + | Annotated["ProviderNetworkType", strawberry.lazy('circuits.graphql.types')] + | Annotated["RearPortType", strawberry.lazy('dcim.graphql.types')], + strawberry.union("ConnectedEndpointType"), + ] + ] diff --git a/netbox/dcim/graphql/schema.py b/netbox/dcim/graphql/schema.py index 1b0661bc2..fcf1e828f 100644 --- a/netbox/dcim/graphql/schema.py +++ b/netbox/dcim/graphql/schema.py @@ -1,5 +1,3 @@ -from typing import List - import strawberry import strawberry_django @@ -9,130 +7,130 @@ from .types import * @strawberry.type(name="Query") class DCIMQuery: cable: CableType = strawberry_django.field() - cable_list: List[CableType] = strawberry_django.field() + cable_list: list[CableType] = strawberry_django.field() console_port: ConsolePortType = strawberry_django.field() - console_port_list: List[ConsolePortType] = strawberry_django.field() + console_port_list: list[ConsolePortType] = strawberry_django.field() console_port_template: ConsolePortTemplateType = strawberry_django.field() - console_port_template_list: List[ConsolePortTemplateType] = strawberry_django.field() + console_port_template_list: list[ConsolePortTemplateType] = strawberry_django.field() console_server_port: ConsoleServerPortType = strawberry_django.field() - console_server_port_list: List[ConsoleServerPortType] = strawberry_django.field() + console_server_port_list: list[ConsoleServerPortType] = strawberry_django.field() console_server_port_template: ConsoleServerPortTemplateType = strawberry_django.field() - console_server_port_template_list: List[ConsoleServerPortTemplateType] = strawberry_django.field() + console_server_port_template_list: list[ConsoleServerPortTemplateType] = strawberry_django.field() device: DeviceType = strawberry_django.field() - device_list: List[DeviceType] = strawberry_django.field() + device_list: list[DeviceType] = strawberry_django.field() device_bay: DeviceBayType = strawberry_django.field() - device_bay_list: List[DeviceBayType] = strawberry_django.field() + device_bay_list: list[DeviceBayType] = strawberry_django.field() device_bay_template: DeviceBayTemplateType = strawberry_django.field() - device_bay_template_list: List[DeviceBayTemplateType] = strawberry_django.field() + device_bay_template_list: list[DeviceBayTemplateType] = strawberry_django.field() device_role: DeviceRoleType = strawberry_django.field() - device_role_list: List[DeviceRoleType] = strawberry_django.field() + device_role_list: list[DeviceRoleType] = strawberry_django.field() device_type: DeviceTypeType = strawberry_django.field() - device_type_list: List[DeviceTypeType] = strawberry_django.field() + device_type_list: list[DeviceTypeType] = strawberry_django.field() front_port: FrontPortType = strawberry_django.field() - front_port_list: List[FrontPortType] = strawberry_django.field() + front_port_list: list[FrontPortType] = strawberry_django.field() front_port_template: FrontPortTemplateType = strawberry_django.field() - front_port_template_list: List[FrontPortTemplateType] = strawberry_django.field() + front_port_template_list: list[FrontPortTemplateType] = strawberry_django.field() mac_address: MACAddressType = strawberry_django.field() - mac_address_list: List[MACAddressType] = strawberry_django.field() + mac_address_list: list[MACAddressType] = strawberry_django.field() interface: InterfaceType = strawberry_django.field() - interface_list: List[InterfaceType] = strawberry_django.field() + interface_list: list[InterfaceType] = strawberry_django.field() interface_template: InterfaceTemplateType = strawberry_django.field() - interface_template_list: List[InterfaceTemplateType] = strawberry_django.field() + interface_template_list: list[InterfaceTemplateType] = strawberry_django.field() inventory_item: InventoryItemType = strawberry_django.field() - inventory_item_list: List[InventoryItemType] = strawberry_django.field() + inventory_item_list: list[InventoryItemType] = strawberry_django.field() inventory_item_role: InventoryItemRoleType = strawberry_django.field() - inventory_item_role_list: List[InventoryItemRoleType] = strawberry_django.field() + inventory_item_role_list: list[InventoryItemRoleType] = strawberry_django.field() inventory_item_template: InventoryItemTemplateType = strawberry_django.field() - inventory_item_template_list: List[InventoryItemTemplateType] = strawberry_django.field() + inventory_item_template_list: list[InventoryItemTemplateType] = strawberry_django.field() location: LocationType = strawberry_django.field() - location_list: List[LocationType] = strawberry_django.field() + location_list: list[LocationType] = strawberry_django.field() manufacturer: ManufacturerType = strawberry_django.field() - manufacturer_list: List[ManufacturerType] = strawberry_django.field() + manufacturer_list: list[ManufacturerType] = strawberry_django.field() module: ModuleType = strawberry_django.field() - module_list: List[ModuleType] = strawberry_django.field() + module_list: list[ModuleType] = strawberry_django.field() module_bay: ModuleBayType = strawberry_django.field() - module_bay_list: List[ModuleBayType] = strawberry_django.field() + module_bay_list: list[ModuleBayType] = strawberry_django.field() module_bay_template: ModuleBayTemplateType = strawberry_django.field() - module_bay_template_list: List[ModuleBayTemplateType] = strawberry_django.field() + module_bay_template_list: list[ModuleBayTemplateType] = strawberry_django.field() module_type_profile: ModuleTypeProfileType = strawberry_django.field() - module_type_profile_list: List[ModuleTypeProfileType] = strawberry_django.field() + module_type_profile_list: list[ModuleTypeProfileType] = strawberry_django.field() module_type: ModuleTypeType = strawberry_django.field() - module_type_list: List[ModuleTypeType] = strawberry_django.field() + module_type_list: list[ModuleTypeType] = strawberry_django.field() platform: PlatformType = strawberry_django.field() - platform_list: List[PlatformType] = strawberry_django.field() + platform_list: list[PlatformType] = strawberry_django.field() power_feed: PowerFeedType = strawberry_django.field() - power_feed_list: List[PowerFeedType] = strawberry_django.field() + power_feed_list: list[PowerFeedType] = strawberry_django.field() power_outlet: PowerOutletType = strawberry_django.field() - power_outlet_list: List[PowerOutletType] = strawberry_django.field() + power_outlet_list: list[PowerOutletType] = strawberry_django.field() power_outlet_template: PowerOutletTemplateType = strawberry_django.field() - power_outlet_template_list: List[PowerOutletTemplateType] = strawberry_django.field() + power_outlet_template_list: list[PowerOutletTemplateType] = strawberry_django.field() power_panel: PowerPanelType = strawberry_django.field() - power_panel_list: List[PowerPanelType] = strawberry_django.field() + power_panel_list: list[PowerPanelType] = strawberry_django.field() power_port: PowerPortType = strawberry_django.field() - power_port_list: List[PowerPortType] = strawberry_django.field() + power_port_list: list[PowerPortType] = strawberry_django.field() power_port_template: PowerPortTemplateType = strawberry_django.field() - power_port_template_list: List[PowerPortTemplateType] = strawberry_django.field() + power_port_template_list: list[PowerPortTemplateType] = strawberry_django.field() rack_type: RackTypeType = strawberry_django.field() - rack_type_list: List[RackTypeType] = strawberry_django.field() + rack_type_list: list[RackTypeType] = strawberry_django.field() rack: RackType = strawberry_django.field() - rack_list: List[RackType] = strawberry_django.field() + rack_list: list[RackType] = strawberry_django.field() rack_reservation: RackReservationType = strawberry_django.field() - rack_reservation_list: List[RackReservationType] = strawberry_django.field() + rack_reservation_list: list[RackReservationType] = strawberry_django.field() rack_role: RackRoleType = strawberry_django.field() - rack_role_list: List[RackRoleType] = strawberry_django.field() + rack_role_list: list[RackRoleType] = strawberry_django.field() rear_port: RearPortType = strawberry_django.field() - rear_port_list: List[RearPortType] = strawberry_django.field() + rear_port_list: list[RearPortType] = strawberry_django.field() rear_port_template: RearPortTemplateType = strawberry_django.field() - rear_port_template_list: List[RearPortTemplateType] = strawberry_django.field() + rear_port_template_list: list[RearPortTemplateType] = strawberry_django.field() region: RegionType = strawberry_django.field() - region_list: List[RegionType] = strawberry_django.field() + region_list: list[RegionType] = strawberry_django.field() site: SiteType = strawberry_django.field() - site_list: List[SiteType] = strawberry_django.field() + site_list: list[SiteType] = strawberry_django.field() site_group: SiteGroupType = strawberry_django.field() - site_group_list: List[SiteGroupType] = strawberry_django.field() + site_group_list: list[SiteGroupType] = strawberry_django.field() virtual_chassis: VirtualChassisType = strawberry_django.field() - virtual_chassis_list: List[VirtualChassisType] = strawberry_django.field() + virtual_chassis_list: list[VirtualChassisType] = strawberry_django.field() virtual_device_context: VirtualDeviceContextType = strawberry_django.field() - virtual_device_context_list: List[VirtualDeviceContextType] = strawberry_django.field() + virtual_device_context_list: list[VirtualDeviceContextType] = strawberry_django.field() diff --git a/netbox/dcim/graphql/types.py b/netbox/dcim/graphql/types.py index d39b07efa..4036d151f 100644 --- a/netbox/dcim/graphql/types.py +++ b/netbox/dcim/graphql/types.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Annotated, List, Union +from typing import TYPE_CHECKING, Annotated import strawberry import strawberry_django @@ -106,10 +106,7 @@ class ModularComponentType(ComponentType): @strawberry.type -class ComponentTemplateType( - ChangelogMixin, - BaseObjectType -): +class ComponentTemplateType(ChangelogMixin, BaseObjectType): """ Base type for device/VM components """ @@ -136,18 +133,19 @@ class ModularComponentTemplateType(ComponentTemplateType): pagination=True ) class CableTerminationType(NetBoxObjectType): - cable: Annotated["CableType", strawberry.lazy('dcim.graphql.types')] | None - termination: Annotated[Union[ - Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')], - Annotated["ConsolePortType", strawberry.lazy('dcim.graphql.types')], - Annotated["ConsoleServerPortType", strawberry.lazy('dcim.graphql.types')], - Annotated["FrontPortType", strawberry.lazy('dcim.graphql.types')], - Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')], - Annotated["PowerFeedType", strawberry.lazy('dcim.graphql.types')], - Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')], - Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')], - Annotated["RearPortType", strawberry.lazy('dcim.graphql.types')], - ], strawberry.union("CableTerminationTerminationType")] | None + cable: Annotated['CableType', strawberry.lazy('dcim.graphql.types')] | None + termination: Annotated[ + Annotated['CircuitTerminationType', strawberry.lazy('circuits.graphql.types')] + | Annotated['ConsolePortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['ConsoleServerPortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['FrontPortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')] + | Annotated['PowerFeedType', strawberry.lazy('dcim.graphql.types')] + | Annotated['PowerOutletType', strawberry.lazy('dcim.graphql.types')] + | Annotated['PowerPortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['RearPortType', strawberry.lazy('dcim.graphql.types')], + strawberry.union('CableTerminationTerminationType'), + ] | None @strawberry_django.type( @@ -158,33 +156,35 @@ class CableTerminationType(NetBoxObjectType): ) class CableType(PrimaryObjectType): color: str - tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None + tenant: Annotated['TenantType', strawberry.lazy('tenancy.graphql.types')] | None - terminations: List[CableTerminationType] + terminations: list[CableTerminationType] - a_terminations: List[Annotated[Union[ - Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')], - Annotated["ConsolePortType", strawberry.lazy('dcim.graphql.types')], - Annotated["ConsoleServerPortType", strawberry.lazy('dcim.graphql.types')], - Annotated["FrontPortType", strawberry.lazy('dcim.graphql.types')], - Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')], - Annotated["PowerFeedType", strawberry.lazy('dcim.graphql.types')], - Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')], - Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')], - Annotated["RearPortType", strawberry.lazy('dcim.graphql.types')], - ], strawberry.union("CableTerminationTerminationType")]] + a_terminations: list[Annotated[ + Annotated['CircuitTerminationType', strawberry.lazy('circuits.graphql.types')] + | Annotated['ConsolePortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['ConsoleServerPortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['FrontPortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')] + | Annotated['PowerFeedType', strawberry.lazy('dcim.graphql.types')] + | Annotated['PowerOutletType', strawberry.lazy('dcim.graphql.types')] + | Annotated['PowerPortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['RearPortType', strawberry.lazy('dcim.graphql.types')], + strawberry.union('CableTerminationTerminationType'), + ]] - b_terminations: List[Annotated[Union[ - Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')], - Annotated["ConsolePortType", strawberry.lazy('dcim.graphql.types')], - Annotated["ConsoleServerPortType", strawberry.lazy('dcim.graphql.types')], - Annotated["FrontPortType", strawberry.lazy('dcim.graphql.types')], - Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')], - Annotated["PowerFeedType", strawberry.lazy('dcim.graphql.types')], - Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')], - Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')], - Annotated["RearPortType", strawberry.lazy('dcim.graphql.types')], - ], strawberry.union("CableTerminationTerminationType")]] + b_terminations: list[Annotated[ + Annotated['CircuitTerminationType', strawberry.lazy('circuits.graphql.types')] + | Annotated['ConsolePortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['ConsoleServerPortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['FrontPortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')] + | Annotated['PowerFeedType', strawberry.lazy('dcim.graphql.types')] + | Annotated['PowerOutletType', strawberry.lazy('dcim.graphql.types')] + | Annotated['PowerPortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['RearPortType', strawberry.lazy('dcim.graphql.types')], + strawberry.union('CableTerminationTerminationType'), + ]] @strawberry_django.type( @@ -258,21 +258,21 @@ class DeviceType(ConfigContextMixin, ImageAttachmentsMixin, ContactsMixin, Prima cluster: Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')] | None virtual_chassis: Annotated["VirtualChassisType", strawberry.lazy('dcim.graphql.types')] | None - virtual_machines: List[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]] - modules: List[Annotated["ModuleType", strawberry.lazy('dcim.graphql.types')]] - interfaces: List[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] - rearports: List[Annotated["RearPortType", strawberry.lazy('dcim.graphql.types')]] - consoleports: List[Annotated["ConsolePortType", strawberry.lazy('dcim.graphql.types')]] - powerports: List[Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')]] - cabletermination_set: List[Annotated["CableTerminationType", strawberry.lazy('dcim.graphql.types')]] - consoleserverports: List[Annotated["ConsoleServerPortType", strawberry.lazy('dcim.graphql.types')]] - poweroutlets: List[Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')]] - frontports: List[Annotated["FrontPortType", strawberry.lazy('dcim.graphql.types')]] - devicebays: List[Annotated["DeviceBayType", strawberry.lazy('dcim.graphql.types')]] - modulebays: List[Annotated["ModuleBayType", strawberry.lazy('dcim.graphql.types')]] - services: List[Annotated["ServiceType", strawberry.lazy('ipam.graphql.types')]] - inventoryitems: List[Annotated["InventoryItemType", strawberry.lazy('dcim.graphql.types')]] - vdcs: List[Annotated["VirtualDeviceContextType", strawberry.lazy('dcim.graphql.types')]] + virtual_machines: list[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]] + modules: list[Annotated["ModuleType", strawberry.lazy('dcim.graphql.types')]] + interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] + rearports: list[Annotated["RearPortType", strawberry.lazy('dcim.graphql.types')]] + consoleports: list[Annotated["ConsolePortType", strawberry.lazy('dcim.graphql.types')]] + powerports: list[Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')]] + cabletermination_set: list[Annotated["CableTerminationType", strawberry.lazy('dcim.graphql.types')]] + consoleserverports: list[Annotated["ConsoleServerPortType", strawberry.lazy('dcim.graphql.types')]] + poweroutlets: list[Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')]] + frontports: list[Annotated["FrontPortType", strawberry.lazy('dcim.graphql.types')]] + devicebays: list[Annotated["DeviceBayType", strawberry.lazy('dcim.graphql.types')]] + modulebays: list[Annotated["ModuleBayType", strawberry.lazy('dcim.graphql.types')]] + services: list[Annotated["ServiceType", strawberry.lazy('ipam.graphql.types')]] + inventoryitems: list[Annotated["InventoryItemType", strawberry.lazy('dcim.graphql.types')]] + vdcs: list[Annotated["VirtualDeviceContextType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.field def vc_master_for(self) -> Annotated["VirtualChassisType", strawberry.lazy('dcim.graphql.types')] | None: @@ -310,24 +310,25 @@ class DeviceBayTemplateType(ComponentTemplateType): pagination=True ) class InventoryItemTemplateType(ComponentTemplateType): - role: Annotated["InventoryItemRoleType", strawberry.lazy('dcim.graphql.types')] | None - manufacturer: Annotated["ManufacturerType", strawberry.lazy('dcim.graphql.types')] + role: Annotated['InventoryItemRoleType', strawberry.lazy('dcim.graphql.types')] | None + manufacturer: Annotated['ManufacturerType', strawberry.lazy('dcim.graphql.types')] @strawberry_django.field - def parent(self) -> Annotated["InventoryItemTemplateType", strawberry.lazy('dcim.graphql.types')] | None: + def parent(self) -> Annotated['InventoryItemTemplateType', strawberry.lazy('dcim.graphql.types')] | None: return self.parent - child_items: List[Annotated["InventoryItemTemplateType", strawberry.lazy('dcim.graphql.types')]] + child_items: list[Annotated['InventoryItemTemplateType', strawberry.lazy('dcim.graphql.types')]] - component: Annotated[Union[ - Annotated["ConsolePortType", strawberry.lazy('dcim.graphql.types')], - Annotated["ConsoleServerPortType", strawberry.lazy('dcim.graphql.types')], - Annotated["FrontPortType", strawberry.lazy('dcim.graphql.types')], - Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')], - Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')], - Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')], - Annotated["RearPortType", strawberry.lazy('dcim.graphql.types')], - ], strawberry.union("InventoryItemTemplateComponentType")] | None + component: Annotated[ + Annotated['ConsolePortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['ConsoleServerPortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['FrontPortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')] + | Annotated['PowerOutletType', strawberry.lazy('dcim.graphql.types')] + | Annotated['PowerPortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['RearPortType', strawberry.lazy('dcim.graphql.types')], + strawberry.union('InventoryItemTemplateComponentType'), + ] | None @strawberry_django.type( @@ -338,12 +339,12 @@ class InventoryItemTemplateType(ComponentTemplateType): ) class DeviceRoleType(NestedGroupObjectType): parent: Annotated['DeviceRoleType', strawberry.lazy('dcim.graphql.types')] | None - children: List[Annotated['DeviceRoleType', strawberry.lazy('dcim.graphql.types')]] + children: list[Annotated['DeviceRoleType', strawberry.lazy('dcim.graphql.types')]] color: str config_template: Annotated["ConfigTemplateType", strawberry.lazy('extras.graphql.types')] | None - virtual_machines: List[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]] - devices: List[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] + virtual_machines: list[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]] + devices: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -369,17 +370,17 @@ class DeviceTypeType(PrimaryObjectType): manufacturer: Annotated["ManufacturerType", strawberry.lazy('dcim.graphql.types')] default_platform: Annotated["PlatformType", strawberry.lazy('dcim.graphql.types')] | None - frontporttemplates: List[Annotated["FrontPortTemplateType", strawberry.lazy('dcim.graphql.types')]] - modulebaytemplates: List[Annotated["ModuleBayTemplateType", strawberry.lazy('dcim.graphql.types')]] - instances: List[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] - poweroutlettemplates: List[Annotated["PowerOutletTemplateType", strawberry.lazy('dcim.graphql.types')]] - powerporttemplates: List[Annotated["PowerPortTemplateType", strawberry.lazy('dcim.graphql.types')]] - inventoryitemtemplates: List[Annotated["InventoryItemTemplateType", strawberry.lazy('dcim.graphql.types')]] - rearporttemplates: List[Annotated["RearPortTemplateType", strawberry.lazy('dcim.graphql.types')]] - consoleserverporttemplates: List[Annotated["ConsoleServerPortTemplateType", strawberry.lazy('dcim.graphql.types')]] - interfacetemplates: List[Annotated["InterfaceTemplateType", strawberry.lazy('dcim.graphql.types')]] - devicebaytemplates: List[Annotated["DeviceBayTemplateType", strawberry.lazy('dcim.graphql.types')]] - consoleporttemplates: List[Annotated["ConsolePortTemplateType", strawberry.lazy('dcim.graphql.types')]] + frontporttemplates: list[Annotated["FrontPortTemplateType", strawberry.lazy('dcim.graphql.types')]] + modulebaytemplates: list[Annotated["ModuleBayTemplateType", strawberry.lazy('dcim.graphql.types')]] + instances: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] + poweroutlettemplates: list[Annotated["PowerOutletTemplateType", strawberry.lazy('dcim.graphql.types')]] + powerporttemplates: list[Annotated["PowerPortTemplateType", strawberry.lazy('dcim.graphql.types')]] + inventoryitemtemplates: list[Annotated["InventoryItemTemplateType", strawberry.lazy('dcim.graphql.types')]] + rearporttemplates: list[Annotated["RearPortTemplateType", strawberry.lazy('dcim.graphql.types')]] + consoleserverporttemplates: list[Annotated["ConsoleServerPortTemplateType", strawberry.lazy('dcim.graphql.types')]] + interfacetemplates: list[Annotated["InterfaceTemplateType", strawberry.lazy('dcim.graphql.types')]] + devicebaytemplates: list[Annotated["DeviceBayTemplateType", strawberry.lazy('dcim.graphql.types')]] + consoleporttemplates: list[Annotated["ConsolePortTemplateType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -391,7 +392,7 @@ class DeviceTypeType(PrimaryObjectType): class FrontPortType(ModularComponentType, CabledObjectMixin): color: str - mappings: List[Annotated["PortMappingType", strawberry.lazy('dcim.graphql.types')]] + mappings: list[Annotated["PortMappingType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -403,7 +404,7 @@ class FrontPortType(ModularComponentType, CabledObjectMixin): class FrontPortTemplateType(ModularComponentTemplateType): color: str - mappings: List[Annotated["PortMappingTemplateType", strawberry.lazy('dcim.graphql.types')]] + mappings: list[Annotated["PortMappingTemplateType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -416,10 +417,11 @@ class MACAddressType(PrimaryObjectType): mac_address: str @strawberry_django.field - def assigned_object(self) -> Annotated[Union[ - Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')], - Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')], - ], strawberry.union("MACAddressAssignmentType")] | None: + def assigned_object(self) -> Annotated[ + Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')] + | Annotated['VMInterfaceType', strawberry.lazy('virtualization.graphql.types')], + strawberry.union('MACAddressAssignmentType'), + ] | None: return self.assigned_object @@ -443,13 +445,13 @@ class InterfaceType(IPAddressesMixin, ModularComponentType, CabledObjectMixin, P vlan_translation_policy: Annotated["VLANTranslationPolicyType", strawberry.lazy('ipam.graphql.types')] | None l2vpn_termination: Annotated["L2VPNTerminationType", strawberry.lazy('vpn.graphql.types')] | None - vdcs: List[Annotated["VirtualDeviceContextType", strawberry.lazy('dcim.graphql.types')]] - tagged_vlans: List[Annotated["VLANType", strawberry.lazy('ipam.graphql.types')]] - bridge_interfaces: List[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] - wireless_lans: List[Annotated["WirelessLANType", strawberry.lazy('wireless.graphql.types')]] - member_interfaces: List[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] - child_interfaces: List[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] - mac_addresses: List[Annotated["MACAddressType", strawberry.lazy('dcim.graphql.types')]] + vdcs: list[Annotated["VirtualDeviceContextType", strawberry.lazy('dcim.graphql.types')]] + tagged_vlans: list[Annotated["VLANType", strawberry.lazy('ipam.graphql.types')]] + bridge_interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] + wireless_lans: list[Annotated["WirelessLANType", strawberry.lazy('wireless.graphql.types')]] + member_interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] + child_interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] + mac_addresses: list[Annotated["MACAddressType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -462,7 +464,7 @@ class InterfaceTemplateType(ModularComponentTemplateType): _name: str bridge: Annotated["InterfaceTemplateType", strawberry.lazy('dcim.graphql.types')] | None - bridge_interfaces: List[Annotated["InterfaceTemplateType", strawberry.lazy('dcim.graphql.types')]] + bridge_interfaces: list[Annotated["InterfaceTemplateType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -472,24 +474,25 @@ class InterfaceTemplateType(ModularComponentTemplateType): pagination=True ) class InventoryItemType(ComponentType): - role: Annotated["InventoryItemRoleType", strawberry.lazy('dcim.graphql.types')] | None - manufacturer: Annotated["ManufacturerType", strawberry.lazy('dcim.graphql.types')] | None + role: Annotated['InventoryItemRoleType', strawberry.lazy('dcim.graphql.types')] | None + manufacturer: Annotated['ManufacturerType', strawberry.lazy('dcim.graphql.types')] | None - child_items: List[Annotated["InventoryItemType", strawberry.lazy('dcim.graphql.types')]] + child_items: list[Annotated['InventoryItemType', strawberry.lazy('dcim.graphql.types')]] @strawberry_django.field - def parent(self) -> Annotated["InventoryItemType", strawberry.lazy('dcim.graphql.types')] | None: + def parent(self) -> Annotated['InventoryItemType', strawberry.lazy('dcim.graphql.types')] | None: return self.parent - component: Annotated[Union[ - Annotated["ConsolePortType", strawberry.lazy('dcim.graphql.types')], - Annotated["ConsoleServerPortType", strawberry.lazy('dcim.graphql.types')], - Annotated["FrontPortType", strawberry.lazy('dcim.graphql.types')], - Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')], - Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')], - Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')], - Annotated["RearPortType", strawberry.lazy('dcim.graphql.types')], - ], strawberry.union("InventoryItemComponentType")] | None + component: Annotated[ + Annotated['ConsolePortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['ConsoleServerPortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['FrontPortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')] + | Annotated['PowerOutletType', strawberry.lazy('dcim.graphql.types')] + | Annotated['PowerPortType', strawberry.lazy('dcim.graphql.types')] + | Annotated['RearPortType', strawberry.lazy('dcim.graphql.types')], + strawberry.union('InventoryItemComponentType'), + ] | None @strawberry_django.type( @@ -501,8 +504,8 @@ class InventoryItemType(ComponentType): class InventoryItemRoleType(OrganizationalObjectType): color: str - inventory_items: List[Annotated["InventoryItemType", strawberry.lazy('dcim.graphql.types')]] - inventory_item_templates: List[Annotated["InventoryItemTemplateType", strawberry.lazy('dcim.graphql.types')]] + inventory_items: list[Annotated["InventoryItemType", strawberry.lazy('dcim.graphql.types')]] + inventory_item_templates: list[Annotated["InventoryItemTemplateType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -517,18 +520,18 @@ class LocationType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, Nested tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None parent: Annotated["LocationType", strawberry.lazy('dcim.graphql.types')] | None - powerpanel_set: List[Annotated["PowerPanelType", strawberry.lazy('dcim.graphql.types')]] - cabletermination_set: List[Annotated["CableTerminationType", strawberry.lazy('dcim.graphql.types')]] - racks: List[Annotated["RackType", strawberry.lazy('dcim.graphql.types')]] - devices: List[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] - children: List[Annotated["LocationType", strawberry.lazy('dcim.graphql.types')]] + powerpanel_set: list[Annotated["PowerPanelType", strawberry.lazy('dcim.graphql.types')]] + cabletermination_set: list[Annotated["CableTerminationType", strawberry.lazy('dcim.graphql.types')]] + racks: list[Annotated["RackType", strawberry.lazy('dcim.graphql.types')]] + devices: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] + children: list[Annotated["LocationType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.field - def clusters(self) -> List[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]: + def clusters(self) -> list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]: return self.cluster_set.all() @strawberry_django.field - def circuit_terminations(self) -> List[ + def circuit_terminations(self) -> list[ Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')] ]: return self.circuit_terminations.all() @@ -542,11 +545,11 @@ class LocationType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, Nested ) class ManufacturerType(OrganizationalObjectType, ContactsMixin): - platforms: List[Annotated["PlatformType", strawberry.lazy('dcim.graphql.types')]] - device_types: List[Annotated["DeviceTypeType", strawberry.lazy('dcim.graphql.types')]] - inventory_item_templates: List[Annotated["InventoryItemTemplateType", strawberry.lazy('dcim.graphql.types')]] - inventory_items: List[Annotated["InventoryItemType", strawberry.lazy('dcim.graphql.types')]] - module_types: List[Annotated["ModuleTypeType", strawberry.lazy('dcim.graphql.types')]] + platforms: list[Annotated["PlatformType", strawberry.lazy('dcim.graphql.types')]] + device_types: list[Annotated["DeviceTypeType", strawberry.lazy('dcim.graphql.types')]] + inventory_item_templates: list[Annotated["InventoryItemTemplateType", strawberry.lazy('dcim.graphql.types')]] + inventory_items: list[Annotated["InventoryItemType", strawberry.lazy('dcim.graphql.types')]] + module_types: list[Annotated["ModuleTypeType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -560,13 +563,13 @@ class ModuleType(PrimaryObjectType): module_bay: Annotated["ModuleBayType", strawberry.lazy('dcim.graphql.types')] module_type: Annotated["ModuleTypeType", strawberry.lazy('dcim.graphql.types')] - interfaces: List[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] - powerports: List[Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')]] - consoleserverports: List[Annotated["ConsoleServerPortType", strawberry.lazy('dcim.graphql.types')]] - consoleports: List[Annotated["ConsolePortType", strawberry.lazy('dcim.graphql.types')]] - poweroutlets: List[Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')]] - rearports: List[Annotated["RearPortType", strawberry.lazy('dcim.graphql.types')]] - frontports: List[Annotated["FrontPortType", strawberry.lazy('dcim.graphql.types')]] + interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] + powerports: list[Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')]] + consoleserverports: list[Annotated["ConsoleServerPortType", strawberry.lazy('dcim.graphql.types')]] + consoleports: list[Annotated["ConsolePortType", strawberry.lazy('dcim.graphql.types')]] + poweroutlets: list[Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')]] + rearports: list[Annotated["RearPortType", strawberry.lazy('dcim.graphql.types')]] + frontports: list[Annotated["FrontPortType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -579,7 +582,7 @@ class ModuleType(PrimaryObjectType): class ModuleBayType(ModularComponentType): installed_module: Annotated["ModuleType", strawberry.lazy('dcim.graphql.types')] | None - children: List[Annotated["ModuleBayType", strawberry.lazy('dcim.graphql.types')]] + children: list[Annotated["ModuleBayType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.field def parent(self) -> Annotated["ModuleBayType", strawberry.lazy('dcim.graphql.types')] | None: @@ -603,7 +606,7 @@ class ModuleBayTemplateType(ModularComponentTemplateType): pagination=True ) class ModuleTypeProfileType(PrimaryObjectType): - module_types: List[Annotated["ModuleType", strawberry.lazy('dcim.graphql.types')]] + module_types: list[Annotated["ModuleType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -617,14 +620,14 @@ class ModuleTypeType(PrimaryObjectType): profile: Annotated["ModuleTypeProfileType", strawberry.lazy('dcim.graphql.types')] | None manufacturer: Annotated["ManufacturerType", strawberry.lazy('dcim.graphql.types')] - frontporttemplates: List[Annotated["FrontPortTemplateType", strawberry.lazy('dcim.graphql.types')]] - consoleserverporttemplates: List[Annotated["ConsoleServerPortTemplateType", strawberry.lazy('dcim.graphql.types')]] - interfacetemplates: List[Annotated["InterfaceTemplateType", strawberry.lazy('dcim.graphql.types')]] - powerporttemplates: List[Annotated["PowerPortTemplateType", strawberry.lazy('dcim.graphql.types')]] - poweroutlettemplates: List[Annotated["PowerOutletTemplateType", strawberry.lazy('dcim.graphql.types')]] - rearporttemplates: List[Annotated["RearPortTemplateType", strawberry.lazy('dcim.graphql.types')]] - instances: List[Annotated["ModuleType", strawberry.lazy('dcim.graphql.types')]] - consoleporttemplates: List[Annotated["ConsolePortTemplateType", strawberry.lazy('dcim.graphql.types')]] + frontporttemplates: list[Annotated["FrontPortTemplateType", strawberry.lazy('dcim.graphql.types')]] + consoleserverporttemplates: list[Annotated["ConsoleServerPortTemplateType", strawberry.lazy('dcim.graphql.types')]] + interfacetemplates: list[Annotated["InterfaceTemplateType", strawberry.lazy('dcim.graphql.types')]] + powerporttemplates: list[Annotated["PowerPortTemplateType", strawberry.lazy('dcim.graphql.types')]] + poweroutlettemplates: list[Annotated["PowerOutletTemplateType", strawberry.lazy('dcim.graphql.types')]] + rearporttemplates: list[Annotated["RearPortTemplateType", strawberry.lazy('dcim.graphql.types')]] + instances: list[Annotated["ModuleType", strawberry.lazy('dcim.graphql.types')]] + consoleporttemplates: list[Annotated["ConsolePortTemplateType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -635,12 +638,12 @@ class ModuleTypeType(PrimaryObjectType): ) class PlatformType(NestedGroupObjectType): parent: Annotated['PlatformType', strawberry.lazy('dcim.graphql.types')] | None - children: List[Annotated['PlatformType', strawberry.lazy('dcim.graphql.types')]] + children: list[Annotated['PlatformType', strawberry.lazy('dcim.graphql.types')]] manufacturer: Annotated["ManufacturerType", strawberry.lazy('dcim.graphql.types')] | None config_template: Annotated["ConfigTemplateType", strawberry.lazy('extras.graphql.types')] | None - virtual_machines: List[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]] - devices: List[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] + virtual_machines: list[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]] + devices: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -709,7 +712,7 @@ class PowerPanelType(ContactsMixin, PrimaryObjectType): site: Annotated["SiteType", strawberry.lazy('dcim.graphql.types')] location: Annotated["LocationType", strawberry.lazy('dcim.graphql.types')] | None - powerfeeds: List[Annotated["PowerFeedType", strawberry.lazy('dcim.graphql.types')]] + powerfeeds: list[Annotated["PowerFeedType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -720,7 +723,7 @@ class PowerPanelType(ContactsMixin, PrimaryObjectType): ) class PowerPortType(ModularComponentType, CabledObjectMixin, PathEndpointMixin): - poweroutlets: List[Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')]] + poweroutlets: list[Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -730,7 +733,7 @@ class PowerPortType(ModularComponentType, CabledObjectMixin, PathEndpointMixin): pagination=True ) class PowerPortTemplateType(ModularComponentTemplateType): - poweroutlet_templates: List[Annotated["PowerOutletTemplateType", strawberry.lazy('dcim.graphql.types')]] + poweroutlet_templates: list[Annotated["PowerOutletTemplateType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -757,10 +760,10 @@ class RackType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, PrimaryObj role: Annotated["RackRoleType", strawberry.lazy('dcim.graphql.types')] | None rack_type: Annotated["RackTypeType", strawberry.lazy('dcim.graphql.types')] | None - reservations: List[Annotated["RackReservationType", strawberry.lazy('dcim.graphql.types')]] - devices: List[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] - powerfeeds: List[Annotated["PowerFeedType", strawberry.lazy('dcim.graphql.types')]] - cabletermination_set: List[Annotated["CableTerminationType", strawberry.lazy('dcim.graphql.types')]] + reservations: list[Annotated["RackReservationType", strawberry.lazy('dcim.graphql.types')]] + devices: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] + powerfeeds: list[Annotated["PowerFeedType", strawberry.lazy('dcim.graphql.types')]] + cabletermination_set: list[Annotated["CableTerminationType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -770,7 +773,7 @@ class RackType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, PrimaryObj pagination=True ) class RackReservationType(PrimaryObjectType): - units: List[int] + units: list[int] rack: Annotated["RackType", strawberry.lazy('dcim.graphql.types')] tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None user: Annotated["UserType", strawberry.lazy('users.graphql.types')] @@ -785,7 +788,7 @@ class RackReservationType(PrimaryObjectType): class RackRoleType(OrganizationalObjectType): color: str - racks: List[Annotated["RackType", strawberry.lazy('dcim.graphql.types')]] + racks: list[Annotated["RackType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -797,7 +800,7 @@ class RackRoleType(OrganizationalObjectType): class RearPortType(ModularComponentType, CabledObjectMixin): color: str - mappings: List[Annotated["PortMappingType", strawberry.lazy('dcim.graphql.types')]] + mappings: list[Annotated["PortMappingType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -809,7 +812,7 @@ class RearPortType(ModularComponentType, CabledObjectMixin): class RearPortTemplateType(ModularComponentTemplateType): color: str - mappings: List[Annotated["PortMappingTemplateType", strawberry.lazy('dcim.graphql.types')]] + mappings: list[Annotated["PortMappingTemplateType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -820,19 +823,19 @@ class RearPortTemplateType(ModularComponentTemplateType): ) class RegionType(VLANGroupsMixin, ContactsMixin, NestedGroupObjectType): - sites: List[Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]] - children: List[Annotated["RegionType", strawberry.lazy('dcim.graphql.types')]] + sites: list[Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]] + children: list[Annotated["RegionType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.field def parent(self) -> Annotated["RegionType", strawberry.lazy('dcim.graphql.types')] | None: return self.parent @strawberry_django.field - def clusters(self) -> List[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]: + def clusters(self) -> list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]: return self.cluster_set.all() @strawberry_django.field - def circuit_terminations(self) -> List[ + def circuit_terminations(self) -> list[ Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')] ]: return self.circuit_terminations.all() @@ -850,24 +853,24 @@ class SiteType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, PrimaryObj group: Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')] | None tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None - prefixes: List[Annotated["PrefixType", strawberry.lazy('ipam.graphql.types')]] - virtual_machines: List[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]] - racks: List[Annotated["RackType", strawberry.lazy('dcim.graphql.types')]] - cabletermination_set: List[Annotated["CableTerminationType", strawberry.lazy('dcim.graphql.types')]] - powerpanel_set: List[Annotated["PowerPanelType", strawberry.lazy('dcim.graphql.types')]] - devices: List[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] - locations: List[Annotated["LocationType", strawberry.lazy('dcim.graphql.types')]] - asns: List[Annotated["ASNType", strawberry.lazy('ipam.graphql.types')]] - circuit_terminations: List[Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]] - clusters: List[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]] - vlans: List[Annotated["VLANType", strawberry.lazy('ipam.graphql.types')]] + prefixes: list[Annotated["PrefixType", strawberry.lazy('ipam.graphql.types')]] + virtual_machines: list[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]] + racks: list[Annotated["RackType", strawberry.lazy('dcim.graphql.types')]] + cabletermination_set: list[Annotated["CableTerminationType", strawberry.lazy('dcim.graphql.types')]] + powerpanel_set: list[Annotated["PowerPanelType", strawberry.lazy('dcim.graphql.types')]] + devices: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] + locations: list[Annotated["LocationType", strawberry.lazy('dcim.graphql.types')]] + asns: list[Annotated["ASNType", strawberry.lazy('ipam.graphql.types')]] + circuit_terminations: list[Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]] + clusters: list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]] + vlans: list[Annotated["VLANType", strawberry.lazy('ipam.graphql.types')]] @strawberry_django.field - def clusters(self) -> List[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]: + def clusters(self) -> list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]: return self.cluster_set.all() @strawberry_django.field - def circuit_terminations(self) -> List[ + def circuit_terminations(self) -> list[ Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')] ]: return self.circuit_terminations.all() @@ -881,19 +884,19 @@ class SiteType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, PrimaryObj ) class SiteGroupType(VLANGroupsMixin, ContactsMixin, NestedGroupObjectType): - sites: List[Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]] - children: List[Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')]] + sites: list[Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]] + children: list[Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.field def parent(self) -> Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')] | None: return self.parent @strawberry_django.field - def clusters(self) -> List[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]: + def clusters(self) -> list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]: return self.cluster_set.all() @strawberry_django.field - def circuit_terminations(self) -> List[ + def circuit_terminations(self) -> list[ Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')] ]: return self.circuit_terminations.all() @@ -909,7 +912,7 @@ class VirtualChassisType(PrimaryObjectType): member_count: BigInt master: Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')] | None - members: List[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] + members: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -924,4 +927,4 @@ class VirtualDeviceContextType(PrimaryObjectType): primary_ip6: Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')] | None tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None - interfaces: List[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] + interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] diff --git a/netbox/dcim/management/commands/trace_paths.py b/netbox/dcim/management/commands/trace_paths.py index ded4e1780..bc075c2e4 100644 --- a/netbox/dcim/management/commands/trace_paths.py +++ b/netbox/dcim/management/commands/trace_paths.py @@ -57,7 +57,7 @@ class Command(BaseCommand): # Delete all existing CablePath instances self.stdout.write(f"Deleting {paths_count} existing cable paths...") deleted_count, _ = CablePath.objects.all().delete() - self.stdout.write((self.style.SUCCESS(f' Deleted {deleted_count} paths'))) + self.stdout.write(self.style.SUCCESS(f' Deleted {deleted_count} paths')) # Reinitialize the model's PK sequence self.stdout.write('Resetting database sequence for CablePath model') diff --git a/netbox/dcim/svg/cables.py b/netbox/dcim/svg/cables.py index 1a8844daf..587027d59 100644 --- a/netbox/dcim/svg/cables.py +++ b/netbox/dcim/svg/cables.py @@ -37,7 +37,7 @@ class Node(Hyperlink): object = None def __init__(self, position, width, url, color, labels, radius=10, object=object, **extra): - super(Node, self).__init__(href=url, target='_parent', **extra) + super().__init__(href=url, target='_parent', **extra) # Save object for reference by cable systems self.object = object diff --git a/netbox/extras/graphql/mixins.py b/netbox/extras/graphql/mixins.py index 360cdc50a..719d95f79 100644 --- a/netbox/extras/graphql/mixins.py +++ b/netbox/extras/graphql/mixins.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Annotated, List +from typing import TYPE_CHECKING, Annotated import strawberry import strawberry_django @@ -39,7 +39,7 @@ class CustomFieldsMixin: class ImageAttachmentsMixin: @strawberry_django.field - def image_attachments(self, info: Info) -> List[Annotated['ImageAttachmentType', strawberry.lazy('.types')]]: + def image_attachments(self, info: Info) -> list[Annotated['ImageAttachmentType', strawberry.lazy('.types')]]: return self.images.restrict(info.context.request.user, 'view') @@ -47,17 +47,17 @@ class ImageAttachmentsMixin: class JournalEntriesMixin: @strawberry_django.field - def journal_entries(self, info: Info) -> List[Annotated['JournalEntryType', strawberry.lazy('.types')]]: + def journal_entries(self, info: Info) -> list[Annotated['JournalEntryType', strawberry.lazy('.types')]]: return self.journal_entries.all() @strawberry.type class TagsMixin: - tags: List[Annotated['TagType', strawberry.lazy('.types')]] + tags: list[Annotated['TagType', strawberry.lazy('.types')]] @strawberry.type class ContactsMixin: - contacts: List[Annotated['ContactAssignmentType', strawberry.lazy('tenancy.graphql.types')]] + contacts: list[Annotated['ContactAssignmentType', strawberry.lazy('tenancy.graphql.types')]] diff --git a/netbox/extras/graphql/schema.py b/netbox/extras/graphql/schema.py index 60d596f01..6ec920d83 100644 --- a/netbox/extras/graphql/schema.py +++ b/netbox/extras/graphql/schema.py @@ -1,5 +1,3 @@ -from typing import List - import strawberry import strawberry_django @@ -9,52 +7,52 @@ from .types import * @strawberry.type(name="Query") class ExtrasQuery: config_context: ConfigContextType = strawberry_django.field() - config_context_list: List[ConfigContextType] = strawberry_django.field() + config_context_list: list[ConfigContextType] = strawberry_django.field() config_context_profile: ConfigContextProfileType = strawberry_django.field() - config_context_profile_list: List[ConfigContextProfileType] = strawberry_django.field() + config_context_profile_list: list[ConfigContextProfileType] = strawberry_django.field() config_template: ConfigTemplateType = strawberry_django.field() - config_template_list: List[ConfigTemplateType] = strawberry_django.field() + config_template_list: list[ConfigTemplateType] = strawberry_django.field() custom_field: CustomFieldType = strawberry_django.field() - custom_field_list: List[CustomFieldType] = strawberry_django.field() + custom_field_list: list[CustomFieldType] = strawberry_django.field() custom_field_choice_set: CustomFieldChoiceSetType = strawberry_django.field() - custom_field_choice_set_list: List[CustomFieldChoiceSetType] = strawberry_django.field() + custom_field_choice_set_list: list[CustomFieldChoiceSetType] = strawberry_django.field() custom_link: CustomLinkType = strawberry_django.field() - custom_link_list: List[CustomLinkType] = strawberry_django.field() + custom_link_list: list[CustomLinkType] = strawberry_django.field() export_template: ExportTemplateType = strawberry_django.field() - export_template_list: List[ExportTemplateType] = strawberry_django.field() + export_template_list: list[ExportTemplateType] = strawberry_django.field() image_attachment: ImageAttachmentType = strawberry_django.field() - image_attachment_list: List[ImageAttachmentType] = strawberry_django.field() + image_attachment_list: list[ImageAttachmentType] = strawberry_django.field() saved_filter: SavedFilterType = strawberry_django.field() - saved_filter_list: List[SavedFilterType] = strawberry_django.field() + saved_filter_list: list[SavedFilterType] = strawberry_django.field() table_config: TableConfigType = strawberry_django.field() - table_config_list: List[TableConfigType] = strawberry_django.field() + table_config_list: list[TableConfigType] = strawberry_django.field() journal_entry: JournalEntryType = strawberry_django.field() - journal_entry_list: List[JournalEntryType] = strawberry_django.field() + journal_entry_list: list[JournalEntryType] = strawberry_django.field() notification: NotificationType = strawberry_django.field() - notification_list: List[NotificationType] = strawberry_django.field() + notification_list: list[NotificationType] = strawberry_django.field() notification_group: NotificationGroupType = strawberry_django.field() - notification_group_list: List[NotificationGroupType] = strawberry_django.field() + notification_group_list: list[NotificationGroupType] = strawberry_django.field() subscription: SubscriptionType = strawberry_django.field() - subscription_list: List[SubscriptionType] = strawberry_django.field() + subscription_list: list[SubscriptionType] = strawberry_django.field() tag: TagType = strawberry_django.field() - tag_list: List[TagType] = strawberry_django.field() + tag_list: list[TagType] = strawberry_django.field() webhook: WebhookType = strawberry_django.field() - webhook_list: List[WebhookType] = strawberry_django.field() + webhook_list: list[WebhookType] = strawberry_django.field() event_rule: EventRuleType = strawberry_django.field() - event_rule_list: List[EventRuleType] = strawberry_django.field() + event_rule_list: list[EventRuleType] = strawberry_django.field() diff --git a/netbox/extras/graphql/types.py b/netbox/extras/graphql/types.py index bb37f5c29..1aac5e971 100644 --- a/netbox/extras/graphql/types.py +++ b/netbox/extras/graphql/types.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Annotated, List +from typing import TYPE_CHECKING, Annotated import strawberry import strawberry_django @@ -65,19 +65,19 @@ class ConfigContextProfileType(SyncedDataMixin, PrimaryObjectType): ) class ConfigContextType(SyncedDataMixin, OwnerMixin, ObjectType): profile: ConfigContextProfileType | None - roles: List[Annotated["DeviceRoleType", strawberry.lazy('dcim.graphql.types')]] - device_types: List[Annotated["DeviceTypeType", strawberry.lazy('dcim.graphql.types')]] - tags: List[Annotated["TagType", strawberry.lazy('extras.graphql.types')]] - platforms: List[Annotated["PlatformType", strawberry.lazy('dcim.graphql.types')]] - regions: List[Annotated["RegionType", strawberry.lazy('dcim.graphql.types')]] - cluster_groups: List[Annotated["ClusterGroupType", strawberry.lazy('virtualization.graphql.types')]] - tenant_groups: List[Annotated["TenantGroupType", strawberry.lazy('tenancy.graphql.types')]] - cluster_types: List[Annotated["ClusterTypeType", strawberry.lazy('virtualization.graphql.types')]] - clusters: List[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]] - locations: List[Annotated["LocationType", strawberry.lazy('dcim.graphql.types')]] - sites: List[Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]] - tenants: List[Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')]] - site_groups: List[Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')]] + roles: list[Annotated["DeviceRoleType", strawberry.lazy('dcim.graphql.types')]] + device_types: list[Annotated["DeviceTypeType", strawberry.lazy('dcim.graphql.types')]] + tags: list[Annotated["TagType", strawberry.lazy('extras.graphql.types')]] + platforms: list[Annotated["PlatformType", strawberry.lazy('dcim.graphql.types')]] + regions: list[Annotated["RegionType", strawberry.lazy('dcim.graphql.types')]] + cluster_groups: list[Annotated["ClusterGroupType", strawberry.lazy('virtualization.graphql.types')]] + tenant_groups: list[Annotated["TenantGroupType", strawberry.lazy('tenancy.graphql.types')]] + cluster_types: list[Annotated["ClusterTypeType", strawberry.lazy('virtualization.graphql.types')]] + clusters: list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]] + locations: list[Annotated["LocationType", strawberry.lazy('dcim.graphql.types')]] + sites: list[Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]] + tenants: list[Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')]] + site_groups: list[Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -87,10 +87,10 @@ class ConfigContextType(SyncedDataMixin, OwnerMixin, ObjectType): pagination=True ) class ConfigTemplateType(SyncedDataMixin, OwnerMixin, TagsMixin, ObjectType): - virtualmachines: List[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]] - devices: List[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] - platforms: List[Annotated["PlatformType", strawberry.lazy('dcim.graphql.types')]] - device_roles: List[Annotated["DeviceRoleType", strawberry.lazy('dcim.graphql.types')]] + virtualmachines: list[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]] + devices: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] + platforms: list[Annotated["PlatformType", strawberry.lazy('dcim.graphql.types')]] + device_roles: list[Annotated["DeviceRoleType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( @@ -112,8 +112,8 @@ class CustomFieldType(OwnerMixin, ObjectType): ) class CustomFieldChoiceSetType(OwnerMixin, ObjectType): - choices_for: List[Annotated["CustomFieldType", strawberry.lazy('extras.graphql.types')]] - extra_choices: List[List[str]] | None + choices_for: list[Annotated["CustomFieldType", strawberry.lazy('extras.graphql.types')]] + extra_choices: list[list[str]] | None @strawberry_django.type( @@ -172,8 +172,8 @@ class NotificationType(ObjectType): pagination=True ) class NotificationGroupType(ObjectType): - users: List[Annotated["UserType", strawberry.lazy('users.graphql.types')]] - groups: List[Annotated["GroupType", strawberry.lazy('users.graphql.types')]] + users: list[Annotated["UserType", strawberry.lazy('users.graphql.types')]] + groups: list[Annotated["GroupType", strawberry.lazy('users.graphql.types')]] @strawberry_django.type( @@ -214,7 +214,7 @@ class TableConfigType(ObjectType): class TagType(OwnerMixin, ObjectType): color: str - object_types: List[ContentTypeType] + object_types: list[ContentTypeType] @strawberry_django.type( diff --git a/netbox/extras/lookups.py b/netbox/extras/lookups.py index d32259312..062a2a01b 100644 --- a/netbox/extras/lookups.py +++ b/netbox/extras/lookups.py @@ -82,7 +82,7 @@ class NetHost(Lookup): lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params - return 'HOST(CAST(%s AS INET)) = HOST(%s)' % (lhs, rhs), params + return f'HOST(CAST({lhs} AS INET)) = HOST({rhs})', params class NetContainsOrEquals(Lookup): @@ -95,7 +95,7 @@ class NetContainsOrEquals(Lookup): lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params - return 'CAST(%s AS INET) >>= %s' % (lhs, rhs), params + return f'CAST({lhs} AS INET) >>= {rhs}', params ArrayField.register_lookup(RangeContains) diff --git a/netbox/extras/migrations/0111_rename_content_types.py b/netbox/extras/migrations/0111_rename_content_types.py index 8a5db53ff..cfb33a3bc 100644 --- a/netbox/extras/migrations/0111_rename_content_types.py +++ b/netbox/extras/migrations/0111_rename_content_types.py @@ -27,15 +27,15 @@ class Migration(migrations.Migration): blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='contenttypes.contenttype' ), ), - migrations.RunSQL(( + migrations.RunSQL( 'ALTER TABLE IF EXISTS extras_customfield_content_types_id_seq ' 'RENAME TO extras_customfield_object_types_id_seq' - )), + ), # Pre-v2.10 sequence name (see #15605) - migrations.RunSQL(( + migrations.RunSQL( 'ALTER TABLE IF EXISTS extras_customfield_obj_type_id_seq ' 'RENAME TO extras_customfield_object_types_id_seq' - )), + ), # Custom links migrations.RenameField( model_name='customlink', diff --git a/netbox/extras/models/tags.py b/netbox/extras/models/tags.py index bff9598d1..1fdb48462 100644 --- a/netbox/extras/models/tags.py +++ b/netbox/extras/models/tags.py @@ -66,7 +66,7 @@ class Tag(CloningMixin, ExportTemplatesMixin, OwnerMixin, ChangeLoggedModel, Tag # Allow Unicode in Tag slugs (avoids empty slugs for Tags with all-Unicode names) slug = slugify(tag, allow_unicode=True) if i is not None: - slug += "_%d" % i + slug += f'_{i}' return slug diff --git a/netbox/extras/tests/test_filtersets.py b/netbox/extras/tests/test_filtersets.py index 056776f75..4eb8533eb 100644 --- a/netbox/extras/tests/test_filtersets.py +++ b/netbox/extras/tests/test_filtersets.py @@ -1,5 +1,5 @@ import uuid -from datetime import datetime, timezone +from datetime import UTC, datetime from django.contrib.contenttypes.models import ContentType from django.test import TestCase @@ -862,7 +862,7 @@ class JournalEntryTestCase(TestCase, ChangeLoggedFilterSetTests): def test_created(self): pk_list = self.queryset.values_list('pk', flat=True)[:2] - self.queryset.filter(pk__in=pk_list).update(created=datetime(2021, 1, 1, 0, 0, 0, tzinfo=timezone.utc)) + self.queryset.filter(pk__in=pk_list).update(created=datetime(2021, 1, 1, 0, 0, 0, tzinfo=UTC)) params = { 'created_after': '2020-12-31T00:00:00', 'created_before': '2021-01-02T00:00:00', diff --git a/netbox/extras/tests/test_scripts.py b/netbox/extras/tests/test_scripts.py index 5db15bd41..bd4033e92 100644 --- a/netbox/extras/tests/test_scripts.py +++ b/netbox/extras/tests/test_scripts.py @@ -1,4 +1,4 @@ -from datetime import date, datetime, timezone +from datetime import UTC, date, datetime from decimal import Decimal from django.core.files.uploadedfile import SimpleUploadedFile @@ -381,7 +381,7 @@ class ScriptVariablesTest(TestCase): self.assertIn('var1', form.errors) # Validate valid data - input_datetime = datetime(2024, 4, 1, 8, 0, 0, 0, timezone.utc) + input_datetime = datetime(2024, 4, 1, 8, 0, 0, 0, UTC) data = {'var1': input_datetime} form = TestScript().as_form(data, None) self.assertTrue(form.is_valid()) diff --git a/netbox/ipam/graphql/mixins.py b/netbox/ipam/graphql/mixins.py index 692741871..e4a616e8d 100644 --- a/netbox/ipam/graphql/mixins.py +++ b/netbox/ipam/graphql/mixins.py @@ -1,4 +1,4 @@ -from typing import Annotated, List +from typing import Annotated import strawberry @@ -10,9 +10,9 @@ __all__ = ( @strawberry.type class IPAddressesMixin: - ip_addresses: List[Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')]] # noqa: F821 + ip_addresses: list[Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')]] # noqa: F821 @strawberry.type class VLANGroupsMixin: - vlan_groups: List[Annotated["VLANGroupType", strawberry.lazy('ipam.graphql.types')]] # noqa: F821 + vlan_groups: list[Annotated["VLANGroupType", strawberry.lazy('ipam.graphql.types')]] # noqa: F821 diff --git a/netbox/ipam/graphql/schema.py b/netbox/ipam/graphql/schema.py index 5fcf78ea9..253debfa3 100644 --- a/netbox/ipam/graphql/schema.py +++ b/netbox/ipam/graphql/schema.py @@ -1,5 +1,3 @@ -from typing import List - import strawberry import strawberry_django @@ -9,55 +7,55 @@ from .types import * @strawberry.type(name="Query") class IPAMQuery: asn: ASNType = strawberry_django.field() - asn_list: List[ASNType] = strawberry_django.field() + asn_list: list[ASNType] = strawberry_django.field() asn_range: ASNRangeType = strawberry_django.field() - asn_range_list: List[ASNRangeType] = strawberry_django.field() + asn_range_list: list[ASNRangeType] = strawberry_django.field() aggregate: AggregateType = strawberry_django.field() - aggregate_list: List[AggregateType] = strawberry_django.field() + aggregate_list: list[AggregateType] = strawberry_django.field() ip_address: IPAddressType = strawberry_django.field() - ip_address_list: List[IPAddressType] = strawberry_django.field() + ip_address_list: list[IPAddressType] = strawberry_django.field() ip_range: IPRangeType = strawberry_django.field() - ip_range_list: List[IPRangeType] = strawberry_django.field() + ip_range_list: list[IPRangeType] = strawberry_django.field() prefix: PrefixType = strawberry_django.field() - prefix_list: List[PrefixType] = strawberry_django.field() + prefix_list: list[PrefixType] = strawberry_django.field() rir: RIRType = strawberry_django.field() - rir_list: List[RIRType] = strawberry_django.field() + rir_list: list[RIRType] = strawberry_django.field() role: RoleType = strawberry_django.field() - role_list: List[RoleType] = strawberry_django.field() + role_list: list[RoleType] = strawberry_django.field() route_target: RouteTargetType = strawberry_django.field() - route_target_list: List[RouteTargetType] = strawberry_django.field() + route_target_list: list[RouteTargetType] = strawberry_django.field() service: ServiceType = strawberry_django.field() - service_list: List[ServiceType] = strawberry_django.field() + service_list: list[ServiceType] = strawberry_django.field() service_template: ServiceTemplateType = strawberry_django.field() - service_template_list: List[ServiceTemplateType] = strawberry_django.field() + service_template_list: list[ServiceTemplateType] = strawberry_django.field() fhrp_group: FHRPGroupType = strawberry_django.field() - fhrp_group_list: List[FHRPGroupType] = strawberry_django.field() + fhrp_group_list: list[FHRPGroupType] = strawberry_django.field() fhrp_group_assignment: FHRPGroupAssignmentType = strawberry_django.field() - fhrp_group_assignment_list: List[FHRPGroupAssignmentType] = strawberry_django.field() + fhrp_group_assignment_list: list[FHRPGroupAssignmentType] = strawberry_django.field() vlan: VLANType = strawberry_django.field() - vlan_list: List[VLANType] = strawberry_django.field() + vlan_list: list[VLANType] = strawberry_django.field() vlan_group: VLANGroupType = strawberry_django.field() - vlan_group_list: List[VLANGroupType] = strawberry_django.field() + vlan_group_list: list[VLANGroupType] = strawberry_django.field() vlan_translation_policy: VLANTranslationPolicyType = strawberry_django.field() - vlan_translation_policy_list: List[VLANTranslationPolicyType] = strawberry_django.field() + vlan_translation_policy_list: list[VLANTranslationPolicyType] = strawberry_django.field() vlan_translation_rule: VLANTranslationRuleType = strawberry_django.field() - vlan_translation_rule_list: List[VLANTranslationRuleType] = strawberry_django.field() + vlan_translation_rule_list: list[VLANTranslationRuleType] = strawberry_django.field() vrf: VRFType = strawberry_django.field() - vrf_list: List[VRFType] = strawberry_django.field() + vrf_list: list[VRFType] = strawberry_django.field() diff --git a/netbox/ipam/graphql/types.py b/netbox/ipam/graphql/types.py index eeb561903..cf957a914 100644 --- a/netbox/ipam/graphql/types.py +++ b/netbox/ipam/graphql/types.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Annotated, List, Union +from typing import TYPE_CHECKING, Annotated import strawberry import strawberry_django @@ -21,7 +21,6 @@ if TYPE_CHECKING: RackType, RegionType, SiteGroupType, - SiteType, ) from tenancy.graphql.types import TenantType from virtualization.graphql.types import ClusterGroupType, ClusterType, VirtualMachineType, VMInterfaceType @@ -80,8 +79,8 @@ class ASNType(ContactsMixin, PrimaryObjectType): rir: Annotated["RIRType", strawberry.lazy('ipam.graphql.types')] | None tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None - sites: List[SiteType] - providers: List[ProviderType] + sites: list[SiteType] + providers: list[ProviderType] @strawberry_django.type( @@ -116,7 +115,7 @@ class AggregateType(ContactsMixin, BaseIPAddressFamilyType, PrimaryObjectType): pagination=True ) class FHRPGroupType(IPAddressesMixin, PrimaryObjectType): - fhrpgroupassignment_set: List[Annotated["FHRPGroupAssignmentType", strawberry.lazy('ipam.graphql.types')]] + fhrpgroupassignment_set: list[Annotated["FHRPGroupAssignmentType", strawberry.lazy('ipam.graphql.types')]] @strawberry_django.type( @@ -126,13 +125,14 @@ class FHRPGroupType(IPAddressesMixin, PrimaryObjectType): pagination=True ) class FHRPGroupAssignmentType(BaseObjectType): - group: Annotated["FHRPGroupType", strawberry.lazy('ipam.graphql.types')] + group: Annotated['FHRPGroupType', strawberry.lazy('ipam.graphql.types')] @strawberry_django.field - def interface(self) -> Annotated[Union[ - Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')], - Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')], - ], strawberry.union("FHRPGroupInterfaceType")]: + def interface(self) -> Annotated[ + Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')] + | Annotated['VMInterfaceType', strawberry.lazy('virtualization.graphql.types')], + strawberry.union('FHRPGroupInterfaceType'), + ]: return self.interface @@ -144,20 +144,21 @@ class FHRPGroupAssignmentType(BaseObjectType): ) class IPAddressType(ContactsMixin, BaseIPAddressFamilyType, PrimaryObjectType): address: str - vrf: Annotated["VRFType", strawberry.lazy('ipam.graphql.types')] | None - tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None - nat_inside: Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')] | None + vrf: Annotated['VRFType', strawberry.lazy('ipam.graphql.types')] | None + tenant: Annotated['TenantType', strawberry.lazy('tenancy.graphql.types')] | None + nat_inside: Annotated['IPAddressType', strawberry.lazy('ipam.graphql.types')] | None - nat_outside: List[Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')]] - tunnel_terminations: List[Annotated["TunnelTerminationType", strawberry.lazy('vpn.graphql.types')]] - services: List[Annotated["ServiceType", strawberry.lazy('ipam.graphql.types')]] + nat_outside: list[Annotated['IPAddressType', strawberry.lazy('ipam.graphql.types')]] + tunnel_terminations: list[Annotated['TunnelTerminationType', strawberry.lazy('vpn.graphql.types')]] + services: list[Annotated['ServiceType', strawberry.lazy('ipam.graphql.types')]] @strawberry_django.field - def assigned_object(self) -> Annotated[Union[ - Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')], - Annotated["FHRPGroupType", strawberry.lazy('ipam.graphql.types')], - Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')], - ], strawberry.union("IPAddressAssignmentType")] | None: + def assigned_object(self) -> Annotated[ + Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')] + | Annotated['FHRPGroupType', strawberry.lazy('ipam.graphql.types')] + | Annotated['VMInterfaceType', strawberry.lazy('virtualization.graphql.types')], + strawberry.union('IPAddressAssignmentType'), + ] | None: return self.assigned_object @@ -183,18 +184,19 @@ class IPRangeType(ContactsMixin, PrimaryObjectType): ) class PrefixType(ContactsMixin, BaseIPAddressFamilyType, PrimaryObjectType): prefix: str - vrf: Annotated["VRFType", strawberry.lazy('ipam.graphql.types')] | None - tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None - vlan: Annotated["VLANType", strawberry.lazy('ipam.graphql.types')] | None - role: Annotated["RoleType", strawberry.lazy('ipam.graphql.types')] | None + vrf: Annotated['VRFType', strawberry.lazy('ipam.graphql.types')] | None + tenant: Annotated['TenantType', strawberry.lazy('tenancy.graphql.types')] | None + vlan: Annotated['VLANType', strawberry.lazy('ipam.graphql.types')] | None + role: Annotated['RoleType', strawberry.lazy('ipam.graphql.types')] | None @strawberry_django.field - def scope(self) -> Annotated[Union[ - Annotated["LocationType", strawberry.lazy('dcim.graphql.types')], - Annotated["RegionType", strawberry.lazy('dcim.graphql.types')], - Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')], - Annotated["SiteType", strawberry.lazy('dcim.graphql.types')], - ], strawberry.union("PrefixScopeType")] | None: + def scope(self) -> Annotated[ + Annotated['LocationType', strawberry.lazy('dcim.graphql.types')] + | Annotated['RegionType', strawberry.lazy('dcim.graphql.types')] + | Annotated['SiteGroupType', strawberry.lazy('dcim.graphql.types')] + | Annotated['SiteType', strawberry.lazy('dcim.graphql.types')], + strawberry.union('PrefixScopeType'), + ] | None: return self.scope @@ -206,9 +208,9 @@ class PrefixType(ContactsMixin, BaseIPAddressFamilyType, PrimaryObjectType): ) class RIRType(OrganizationalObjectType): - asn_ranges: List[Annotated["ASNRangeType", strawberry.lazy('ipam.graphql.types')]] - asns: List[Annotated["ASNType", strawberry.lazy('ipam.graphql.types')]] - aggregates: List[Annotated["AggregateType", strawberry.lazy('ipam.graphql.types')]] + asn_ranges: list[Annotated["ASNRangeType", strawberry.lazy('ipam.graphql.types')]] + asns: list[Annotated["ASNType", strawberry.lazy('ipam.graphql.types')]] + aggregates: list[Annotated["AggregateType", strawberry.lazy('ipam.graphql.types')]] @strawberry_django.type( @@ -219,9 +221,9 @@ class RIRType(OrganizationalObjectType): ) class RoleType(OrganizationalObjectType): - prefixes: List[Annotated["PrefixType", strawberry.lazy('ipam.graphql.types')]] - ip_ranges: List[Annotated["IPRangeType", strawberry.lazy('ipam.graphql.types')]] - vlans: List[Annotated["VLANType", strawberry.lazy('ipam.graphql.types')]] + prefixes: list[Annotated["PrefixType", strawberry.lazy('ipam.graphql.types')]] + ip_ranges: list[Annotated["IPRangeType", strawberry.lazy('ipam.graphql.types')]] + vlans: list[Annotated["VLANType", strawberry.lazy('ipam.graphql.types')]] @strawberry_django.type( @@ -233,10 +235,10 @@ class RoleType(OrganizationalObjectType): class RouteTargetType(PrimaryObjectType): tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None - importing_l2vpns: List[Annotated["L2VPNType", strawberry.lazy('vpn.graphql.types')]] - exporting_l2vpns: List[Annotated["L2VPNType", strawberry.lazy('vpn.graphql.types')]] - importing_vrfs: List[Annotated["VRFType", strawberry.lazy('ipam.graphql.types')]] - exporting_vrfs: List[Annotated["VRFType", strawberry.lazy('ipam.graphql.types')]] + importing_l2vpns: list[Annotated["L2VPNType", strawberry.lazy('vpn.graphql.types')]] + exporting_l2vpns: list[Annotated["L2VPNType", strawberry.lazy('vpn.graphql.types')]] + importing_vrfs: list[Annotated["VRFType", strawberry.lazy('ipam.graphql.types')]] + exporting_vrfs: list[Annotated["VRFType", strawberry.lazy('ipam.graphql.types')]] @strawberry_django.type( @@ -246,15 +248,16 @@ class RouteTargetType(PrimaryObjectType): pagination=True ) class ServiceType(ContactsMixin, PrimaryObjectType): - ports: List[int] - ipaddresses: List[Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')]] + ports: list[int] + ipaddresses: list[Annotated['IPAddressType', strawberry.lazy('ipam.graphql.types')]] @strawberry_django.field - def parent(self) -> Annotated[Union[ - Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')], - Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')], - Annotated["FHRPGroupType", strawberry.lazy('ipam.graphql.types')], - ], strawberry.union("ServiceParentType")] | None: + def parent(self) -> Annotated[ + Annotated['DeviceType', strawberry.lazy('dcim.graphql.types')] + | Annotated['VirtualMachineType', strawberry.lazy('virtualization.graphql.types')] + | Annotated['FHRPGroupType', strawberry.lazy('ipam.graphql.types')], + strawberry.union('ServiceParentType'), + ] | None: return self.parent @@ -265,7 +268,7 @@ class ServiceType(ContactsMixin, PrimaryObjectType): pagination=True ) class ServiceTemplateType(PrimaryObjectType): - ports: List[int] + ports: list[int] @strawberry_django.type( @@ -280,12 +283,12 @@ class VLANType(PrimaryObjectType): tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None role: Annotated["RoleType", strawberry.lazy('ipam.graphql.types')] | None - interfaces_as_untagged: List[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] - vminterfaces_as_untagged: List[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]] - wirelesslan_set: List[Annotated["WirelessLANType", strawberry.lazy('wireless.graphql.types')]] - prefixes: List[Annotated["PrefixType", strawberry.lazy('ipam.graphql.types')]] - interfaces_as_tagged: List[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] - vminterfaces_as_tagged: List[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]] + interfaces_as_untagged: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] + vminterfaces_as_untagged: list[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]] + wirelesslan_set: list[Annotated["WirelessLANType", strawberry.lazy('wireless.graphql.types')]] + prefixes: list[Annotated["PrefixType", strawberry.lazy('ipam.graphql.types')]] + interfaces_as_tagged: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] + vminterfaces_as_tagged: list[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]] @strawberry_django.field def qinq_svlan(self) -> Annotated["VLANType", strawberry.lazy('ipam.graphql.types')] | None: @@ -300,20 +303,21 @@ class VLANType(PrimaryObjectType): ) class VLANGroupType(OrganizationalObjectType): - vlans: List[VLANType] - vid_ranges: List[str] - tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None + vlans: list[VLANType] + vid_ranges: list[str] + tenant: Annotated['TenantType', strawberry.lazy('tenancy.graphql.types')] | None @strawberry_django.field - def scope(self) -> Annotated[Union[ - Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')], - Annotated["ClusterGroupType", strawberry.lazy('virtualization.graphql.types')], - Annotated["LocationType", strawberry.lazy('dcim.graphql.types')], - Annotated["RackType", strawberry.lazy('dcim.graphql.types')], - Annotated["RegionType", strawberry.lazy('dcim.graphql.types')], - Annotated["SiteType", strawberry.lazy('dcim.graphql.types')], - Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')], - ], strawberry.union("VLANGroupScopeType")] | None: + def scope(self) -> Annotated[ + Annotated['ClusterType', strawberry.lazy('virtualization.graphql.types')] + | Annotated['ClusterGroupType', strawberry.lazy('virtualization.graphql.types')] + | Annotated['LocationType', strawberry.lazy('dcim.graphql.types')] + | Annotated['RackType', strawberry.lazy('dcim.graphql.types')] + | Annotated['RegionType', strawberry.lazy('dcim.graphql.types')] + | Annotated['SiteType', strawberry.lazy('dcim.graphql.types')] + | Annotated['SiteGroupType', strawberry.lazy('dcim.graphql.types')], + strawberry.union('VLANGroupScopeType'), + ] | None: return self.scope @@ -324,7 +328,7 @@ class VLANGroupType(OrganizationalObjectType): pagination=True ) class VLANTranslationPolicyType(PrimaryObjectType): - rules: List[Annotated["VLANTranslationRuleType", strawberry.lazy('ipam.graphql.types')]] + rules: list[Annotated["VLANTranslationRuleType", strawberry.lazy('ipam.graphql.types')]] @strawberry_django.type( @@ -349,10 +353,10 @@ class VLANTranslationRuleType(NetBoxObjectType): class VRFType(PrimaryObjectType): tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None - interfaces: List[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] - ip_addresses: List[Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')]] - vminterfaces: List[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]] - ip_ranges: List[Annotated["IPRangeType", strawberry.lazy('ipam.graphql.types')]] - export_targets: List[Annotated["RouteTargetType", strawberry.lazy('ipam.graphql.types')]] - import_targets: List[Annotated["RouteTargetType", strawberry.lazy('ipam.graphql.types')]] - prefixes: List[Annotated["PrefixType", strawberry.lazy('ipam.graphql.types')]] + interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] + ip_addresses: list[Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')]] + vminterfaces: list[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]] + ip_ranges: list[Annotated["IPRangeType", strawberry.lazy('ipam.graphql.types')]] + export_targets: list[Annotated["RouteTargetType", strawberry.lazy('ipam.graphql.types')]] + import_targets: list[Annotated["RouteTargetType", strawberry.lazy('ipam.graphql.types')]] + prefixes: list[Annotated["PrefixType", strawberry.lazy('ipam.graphql.types')]] diff --git a/netbox/ipam/lookups.py b/netbox/ipam/lookups.py index 045877eb3..45f6fd82f 100644 --- a/netbox/ipam/lookups.py +++ b/netbox/ipam/lookups.py @@ -1,19 +1,19 @@ from django.db.models import IntegerField, Lookup, Transform, lookups -class NetFieldDecoratorMixin(object): +class NetFieldDecoratorMixin: def process_lhs(self, qn, connection, lhs=None): lhs = lhs or self.lhs lhs_string, lhs_params = qn.compile(lhs) - lhs_string = 'TEXT(%s)' % lhs_string + lhs_string = f'TEXT({lhs_string})' return lhs_string, lhs_params class IExact(NetFieldDecoratorMixin, lookups.IExact): def get_rhs_op(self, connection, rhs): - return '= LOWER(%s)' % rhs + return f'= LOWER({rhs})' class EndsWith(NetFieldDecoratorMixin, lookups.EndsWith): @@ -24,7 +24,7 @@ class IEndsWith(NetFieldDecoratorMixin, lookups.IEndsWith): pass def get_rhs_op(self, connection, rhs): - return 'LIKE LOWER(%s)' % rhs + return f'LIKE LOWER({rhs})' class StartsWith(NetFieldDecoratorMixin, lookups.StartsWith): @@ -35,7 +35,7 @@ class IStartsWith(NetFieldDecoratorMixin, lookups.IStartsWith): pass def get_rhs_op(self, connection, rhs): - return 'LIKE LOWER(%s)' % rhs + return f'LIKE LOWER({rhs})' class Regex(NetFieldDecoratorMixin, lookups.Regex): @@ -53,7 +53,7 @@ class NetContainsOrEquals(Lookup): lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params - return '%s >>= %s' % (lhs, rhs), params + return f'{lhs} >>= {rhs}', params class NetContains(Lookup): @@ -63,7 +63,7 @@ class NetContains(Lookup): lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params - return '%s >> %s' % (lhs, rhs), params + return f'{lhs} >> {rhs}', params class NetContained(Lookup): @@ -73,7 +73,7 @@ class NetContained(Lookup): lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params - return '%s << %s' % (lhs, rhs), params + return f'{lhs} << {rhs}', params class NetContainedOrEqual(Lookup): @@ -83,7 +83,7 @@ class NetContainedOrEqual(Lookup): lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params - return '%s <<= %s' % (lhs, rhs), params + return f'{lhs} <<= {rhs}', params class NetHost(Lookup): @@ -97,7 +97,7 @@ class NetHost(Lookup): if rhs_params: rhs_params[0] = rhs_params[0].split('/')[0] params = lhs_params + rhs_params - return 'HOST(%s) = %s' % (lhs, rhs), params + return f'HOST({lhs}) = {rhs}', params class NetIn(Lookup): @@ -151,7 +151,7 @@ class NetHostContained(Lookup): lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params - return 'CAST(HOST(%s) AS INET) <<= %s' % (lhs, rhs), params + return f'CAST(HOST({lhs}) AS INET) <<= {rhs}', params class NetFamily(Transform): diff --git a/netbox/netbox/graphql/filter_lookups.py b/netbox/netbox/graphql/filter_lookups.py index 953de2382..bbbccc312 100644 --- a/netbox/netbox/graphql/filter_lookups.py +++ b/netbox/netbox/graphql/filter_lookups.py @@ -1,5 +1,5 @@ from enum import Enum -from typing import Generic, Tuple, TypeVar +from typing import Generic, TypeVar import strawberry import strawberry_django @@ -72,7 +72,7 @@ class IntegerLookup: return None @strawberry_django.filter_field - def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> Tuple[QuerySet, Q]: + def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> tuple[QuerySet, Q]: filters = self.get_filter() if not filters: @@ -95,7 +95,7 @@ class BigIntegerLookup: return None @strawberry_django.filter_field - def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> Tuple[QuerySet, Q]: + def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> tuple[QuerySet, Q]: filters = self.get_filter() if not filters: @@ -118,7 +118,7 @@ class FloatLookup: return None @strawberry_django.filter_field - def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> Tuple[QuerySet, Q]: + def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> tuple[QuerySet, Q]: filters = self.get_filter() if not filters: @@ -137,7 +137,7 @@ class JSONFilter: lookup: JSONLookup @strawberry_django.filter_field - def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> Tuple[QuerySet, Q]: + def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> tuple[QuerySet, Q]: filters = self.lookup.get_filter() if not filters: @@ -164,7 +164,7 @@ class TreeNodeFilter: match_type: TreeNodeMatch @strawberry_django.filter_field - def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> Tuple[QuerySet, Q]: + def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> tuple[QuerySet, Q]: model_field_name = prefix.removesuffix('__').removesuffix('_id') model_field = None try: @@ -257,7 +257,7 @@ class RangeArrayValueLookup(Generic[T]): ) @strawberry_django.filter_field - def filter(self, info: Info, queryset: QuerySet, prefix: str = '') -> Tuple[QuerySet, Q]: + def filter(self, info: Info, queryset: QuerySet, prefix: str = '') -> tuple[QuerySet, Q]: """ Map GraphQL: { : { contains: } } To Django ORM: __range_contains= """ diff --git a/netbox/netbox/models/deletion.py b/netbox/netbox/models/deletion.py index 911bc2007..e106fbc10 100644 --- a/netbox/netbox/models/deletion.py +++ b/netbox/netbox/models/deletion.py @@ -70,9 +70,9 @@ class DeleteMixin: Override delete to use our custom collector. """ using = using or router.db_for_write(self.__class__, instance=self) - assert self._get_pk_val() is not None, "%s object can't be deleted because its %s attribute is set to None." % ( - self._meta.object_name, - self._meta.pk.attname, + assert self._get_pk_val() is not None, ( + f"{self._meta.object_name} object can't be deleted because its " + f"{self._meta.pk.attname} attribute is set to None." ) collector = CustomCollector(using=using) diff --git a/netbox/netbox/navigation/__init__.py b/netbox/netbox/navigation/__init__.py index 83792d06e..41d70fd9a 100644 --- a/netbox/netbox/navigation/__init__.py +++ b/netbox/netbox/navigation/__init__.py @@ -1,5 +1,5 @@ +from collections.abc import Sequence from dataclasses import dataclass -from typing import Optional, Sequence from django.urls import reverse_lazy @@ -23,9 +23,9 @@ class MenuItemButton: link: str title: str icon_class: str - _url: Optional[str] = None - permissions: Optional[Sequence[str]] = () - color: Optional[str] = None + _url: str | None = None + permissions: Sequence[str] | None = () + color: str | None = None def __post_init__(self): if self.link: @@ -45,11 +45,11 @@ class MenuItem: link: str link_text: str - _url: Optional[str] = None - permissions: Optional[Sequence[str]] = () - auth_required: Optional[bool] = False - staff_only: Optional[bool] = False - buttons: Optional[Sequence[MenuItemButton]] = () + _url: str | None = None + permissions: Sequence[str] | None = () + auth_required: bool | None = False + staff_only: bool | None = False + buttons: Sequence[MenuItemButton] | None = () def __post_init__(self): if self.link: diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index d0e413091..90c9f8334 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -33,8 +33,8 @@ VERSION = RELEASE.full_version # Retained for backward compatibility # Set the base directory two levels up BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -# Validate Python version -if sys.version_info < (3, 12): +# Validate the Python version +if sys.version_info < (3, 12): # noqa: UP036 raise RuntimeError( f"NetBox requires Python 3.12 or later. (Currently installed: Python {platform.python_version()})" ) diff --git a/netbox/netbox/tables/columns.py b/netbox/netbox/tables/columns.py index 0d376de31..c1424acd1 100644 --- a/netbox/netbox/tables/columns.py +++ b/netbox/netbox/tables/columns.py @@ -1,6 +1,5 @@ import zoneinfo from dataclasses import dataclass -from typing import Optional from urllib.parse import quote import django_tables2 as tables @@ -229,8 +228,8 @@ class BooleanColumn(tables.Column): class ActionsItem: title: str icon: str - permission: Optional[str] = None - css_class: Optional[str] = 'secondary' + permission: str | None = None + css_class: str | None = 'secondary' class ActionsColumn(tables.Column): diff --git a/netbox/netbox/tests/dummy_plugin/graphql.py b/netbox/netbox/tests/dummy_plugin/graphql.py index ca378066f..7f7d606fd 100644 --- a/netbox/netbox/tests/dummy_plugin/graphql.py +++ b/netbox/netbox/tests/dummy_plugin/graphql.py @@ -1,4 +1,3 @@ -from typing import List import strawberry import strawberry_django @@ -17,7 +16,7 @@ class DummyModelType: @strawberry.type(name="Query") class DummyQuery: dummymodel: DummyModelType = strawberry_django.field() - dummymodel_list: List[DummyModelType] = strawberry_django.field() + dummymodel_list: list[DummyModelType] = strawberry_django.field() schema = [ diff --git a/netbox/netbox/tests/test_authentication.py b/netbox/netbox/tests/test_authentication.py index 5ed335dbf..55298cb2f 100644 --- a/netbox/netbox/tests/test_authentication.py +++ b/netbox/netbox/tests/test_authentication.py @@ -97,7 +97,7 @@ class TokenAuthenticationTestCase(APITestCase): url = reverse('dcim-api:site-list') # Create v1 & v2 tokens - future = datetime.datetime(2100, 1, 1, tzinfo=datetime.timezone.utc) + future = datetime.datetime(2100, 1, 1, tzinfo=datetime.UTC) token1 = Token.objects.create(version=1, user=self.user, expires=future) token2 = Token.objects.create(version=2, user=self.user, expires=future) @@ -108,7 +108,7 @@ class TokenAuthenticationTestCase(APITestCase): self.assertEqual(response.status_code, 200) # Request with an expired token should fail - past = datetime.datetime(2020, 1, 1, tzinfo=datetime.timezone.utc) + past = datetime.datetime(2020, 1, 1, tzinfo=datetime.UTC) token1.expires = past token1.save() token2.expires = past diff --git a/netbox/tenancy/graphql/mixins.py b/netbox/tenancy/graphql/mixins.py index 9437a06f2..d81e806d2 100644 --- a/netbox/tenancy/graphql/mixins.py +++ b/netbox/tenancy/graphql/mixins.py @@ -1,4 +1,4 @@ -from typing import Annotated, List +from typing import Annotated import strawberry @@ -9,4 +9,4 @@ __all__ = ( @strawberry.type class ContactAssignmentsMixin: - assignments: List[Annotated["ContactAssignmentType", strawberry.lazy('tenancy.graphql.types')]] # noqa: F821 + assignments: list[Annotated["ContactAssignmentType", strawberry.lazy('tenancy.graphql.types')]] # noqa: F821 diff --git a/netbox/tenancy/graphql/schema.py b/netbox/tenancy/graphql/schema.py index 857d8ddeb..cf3fa1def 100644 --- a/netbox/tenancy/graphql/schema.py +++ b/netbox/tenancy/graphql/schema.py @@ -1,5 +1,3 @@ -from typing import List - import strawberry import strawberry_django @@ -9,19 +7,19 @@ from .types import * @strawberry.type(name="Query") class TenancyQuery: tenant: TenantType = strawberry_django.field() - tenant_list: List[TenantType] = strawberry_django.field() + tenant_list: list[TenantType] = strawberry_django.field() tenant_group: TenantGroupType = strawberry_django.field() - tenant_group_list: List[TenantGroupType] = strawberry_django.field() + tenant_group_list: list[TenantGroupType] = strawberry_django.field() contact: ContactType = strawberry_django.field() - contact_list: List[ContactType] = strawberry_django.field() + contact_list: list[ContactType] = strawberry_django.field() contact_role: ContactRoleType = strawberry_django.field() - contact_role_list: List[ContactRoleType] = strawberry_django.field() + contact_role_list: list[ContactRoleType] = strawberry_django.field() contact_group: ContactGroupType = strawberry_django.field() - contact_group_list: List[ContactGroupType] = strawberry_django.field() + contact_group_list: list[ContactGroupType] = strawberry_django.field() contact_assignment: ContactAssignmentType = strawberry_django.field() - contact_assignment_list: List[ContactAssignmentType] = strawberry_django.field() + contact_assignment_list: list[ContactAssignmentType] = strawberry_django.field() diff --git a/netbox/tenancy/graphql/types.py b/netbox/tenancy/graphql/types.py index 4929c7b12..2c7143f5a 100644 --- a/netbox/tenancy/graphql/types.py +++ b/netbox/tenancy/graphql/types.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Annotated, List +from typing import TYPE_CHECKING, Annotated import strawberry import strawberry_django @@ -60,30 +60,30 @@ __all__ = ( ) class TenantType(ContactsMixin, PrimaryObjectType): group: Annotated['TenantGroupType', strawberry.lazy('tenancy.graphql.types')] | None - asns: List[Annotated['ASNType', strawberry.lazy('ipam.graphql.types')]] - circuits: List[Annotated['CircuitType', strawberry.lazy('circuits.graphql.types')]] - sites: List[Annotated['SiteType', strawberry.lazy('dcim.graphql.types')]] - vlans: List[Annotated['VLANType', strawberry.lazy('ipam.graphql.types')]] - wireless_lans: List[Annotated['WirelessLANType', strawberry.lazy('wireless.graphql.types')]] - route_targets: List[Annotated['RouteTargetType', strawberry.lazy('ipam.graphql.types')]] - locations: List[Annotated['LocationType', strawberry.lazy('dcim.graphql.types')]] - ip_ranges: List[Annotated['IPRangeType', strawberry.lazy('ipam.graphql.types')]] - rackreservations: List[Annotated['RackReservationType', strawberry.lazy('dcim.graphql.types')]] - racks: List[Annotated['RackType', strawberry.lazy('dcim.graphql.types')]] - vdcs: List[Annotated['VirtualDeviceContextType', strawberry.lazy('dcim.graphql.types')]] - prefixes: List[Annotated['PrefixType', strawberry.lazy('ipam.graphql.types')]] - cables: List[Annotated['CableType', strawberry.lazy('dcim.graphql.types')]] - virtual_machines: List[Annotated['VirtualMachineType', strawberry.lazy('virtualization.graphql.types')]] - vrfs: List[Annotated['VRFType', strawberry.lazy('ipam.graphql.types')]] - asn_ranges: List[Annotated['ASNRangeType', strawberry.lazy('ipam.graphql.types')]] - wireless_links: List[Annotated['WirelessLinkType', strawberry.lazy('wireless.graphql.types')]] - aggregates: List[Annotated['AggregateType', strawberry.lazy('ipam.graphql.types')]] - power_feeds: List[Annotated['PowerFeedType', strawberry.lazy('dcim.graphql.types')]] - devices: List[Annotated['DeviceType', strawberry.lazy('dcim.graphql.types')]] - tunnels: List[Annotated['TunnelType', strawberry.lazy('vpn.graphql.types')]] - ip_addresses: List[Annotated['IPAddressType', strawberry.lazy('ipam.graphql.types')]] - clusters: List[Annotated['ClusterType', strawberry.lazy('virtualization.graphql.types')]] - l2vpns: List[Annotated['L2VPNType', strawberry.lazy('vpn.graphql.types')]] + asns: list[Annotated['ASNType', strawberry.lazy('ipam.graphql.types')]] + circuits: list[Annotated['CircuitType', strawberry.lazy('circuits.graphql.types')]] + sites: list[Annotated['SiteType', strawberry.lazy('dcim.graphql.types')]] + vlans: list[Annotated['VLANType', strawberry.lazy('ipam.graphql.types')]] + wireless_lans: list[Annotated['WirelessLANType', strawberry.lazy('wireless.graphql.types')]] + route_targets: list[Annotated['RouteTargetType', strawberry.lazy('ipam.graphql.types')]] + locations: list[Annotated['LocationType', strawberry.lazy('dcim.graphql.types')]] + ip_ranges: list[Annotated['IPRangeType', strawberry.lazy('ipam.graphql.types')]] + rackreservations: list[Annotated['RackReservationType', strawberry.lazy('dcim.graphql.types')]] + racks: list[Annotated['RackType', strawberry.lazy('dcim.graphql.types')]] + vdcs: list[Annotated['VirtualDeviceContextType', strawberry.lazy('dcim.graphql.types')]] + prefixes: list[Annotated['PrefixType', strawberry.lazy('ipam.graphql.types')]] + cables: list[Annotated['CableType', strawberry.lazy('dcim.graphql.types')]] + virtual_machines: list[Annotated['VirtualMachineType', strawberry.lazy('virtualization.graphql.types')]] + vrfs: list[Annotated['VRFType', strawberry.lazy('ipam.graphql.types')]] + asn_ranges: list[Annotated['ASNRangeType', strawberry.lazy('ipam.graphql.types')]] + wireless_links: list[Annotated['WirelessLinkType', strawberry.lazy('wireless.graphql.types')]] + aggregates: list[Annotated['AggregateType', strawberry.lazy('ipam.graphql.types')]] + power_feeds: list[Annotated['PowerFeedType', strawberry.lazy('dcim.graphql.types')]] + devices: list[Annotated['DeviceType', strawberry.lazy('dcim.graphql.types')]] + tunnels: list[Annotated['TunnelType', strawberry.lazy('vpn.graphql.types')]] + ip_addresses: list[Annotated['IPAddressType', strawberry.lazy('ipam.graphql.types')]] + clusters: list[Annotated['ClusterType', strawberry.lazy('virtualization.graphql.types')]] + l2vpns: list[Annotated['L2VPNType', strawberry.lazy('vpn.graphql.types')]] @strawberry_django.type( @@ -95,8 +95,8 @@ class TenantType(ContactsMixin, PrimaryObjectType): class TenantGroupType(NestedGroupObjectType): parent: Annotated['TenantGroupType', strawberry.lazy('tenancy.graphql.types')] | None - tenants: List[TenantType] - children: List[Annotated['TenantGroupType', strawberry.lazy('tenancy.graphql.types')]] + tenants: list[TenantType] + children: list[Annotated['TenantGroupType', strawberry.lazy('tenancy.graphql.types')]] # @@ -110,7 +110,7 @@ class TenantGroupType(NestedGroupObjectType): pagination=True ) class ContactType(ContactAssignmentsMixin, PrimaryObjectType): - groups: List[Annotated['ContactGroupType', strawberry.lazy('tenancy.graphql.types')]] + groups: list[Annotated['ContactGroupType', strawberry.lazy('tenancy.graphql.types')]] @strawberry_django.type( @@ -132,8 +132,8 @@ class ContactRoleType(ContactAssignmentsMixin, OrganizationalObjectType): class ContactGroupType(NestedGroupObjectType): parent: Annotated['ContactGroupType', strawberry.lazy('tenancy.graphql.types')] | None - contacts: List[ContactType] - children: List[Annotated['ContactGroupType', strawberry.lazy('tenancy.graphql.types')]] + contacts: list[ContactType] + children: list[Annotated['ContactGroupType', strawberry.lazy('tenancy.graphql.types')]] @strawberry_django.type( diff --git a/netbox/users/graphql/schema.py b/netbox/users/graphql/schema.py index 5b6341d54..47d4f18d7 100644 --- a/netbox/users/graphql/schema.py +++ b/netbox/users/graphql/schema.py @@ -1,5 +1,3 @@ -from typing import List - import strawberry import strawberry_django @@ -9,13 +7,13 @@ from .types import * @strawberry.type(name="Query") class UsersQuery: group: GroupType = strawberry_django.field() - group_list: List[GroupType] = strawberry_django.field() + group_list: list[GroupType] = strawberry_django.field() user: UserType = strawberry_django.field() - user_list: List[UserType] = strawberry_django.field() + user_list: list[UserType] = strawberry_django.field() owner_group: OwnerGroupType = strawberry_django.field() - owner_group_list: List[OwnerGroupType] = strawberry_django.field() + owner_group_list: list[OwnerGroupType] = strawberry_django.field() owner: OwnerType = strawberry_django.field() - owner_list: List[OwnerType] = strawberry_django.field() + owner_list: list[OwnerType] = strawberry_django.field() diff --git a/netbox/users/graphql/types.py b/netbox/users/graphql/types.py index d01d549fa..57d4839a2 100644 --- a/netbox/users/graphql/types.py +++ b/netbox/users/graphql/types.py @@ -1,4 +1,3 @@ -from typing import List import strawberry_django @@ -34,7 +33,7 @@ class GroupType(BaseObjectType): pagination=True ) class UserType(BaseObjectType): - groups: List[GroupType] + groups: list[GroupType] @strawberry_django.type( diff --git a/netbox/users/models/users.py b/netbox/users/models/users.py index 8ed165c5a..48081dafb 100644 --- a/netbox/users/models/users.py +++ b/netbox/users/models/users.py @@ -189,7 +189,7 @@ class User(AbstractBaseUser, PermissionsMixin): """ Return the first_name plus the last_name, with a space in between. """ - full_name = "%s %s" % (self.first_name, self.last_name) + full_name = f"{self.first_name} {self.last_name}" return full_name.strip() def get_short_name(self): diff --git a/netbox/utilities/forms/widgets/apiselect.py b/netbox/utilities/forms/widgets/apiselect.py index 7e9122922..d10c62c41 100644 --- a/netbox/utilities/forms/widgets/apiselect.py +++ b/netbox/utilities/forms/widgets/apiselect.py @@ -1,5 +1,4 @@ import json -from typing import Dict, List, Tuple from django import forms from django.conf import settings @@ -19,8 +18,8 @@ class APISelect(forms.Select): """ template_name = 'widgets/apiselect.html' option_template_name = 'widgets/select_option.html' - dynamic_params: Dict[str, str] - static_params: Dict[str, List[str]] + dynamic_params: dict[str, str] + static_params: dict[str, list[str]] def get_context(self, name, value, attrs): context = super().get_context(name, value, attrs) @@ -35,8 +34,8 @@ class APISelect(forms.Select): super().__init__(*args, **kwargs) self.attrs['class'] = 'api-select' - self.dynamic_params: Dict[str, List[str]] = {} - self.static_params: Dict[str, List[str]] = {} + self.dynamic_params: dict[str, list[str]] = {} + self.static_params: dict[str, list[str]] = {} if api_url: self.attrs['data-url'] = '/{}{}'.format(settings.BASE_PATH, api_url.lstrip('/')) # Inject BASE_PATH @@ -96,7 +95,7 @@ class APISelect(forms.Select): Process an entire query_params dictionary, and handle primitive or list values. """ for key, value in query_params.items(): - if isinstance(value, (List, Tuple)): + if isinstance(value, (list, tuple)): # If value is a list/tuple, iterate through each item. for item in value: self._process_query_param(key, item) diff --git a/netbox/utilities/release.py b/netbox/utilities/release.py index 78dbe25d1..ab9736b8b 100644 --- a/netbox/utilities/release.py +++ b/netbox/utilities/release.py @@ -1,7 +1,6 @@ import datetime import os from dataclasses import asdict, dataclass, field -from typing import Union import yaml from django.core.exceptions import ImproperlyConfigured @@ -28,9 +27,9 @@ class FeatureSet: class ReleaseInfo: version: str edition: str - published: Union[datetime.date, None] = None - designation: Union[str, None] = None - build: Union[str, None] = None + published: datetime.date | None = None + designation: str | None = None + build: str | None = None features: FeatureSet = field(default_factory=FeatureSet) @property @@ -57,12 +56,12 @@ def load_release_data(): base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Load canonical release attributes - with open(os.path.join(base_path, RELEASE_PATH), 'r') as release_file: + with open(os.path.join(base_path, RELEASE_PATH)) as release_file: data = yaml.safe_load(release_file) # Overlay any local release date (if defined) try: - with open(os.path.join(base_path, LOCAL_RELEASE_PATH), 'r') as release_file: + with open(os.path.join(base_path, LOCAL_RELEASE_PATH)) as release_file: local_data = yaml.safe_load(release_file) except FileNotFoundError: local_data = {} diff --git a/netbox/utilities/templatetags/helpers.py b/netbox/utilities/templatetags/helpers.py index 5613085ed..0a77b9cab 100644 --- a/netbox/utilities/templatetags/helpers.py +++ b/netbox/utilities/templatetags/helpers.py @@ -1,5 +1,5 @@ import json -from typing import Any, Dict +from typing import Any from urllib.parse import quote from django import template @@ -306,7 +306,7 @@ def startswith(text: str, starts: str) -> bool: @register.filter -def get_key(value: Dict, arg: str) -> Any: +def get_key(value: dict, arg: str) -> Any: """ Template implementation of `dict.get()`, for accessing dict values by key when the key is not able to be used in a template. For diff --git a/netbox/utilities/testing/filtersets.py b/netbox/utilities/testing/filtersets.py index 5348fbb07..bb200a43e 100644 --- a/netbox/utilities/testing/filtersets.py +++ b/netbox/utilities/testing/filtersets.py @@ -1,4 +1,4 @@ -from datetime import datetime, timezone +from datetime import UTC, datetime from itertools import chain import django_filters @@ -156,12 +156,12 @@ class ChangeLoggedFilterSetTests(BaseFilterSetTests): def test_created(self): pk_list = self.queryset.values_list('pk', flat=True)[:2] - self.queryset.filter(pk__in=pk_list).update(created=datetime(2021, 1, 1, 0, 0, 0, tzinfo=timezone.utc)) + self.queryset.filter(pk__in=pk_list).update(created=datetime(2021, 1, 1, 0, 0, 0, tzinfo=UTC)) params = {'created': ['2021-01-01T00:00:00']} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_last_updated(self): pk_list = self.queryset.values_list('pk', flat=True)[:2] - self.queryset.filter(pk__in=pk_list).update(last_updated=datetime(2021, 1, 2, 0, 0, 0, tzinfo=timezone.utc)) + self.queryset.filter(pk__in=pk_list).update(last_updated=datetime(2021, 1, 2, 0, 0, 0, tzinfo=UTC)) params = {'last_updated': ['2021-01-02T00:00:00']} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) diff --git a/netbox/utilities/views.py b/netbox/utilities/views.py index ef170da2f..dcf8ed696 100644 --- a/netbox/utilities/views.py +++ b/netbox/utilities/views.py @@ -1,5 +1,5 @@ +from collections.abc import Iterable from dataclasses import dataclass -from typing import Iterable from django.conf import settings from django.contrib.auth.mixins import AccessMixin diff --git a/netbox/virtualization/graphql/schema.py b/netbox/virtualization/graphql/schema.py index 212425814..f0dee3815 100644 --- a/netbox/virtualization/graphql/schema.py +++ b/netbox/virtualization/graphql/schema.py @@ -1,5 +1,3 @@ -from typing import List - import strawberry import strawberry_django @@ -9,19 +7,19 @@ from .types import * @strawberry.type(name="Query") class VirtualizationQuery: cluster: ClusterType = strawberry_django.field() - cluster_list: List[ClusterType] = strawberry_django.field() + cluster_list: list[ClusterType] = strawberry_django.field() cluster_group: ClusterGroupType = strawberry_django.field() - cluster_group_list: List[ClusterGroupType] = strawberry_django.field() + cluster_group_list: list[ClusterGroupType] = strawberry_django.field() cluster_type: ClusterTypeType = strawberry_django.field() - cluster_type_list: List[ClusterTypeType] = strawberry_django.field() + cluster_type_list: list[ClusterTypeType] = strawberry_django.field() virtual_machine: VirtualMachineType = strawberry_django.field() - virtual_machine_list: List[VirtualMachineType] = strawberry_django.field() + virtual_machine_list: list[VirtualMachineType] = strawberry_django.field() vm_interface: VMInterfaceType = strawberry_django.field() - vm_interface_list: List[VMInterfaceType] = strawberry_django.field() + vm_interface_list: list[VMInterfaceType] = strawberry_django.field() virtual_disk: VirtualDiskType = strawberry_django.field() - virtual_disk_list: List[VirtualDiskType] = strawberry_django.field() + virtual_disk_list: list[VirtualDiskType] = strawberry_django.field() diff --git a/netbox/virtualization/graphql/types.py b/netbox/virtualization/graphql/types.py index 5928fd6a5..3142c5ed1 100644 --- a/netbox/virtualization/graphql/types.py +++ b/netbox/virtualization/graphql/types.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Annotated, List, Union +from typing import TYPE_CHECKING, Annotated import strawberry import strawberry_django @@ -55,16 +55,17 @@ class ClusterType(ContactsMixin, VLANGroupsMixin, PrimaryObjectType): type: Annotated["ClusterTypeType", strawberry.lazy('virtualization.graphql.types')] | None group: Annotated["ClusterGroupType", strawberry.lazy('virtualization.graphql.types')] | None tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None - virtual_machines: List[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]] - devices: List[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] + virtual_machines: list[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]] + devices: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.field - def scope(self) -> Annotated[Union[ - Annotated["LocationType", strawberry.lazy('dcim.graphql.types')], - Annotated["RegionType", strawberry.lazy('dcim.graphql.types')], - Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')], - Annotated["SiteType", strawberry.lazy('dcim.graphql.types')], - ], strawberry.union("ClusterScopeType")] | None: + def scope(self) -> Annotated[ + Annotated['LocationType', strawberry.lazy('dcim.graphql.types')] + | Annotated['RegionType', strawberry.lazy('dcim.graphql.types')] + | Annotated['SiteGroupType', strawberry.lazy('dcim.graphql.types')] + | Annotated['SiteType', strawberry.lazy('dcim.graphql.types')], + strawberry.union('ClusterScopeType'), + ] | None: return self.scope @@ -76,7 +77,7 @@ class ClusterType(ContactsMixin, VLANGroupsMixin, PrimaryObjectType): ) class ClusterGroupType(ContactsMixin, VLANGroupsMixin, OrganizationalObjectType): - clusters: List[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]] + clusters: list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]] @strawberry_django.type( @@ -87,7 +88,7 @@ class ClusterGroupType(ContactsMixin, VLANGroupsMixin, OrganizationalObjectType) ) class ClusterTypeType(OrganizationalObjectType): - clusters: List[ClusterType] + clusters: list[ClusterType] @strawberry_django.type( @@ -110,9 +111,9 @@ class VirtualMachineType(ConfigContextMixin, ContactsMixin, PrimaryObjectType): primary_ip4: Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')] | None primary_ip6: Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')] | None - interfaces: List[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]] - services: List[Annotated["ServiceType", strawberry.lazy('ipam.graphql.types')]] - virtualdisks: List[Annotated["VirtualDiskType", strawberry.lazy('virtualization.graphql.types')]] + interfaces: list[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]] + services: list[Annotated["ServiceType", strawberry.lazy('ipam.graphql.types')]] + virtualdisks: list[Annotated["VirtualDiskType", strawberry.lazy('virtualization.graphql.types')]] @strawberry_django.type( @@ -132,10 +133,10 @@ class VMInterfaceType(IPAddressesMixin, ComponentType): qinq_svlan: Annotated["VLANType", strawberry.lazy('ipam.graphql.types')] | None vlan_translation_policy: Annotated["VLANTranslationPolicyType", strawberry.lazy('ipam.graphql.types')] | None - tagged_vlans: List[Annotated["VLANType", strawberry.lazy('ipam.graphql.types')]] - bridge_interfaces: List[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]] - child_interfaces: List[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]] - mac_addresses: List[Annotated["MACAddressType", strawberry.lazy('dcim.graphql.types')]] + tagged_vlans: list[Annotated["VLANType", strawberry.lazy('ipam.graphql.types')]] + bridge_interfaces: list[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]] + child_interfaces: list[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]] + mac_addresses: list[Annotated["MACAddressType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.type( diff --git a/netbox/vpn/graphql/schema.py b/netbox/vpn/graphql/schema.py index 06ccc577d..6795eeed3 100644 --- a/netbox/vpn/graphql/schema.py +++ b/netbox/vpn/graphql/schema.py @@ -1,5 +1,3 @@ -from typing import List - import strawberry import strawberry_django @@ -9,31 +7,31 @@ from .types import * @strawberry.type(name="Query") class VPNQuery: ike_policy: IKEPolicyType = strawberry_django.field() - ike_policy_list: List[IKEPolicyType] = strawberry_django.field() + ike_policy_list: list[IKEPolicyType] = strawberry_django.field() ike_proposal: IKEProposalType = strawberry_django.field() - ike_proposal_list: List[IKEProposalType] = strawberry_django.field() + ike_proposal_list: list[IKEProposalType] = strawberry_django.field() ipsec_policy: IPSecPolicyType = strawberry_django.field() - ipsec_policy_list: List[IPSecPolicyType] = strawberry_django.field() + ipsec_policy_list: list[IPSecPolicyType] = strawberry_django.field() ipsec_profile: IPSecProfileType = strawberry_django.field() - ipsec_profile_list: List[IPSecProfileType] = strawberry_django.field() + ipsec_profile_list: list[IPSecProfileType] = strawberry_django.field() ipsec_proposal: IPSecProposalType = strawberry_django.field() - ipsec_proposal_list: List[IPSecProposalType] = strawberry_django.field() + ipsec_proposal_list: list[IPSecProposalType] = strawberry_django.field() l2vpn: L2VPNType = strawberry_django.field() - l2vpn_list: List[L2VPNType] = strawberry_django.field() + l2vpn_list: list[L2VPNType] = strawberry_django.field() l2vpn_termination: L2VPNTerminationType = strawberry_django.field() - l2vpn_termination_list: List[L2VPNTerminationType] = strawberry_django.field() + l2vpn_termination_list: list[L2VPNTerminationType] = strawberry_django.field() tunnel: TunnelType = strawberry_django.field() - tunnel_list: List[TunnelType] = strawberry_django.field() + tunnel_list: list[TunnelType] = strawberry_django.field() tunnel_group: TunnelGroupType = strawberry_django.field() - tunnel_group_list: List[TunnelGroupType] = strawberry_django.field() + tunnel_group_list: list[TunnelGroupType] = strawberry_django.field() tunnel_termination: TunnelTerminationType = strawberry_django.field() - tunnel_termination_list: List[TunnelTerminationType] = strawberry_django.field() + tunnel_termination_list: list[TunnelTerminationType] = strawberry_django.field() diff --git a/netbox/vpn/graphql/types.py b/netbox/vpn/graphql/types.py index 87b99d2a9..7959f9e52 100644 --- a/netbox/vpn/graphql/types.py +++ b/netbox/vpn/graphql/types.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Annotated, List, Union +from typing import TYPE_CHECKING, Annotated import strawberry import strawberry_django @@ -38,7 +38,7 @@ __all__ = ( ) class TunnelGroupType(ContactsMixin, OrganizationalObjectType): - tunnels: List[Annotated["TunnelType", strawberry.lazy('vpn.graphql.types')]] + tunnels: list[Annotated["TunnelType", strawberry.lazy('vpn.graphql.types')]] @strawberry_django.type( @@ -64,7 +64,7 @@ class TunnelType(ContactsMixin, PrimaryObjectType): ipsec_profile: Annotated["IPSecProfileType", strawberry.lazy('vpn.graphql.types')] | None tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None - terminations: List[Annotated["TunnelTerminationType", strawberry.lazy('vpn.graphql.types')]] + terminations: list[Annotated["TunnelTerminationType", strawberry.lazy('vpn.graphql.types')]] @strawberry_django.type( @@ -74,7 +74,7 @@ class TunnelType(ContactsMixin, PrimaryObjectType): pagination=True ) class IKEProposalType(PrimaryObjectType): - ike_policies: List[Annotated["IKEPolicyType", strawberry.lazy('vpn.graphql.types')]] + ike_policies: list[Annotated["IKEPolicyType", strawberry.lazy('vpn.graphql.types')]] @strawberry_django.type( @@ -84,8 +84,8 @@ class IKEProposalType(PrimaryObjectType): pagination=True ) class IKEPolicyType(PrimaryObjectType): - proposals: List[Annotated["IKEProposalType", strawberry.lazy('vpn.graphql.types')]] - ipsec_profiles: List[Annotated["IPSecProfileType", strawberry.lazy('vpn.graphql.types')]] + proposals: list[Annotated["IKEProposalType", strawberry.lazy('vpn.graphql.types')]] + ipsec_profiles: list[Annotated["IPSecProfileType", strawberry.lazy('vpn.graphql.types')]] @strawberry_django.type( @@ -95,7 +95,7 @@ class IKEPolicyType(PrimaryObjectType): pagination=True ) class IPSecProposalType(PrimaryObjectType): - ipsec_policies: List[Annotated["IPSecPolicyType", strawberry.lazy('vpn.graphql.types')]] + ipsec_policies: list[Annotated["IPSecPolicyType", strawberry.lazy('vpn.graphql.types')]] @strawberry_django.type( @@ -105,8 +105,8 @@ class IPSecProposalType(PrimaryObjectType): pagination=True ) class IPSecPolicyType(PrimaryObjectType): - proposals: List[Annotated["IPSecProposalType", strawberry.lazy('vpn.graphql.types')]] - ipsec_profiles: List[Annotated["IPSecProfileType", strawberry.lazy('vpn.graphql.types')]] + proposals: list[Annotated["IPSecProposalType", strawberry.lazy('vpn.graphql.types')]] + ipsec_profiles: list[Annotated["IPSecProfileType", strawberry.lazy('vpn.graphql.types')]] @strawberry_django.type( @@ -119,7 +119,7 @@ class IPSecProfileType(PrimaryObjectType): ike_policy: Annotated["IKEPolicyType", strawberry.lazy('vpn.graphql.types')] ipsec_policy: Annotated["IPSecPolicyType", strawberry.lazy('vpn.graphql.types')] - tunnels: List[Annotated["TunnelType", strawberry.lazy('vpn.graphql.types')]] + tunnels: list[Annotated["TunnelType", strawberry.lazy('vpn.graphql.types')]] @strawberry_django.type( @@ -131,9 +131,9 @@ class IPSecProfileType(PrimaryObjectType): class L2VPNType(ContactsMixin, PrimaryObjectType): tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None - export_targets: List[Annotated["RouteTargetType", strawberry.lazy('ipam.graphql.types')]] - terminations: List[Annotated["L2VPNTerminationType", strawberry.lazy('vpn.graphql.types')]] - import_targets: List[Annotated["RouteTargetType", strawberry.lazy('ipam.graphql.types')]] + export_targets: list[Annotated["RouteTargetType", strawberry.lazy('ipam.graphql.types')]] + terminations: list[Annotated["L2VPNTerminationType", strawberry.lazy('vpn.graphql.types')]] + import_targets: list[Annotated["RouteTargetType", strawberry.lazy('ipam.graphql.types')]] @strawberry_django.type( @@ -146,9 +146,10 @@ class L2VPNTerminationType(NetBoxObjectType): l2vpn: Annotated["L2VPNType", strawberry.lazy('vpn.graphql.types')] @strawberry_django.field - def assigned_object(self) -> Annotated[Union[ - Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')], - Annotated["VLANType", strawberry.lazy('ipam.graphql.types')], - Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')], - ], strawberry.union("L2VPNAssignmentType")]: + def assigned_object(self) -> Annotated[ + Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')] + | Annotated['VLANType', strawberry.lazy('ipam.graphql.types')] + | Annotated['VMInterfaceType', strawberry.lazy('virtualization.graphql.types')], + strawberry.union('L2VPNAssignmentType'), + ]: return self.assigned_object diff --git a/netbox/vpn/migrations/0005_rename_indexes.py b/netbox/vpn/migrations/0005_rename_indexes.py index f24106c1f..090ca20da 100644 --- a/netbox/vpn/migrations/0005_rename_indexes.py +++ b/netbox/vpn/migrations/0005_rename_indexes.py @@ -8,11 +8,11 @@ class Migration(migrations.Migration): operations = [ # Rename vpn_l2vpn constraints - migrations.RunSQL(( + migrations.RunSQL( 'ALTER TABLE vpn_l2vpn ' 'RENAME CONSTRAINT ipam_l2vpn_tenant_id_bb2564a6_fk_tenancy_tenant_id ' 'TO vpn_l2vpn_tenant_id_57ec8f92_fk_tenancy_tenant_id' - )), + ), # Rename ipam_l2vpn_* sequences migrations.RunSQL('ALTER TABLE ipam_l2vpn_export_targets_id_seq RENAME TO vpn_l2vpn_export_targets_id_seq'), migrations.RunSQL('ALTER TABLE ipam_l2vpn_id_seq RENAME TO vpn_l2vpn_id_seq'), @@ -28,29 +28,29 @@ class Migration(migrations.Migration): migrations.RunSQL('ALTER INDEX IF EXISTS ipam_l2vpn_slug_24008406_uniq RENAME TO vpn_l2vpn_slug_76b5a174_uniq'), migrations.RunSQL('ALTER INDEX IF EXISTS ipam_l2vpn_slug_key RENAME TO vpn_l2vpn_slug_key'), # Rename vpn_l2vpntermination constraints - migrations.RunSQL(( + migrations.RunSQL( 'ALTER TABLE vpn_l2vpntermination ' 'RENAME CONSTRAINT ipam_l2vpntermination_assigned_object_id_check ' 'TO vpn_l2vpntermination_assigned_object_id_check' - )), - migrations.RunSQL(( + ), + migrations.RunSQL( 'ALTER TABLE vpn_l2vpntermination ' 'RENAME CONSTRAINT ipam_l2vpnterminatio_assigned_object_type_3923c124_fk_django_co ' 'TO vpn_l2vpntermination_assigned_object_type_id_f063b865_fk_django_co' - )), - migrations.RunSQL(( + ), + migrations.RunSQL( 'ALTER TABLE vpn_l2vpntermination ' 'RENAME CONSTRAINT ipam_l2vpntermination_l2vpn_id_9e570aa1_fk_ipam_l2vpn_id ' 'TO vpn_l2vpntermination_l2vpn_id_f5367bbe_fk_vpn_l2vpn_id' - )), + ), # Rename ipam_l2vpn_termination_* sequences migrations.RunSQL('ALTER TABLE ipam_l2vpntermination_id_seq RENAME TO vpn_l2vpntermination_id_seq'), # Rename ipam_l2vpn_* indexes migrations.RunSQL('ALTER INDEX ipam_l2vpntermination_pkey RENAME TO vpn_l2vpntermination_pkey'), - migrations.RunSQL(( + migrations.RunSQL( 'ALTER INDEX ipam_l2vpntermination_assigned_object_type_id_3923c124 ' 'RENAME TO vpn_l2vpntermination_assigned_object_type_id_f063b865' - )), + ), migrations.RunSQL( 'ALTER INDEX ipam_l2vpntermination_l2vpn_id_9e570aa1 RENAME TO vpn_l2vpntermination_l2vpn_id_f5367bbe' ), diff --git a/netbox/wireless/graphql/schema.py b/netbox/wireless/graphql/schema.py index 4f176031f..640f44464 100644 --- a/netbox/wireless/graphql/schema.py +++ b/netbox/wireless/graphql/schema.py @@ -1,5 +1,3 @@ -from typing import List - import strawberry import strawberry_django @@ -9,10 +7,10 @@ from .types import * @strawberry.type(name="Query") class WirelessQuery: wireless_lan: WirelessLANType = strawberry_django.field() - wireless_lan_list: List[WirelessLANType] = strawberry_django.field() + wireless_lan_list: list[WirelessLANType] = strawberry_django.field() wireless_lan_group: WirelessLANGroupType = strawberry_django.field() - wireless_lan_group_list: List[WirelessLANGroupType] = strawberry_django.field() + wireless_lan_group_list: list[WirelessLANGroupType] = strawberry_django.field() wireless_link: WirelessLinkType = strawberry_django.field() - wireless_link_list: List[WirelessLinkType] = strawberry_django.field() + wireless_link_list: list[WirelessLinkType] = strawberry_django.field() diff --git a/netbox/wireless/graphql/types.py b/netbox/wireless/graphql/types.py index 5cdf813cf..f02ddf978 100644 --- a/netbox/wireless/graphql/types.py +++ b/netbox/wireless/graphql/types.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Annotated, List, Union +from typing import TYPE_CHECKING, Annotated import strawberry import strawberry_django @@ -29,8 +29,8 @@ __all__ = ( class WirelessLANGroupType(NestedGroupObjectType): parent: Annotated["WirelessLANGroupType", strawberry.lazy('wireless.graphql.types')] | None - wireless_lans: List[Annotated["WirelessLANType", strawberry.lazy('wireless.graphql.types')]] - children: List[Annotated["WirelessLANGroupType", strawberry.lazy('wireless.graphql.types')]] + wireless_lans: list[Annotated["WirelessLANType", strawberry.lazy('wireless.graphql.types')]] + children: list[Annotated["WirelessLANGroupType", strawberry.lazy('wireless.graphql.types')]] @strawberry_django.type( @@ -44,15 +44,16 @@ class WirelessLANType(PrimaryObjectType): vlan: Annotated["VLANType", strawberry.lazy('ipam.graphql.types')] | None tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None - interfaces: List[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] + interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]] @strawberry_django.field - def scope(self) -> Annotated[Union[ - Annotated["LocationType", strawberry.lazy('dcim.graphql.types')], - Annotated["RegionType", strawberry.lazy('dcim.graphql.types')], - Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')], - Annotated["SiteType", strawberry.lazy('dcim.graphql.types')], - ], strawberry.union("WirelessLANScopeType")] | None: + def scope(self) -> Annotated[ + Annotated['LocationType', strawberry.lazy('dcim.graphql.types')] + | Annotated['RegionType', strawberry.lazy('dcim.graphql.types')] + | Annotated['SiteGroupType', strawberry.lazy('dcim.graphql.types')] + | Annotated['SiteType', strawberry.lazy('dcim.graphql.types')], + strawberry.union('WirelessLANScopeType'), + ] | None: return self.scope diff --git a/ruff.toml b/ruff.toml index 4520fd198..5fbfd0090 100644 --- a/ruff.toml +++ b/ruff.toml @@ -37,7 +37,8 @@ extend-select = [ "E501", # pycodestyle: line too long (enforced with `line-length` above) "W", # pycodestyle warnings (various style warnings, often whitespace/newlines) "I", # import sorting (isort-equivalent) - "RET", # return semantics (flake8-return family) + "RET", # return semantics (flake8-return family: consistent/explicit returns; remove redundant else/assign before return) + "UP", # pyupgrade: modernize syntax for your target Python (e.g., f-strings, built-in generics, newer stdlib idioms) ] ignore = [ "F403", # pyflakes: `from ... import *` used; unable to detect undefined names @@ -66,6 +67,8 @@ known-first-party = [ [lint.per-file-ignores] "template_code.py" = ["E501"] +"netbox/netbox/graphql/filter_lookups.py" = ["UP046"] # Strawberry typing: keep `Generic[T]` for now +"netbox/netbox/graphql/scalars.py" = ["UP007"] # Strawberry scalar typing: `Union[...]` required [format] # Use single quotes for strings.