From 1dc94a156c24c02d0517d629183bd36df1ae72a5 Mon Sep 17 00:00:00 2001 From: Patrick Ogenstad Date: Tue, 14 Oct 2025 16:21:50 +0200 Subject: [PATCH] Switch ruff to target Python 3.12 --- backend/infrahub/auth.py | 4 +-- backend/infrahub/cli/db.py | 6 ++-- .../clean_duplicate_schema_fields.py | 4 +-- backend/infrahub/config.py | 28 ++++++++-------- backend/infrahub/constants/database.py | 10 +++--- backend/infrahub/core/diff/model/diff.py | 4 +-- backend/infrahub/core/graph/constraints.py | 4 +-- backend/infrahub/core/manager.py | 2 +- .../core/node/node_property_attribute.py | 4 +-- backend/infrahub/core/schema/__init__.py | 6 ++-- backend/infrahub/core/validators/enum.py | 4 +-- backend/infrahub/dependencies/interface.py | 4 +-- backend/infrahub/events/constants.py | 4 +-- backend/infrahub/graphql/analyzer.py | 8 ++--- .../graphql/mutations/relationship.py | 4 +-- backend/infrahub/patch/constants.py | 4 +-- backend/infrahub/telemetry/constants.py | 4 +-- backend/infrahub/trigger/models.py | 4 +-- backend/infrahub/utils.py | 2 +- backend/infrahub/validators/tasks.py | 2 +- models/infrastructure_edge.py | 4 +-- pyproject.toml | 33 ++++++++++--------- .../infrahub_testcontainers/models.py | 4 +-- tasks/shared.py | 6 ++-- 24 files changed, 80 insertions(+), 79 deletions(-) diff --git a/backend/infrahub/auth.py b/backend/infrahub/auth.py index 264ca64cc8..cc6147e91d 100644 --- a/backend/infrahub/auth.py +++ b/backend/infrahub/auth.py @@ -2,7 +2,7 @@ import uuid from datetime import UTC, datetime, timedelta -from enum import Enum +from enum import StrEnum from typing import TYPE_CHECKING, Any import bcrypt @@ -35,7 +35,7 @@ log = get_logger() -class AuthType(str, Enum): +class AuthType(StrEnum): NONE = "none" JWT = "jwt" API = "api" diff --git a/backend/infrahub/cli/db.py b/backend/infrahub/cli/db.py index 18e212a115..9c6cb0b3a6 100644 --- a/backend/infrahub/cli/db.py +++ b/backend/infrahub/cli/db.py @@ -6,7 +6,7 @@ from collections import defaultdict from csv import DictReader, DictWriter from datetime import UTC, datetime -from enum import Enum +from enum import StrEnum from pathlib import Path from typing import TYPE_CHECKING, Any, Sequence @@ -75,13 +75,13 @@ def get_timestamp_string() -> str: PERMISSIONS_AVAILABLE = ["read", "write", "admin"] -class ConstraintAction(str, Enum): +class ConstraintAction(StrEnum): SHOW = "show" ADD = "add" DROP = "drop" -class IndexAction(str, Enum): +class IndexAction(StrEnum): SHOW = "show" ADD = "add" DROP = "drop" diff --git a/backend/infrahub/cli/db_commands/clean_duplicate_schema_fields.py b/backend/infrahub/cli/db_commands/clean_duplicate_schema_fields.py index 4c8b88fed4..41e134aee5 100644 --- a/backend/infrahub/cli/db_commands/clean_duplicate_schema_fields.py +++ b/backend/infrahub/cli/db_commands/clean_duplicate_schema_fields.py @@ -1,5 +1,5 @@ from dataclasses import dataclass -from enum import Enum +from enum import StrEnum from typing import Any from rich import print as rprint @@ -11,7 +11,7 @@ from infrahub.database import InfrahubDatabase -class SchemaFieldType(str, Enum): +class SchemaFieldType(StrEnum): ATTRIBUTE = "attribute" RELATIONSHIP = "relationship" diff --git a/backend/infrahub/config.py b/backend/infrahub/config.py index a50a56e36d..cfa717c756 100644 --- a/backend/infrahub/config.py +++ b/backend/infrahub/config.py @@ -3,12 +3,12 @@ import os import ssl import sys +import tomllib from dataclasses import dataclass -from enum import Enum +from enum import StrEnum from pathlib import Path from typing import TYPE_CHECKING, Any -import tomllib from infrahub_sdk.utils import generate_uuid from pydantic import ( AliasChoices, @@ -48,28 +48,28 @@ def default_append_git_suffix_domains() -> list[str]: return ["github.com", "gitlab.com"] -class EnterpriseFeatures(str, Enum): +class EnterpriseFeatures(StrEnum): PROPOSED_CHANGE_REQUIRE_APPROVAL = "proposed_change_require_approval" REVOKE_PROPOSED_CHANGE_APPROVALS = "revoke_proposed_change_approvals" -class UserInfoMethod(str, Enum): +class UserInfoMethod(StrEnum): POST = "post" GET = "get" -class SSOProtocol(str, Enum): +class SSOProtocol(StrEnum): OAUTH2 = "oauth2" OIDC = "oidc" -class Oauth2Provider(str, Enum): +class Oauth2Provider(StrEnum): GOOGLE = "google" PROVIDER1 = "provider1" PROVIDER2 = "provider2" -class OIDCProvider(str, Enum): +class OIDCProvider(StrEnum): GOOGLE = "google" PROVIDER1 = "provider1" PROVIDER2 = "provider2" @@ -98,25 +98,25 @@ def token_path(self) -> str: return f"/api/{self.protocol.value}/{self.name}/token" -class StorageDriver(str, Enum): +class StorageDriver(StrEnum): FileSystemStorage = "local" InfrahubS3ObjectStorage = "s3" -class TraceExporterType(str, Enum): +class TraceExporterType(StrEnum): CONSOLE = "console" OTLP = "otlp" # JAEGER = "jaeger" # ZIPKIN = "zipkin" -class TraceTransportProtocol(str, Enum): +class TraceTransportProtocol(StrEnum): GRPC = "grpc" HTTP_PROTOBUF = "http/protobuf" # HTTP_JSON = "http/json" -class BrokerDriver(str, Enum): +class BrokerDriver(StrEnum): RabbitMQ = "rabbitmq" NATS = "nats" @@ -137,7 +137,7 @@ def driver_class_name(self) -> str: return "RabbitMQMessageBus" -class CacheDriver(str, Enum): +class CacheDriver(StrEnum): Redis = "redis" NATS = "nats" @@ -158,12 +158,12 @@ def driver_class_name(self) -> str: return "RedisCache" -class WorkflowDriver(str, Enum): +class WorkflowDriver(StrEnum): LOCAL = "local" WORKER = "worker" -class ExtraLogLevel(str, Enum): +class ExtraLogLevel(StrEnum): CRITICAL = "CRITICAL" ERROR = "ERROR" WARNING = "WARNING" diff --git a/backend/infrahub/constants/database.py b/backend/infrahub/constants/database.py index 42897163a0..2ee745db92 100644 --- a/backend/infrahub/constants/database.py +++ b/backend/infrahub/constants/database.py @@ -1,12 +1,12 @@ -from enum import Enum +from enum import StrEnum -class DatabaseType(str, Enum): +class DatabaseType(StrEnum): NEO4J = "neo4j" MEMGRAPH = "memgraph" -class Neo4jRuntime(str, Enum): +class Neo4jRuntime(StrEnum): DEFAULT = "default" INTERPRETED = "interpreted" SLOTTED = "slotted" @@ -15,13 +15,13 @@ class Neo4jRuntime(str, Enum): UNDEFINED = "undefined" -class IndexType(str, Enum): +class IndexType(StrEnum): TEXT = "text" RANGE = "range" LOOKUP = "lookup" NOT_APPLICABLE = "not_applicable" -class EntityType(str, Enum): +class EntityType(StrEnum): NODE = "node" RELATIONSHIP = "relationship" diff --git a/backend/infrahub/core/diff/model/diff.py b/backend/infrahub/core/diff/model/diff.py index 1b390fc5ae..d498a77a27 100644 --- a/backend/infrahub/core/diff/model/diff.py +++ b/backend/infrahub/core/diff/model/diff.py @@ -1,6 +1,6 @@ from __future__ import annotations -from enum import Enum +from enum import Enum, StrEnum from typing import Any from pydantic import BaseModel, ConfigDict, Field @@ -271,7 +271,7 @@ def label(self) -> str: return self.value -class DiffElementType(str, Enum): +class DiffElementType(StrEnum): ATTRIBUTE = "Attribute" RELATIONSHIP_ONE = "RelationshipOne" RELATIONSHIP_MANY = "RelationshipMany" diff --git a/backend/infrahub/core/graph/constraints.py b/backend/infrahub/core/graph/constraints.py index a704d79402..e14a6e4f30 100644 --- a/backend/infrahub/core/graph/constraints.py +++ b/backend/infrahub/core/graph/constraints.py @@ -1,6 +1,6 @@ from __future__ import annotations -from enum import Enum +from enum import StrEnum from typing import TYPE_CHECKING, ForwardRef, Optional, Union, get_origin from pydantic import BaseModel @@ -12,7 +12,7 @@ from infrahub.database import InfrahubDatabase -class GraphPropertyType(str, Enum): +class GraphPropertyType(StrEnum): BOOLEAN = "BOOLEAN" STRING = "STRING" INTEGER = "INTEGER" diff --git a/backend/infrahub/core/manager.py b/backend/infrahub/core/manager.py index 756a12e7e5..fc5577040a 100644 --- a/backend/infrahub/core/manager.py +++ b/backend/infrahub/core/manager.py @@ -59,7 +59,7 @@ def identify_node_class(node: NodeToProcess) -> type[Node]: return Node -def get_schema( +def get_schema[SchemaProtocol]( db: InfrahubDatabase, branch: Branch, node_schema: type[SchemaProtocol] | MainSchemaTypes | str, diff --git a/backend/infrahub/core/node/node_property_attribute.py b/backend/infrahub/core/node/node_property_attribute.py index 23f18d7e85..3bed2a4a45 100644 --- a/backend/infrahub/core/node/node_property_attribute.py +++ b/backend/infrahub/core/node/node_property_attribute.py @@ -2,7 +2,7 @@ from abc import abstractmethod from enum import Enum -from typing import TYPE_CHECKING, Any, Generic, TypeVar +from typing import TYPE_CHECKING, Any, TypeVar from infrahub_sdk.template import Jinja2Template @@ -21,7 +21,7 @@ T = TypeVar("T") -class NodePropertyAttribute(Generic[T]): +class NodePropertyAttribute[T]: """A node property attribute is a construct that seats between a property and an attribute. View it as a property, set at the node level but stored in the database as an attribute. It usually is something computed from other components of diff --git a/backend/infrahub/core/schema/__init__.py b/backend/infrahub/core/schema/__init__.py index 5e1adba5c4..3313643efd 100644 --- a/backend/infrahub/core/schema/__init__.py +++ b/backend/infrahub/core/schema/__init__.py @@ -1,7 +1,7 @@ from __future__ import annotations import uuid -from typing import Any, TypeAlias +from typing import Any from infrahub_sdk.utils import deep_merge_dict from pydantic import BaseModel, ConfigDict, Field @@ -21,8 +21,8 @@ from .relationship_schema import RelationshipSchema from .template_schema import TemplateSchema -NonGenericSchemaTypes: TypeAlias = NodeSchema | ProfileSchema | TemplateSchema -MainSchemaTypes: TypeAlias = NonGenericSchemaTypes | GenericSchema +NonGenericSchemaTypes = NodeSchema | ProfileSchema | TemplateSchema +MainSchemaTypes = NonGenericSchemaTypes | GenericSchema # ----------------------------------------------------- diff --git a/backend/infrahub/core/validators/enum.py b/backend/infrahub/core/validators/enum.py index b36e8a95a4..97e619457c 100644 --- a/backend/infrahub/core/validators/enum.py +++ b/backend/infrahub/core/validators/enum.py @@ -1,7 +1,7 @@ -from enum import Enum +from enum import StrEnum -class ConstraintIdentifier(str, Enum): +class ConstraintIdentifier(StrEnum): ATTRIBUTE_PARAMETERS_REGEX_UPDATE = "attribute.parameters.regex.update" ATTRIBUTE_PARAMETERS_MIN_LENGTH_UPDATE = "attribute.parameters.min_length.update" ATTRIBUTE_PARAMETERS_MAX_LENGTH_UPDATE = "attribute.parameters.max_length.update" diff --git a/backend/infrahub/dependencies/interface.py b/backend/infrahub/dependencies/interface.py index 40ce24e903..ac379cddb7 100644 --- a/backend/infrahub/dependencies/interface.py +++ b/backend/infrahub/dependencies/interface.py @@ -1,6 +1,6 @@ from abc import ABC, abstractmethod from dataclasses import dataclass -from typing import Generic, TypeVar +from typing import TypeVar from infrahub.core.branch import Branch from infrahub.database import InfrahubDatabase @@ -14,7 +14,7 @@ class DependencyBuilderContext: branch: Branch -class DependencyBuilder(ABC, Generic[T]): +class DependencyBuilder[T](ABC): @classmethod @abstractmethod def build(cls, context: DependencyBuilderContext) -> T: ... diff --git a/backend/infrahub/events/constants.py b/backend/infrahub/events/constants.py index a633471961..54b954ec51 100644 --- a/backend/infrahub/events/constants.py +++ b/backend/infrahub/events/constants.py @@ -1,8 +1,8 @@ -from enum import Enum +from enum import StrEnum EVENT_NAMESPACE = "infrahub" -class EventSortOrder(str, Enum): +class EventSortOrder(StrEnum): ASC = "asc" DESC = "desc" diff --git a/backend/infrahub/graphql/analyzer.py b/backend/infrahub/graphql/analyzer.py index 0af1e49073..708039ed50 100644 --- a/backend/infrahub/graphql/analyzer.py +++ b/backend/infrahub/graphql/analyzer.py @@ -3,7 +3,7 @@ from collections import deque from copy import deepcopy from dataclasses import dataclass, field -from enum import Enum +from enum import StrEnum from functools import cached_property from typing import TYPE_CHECKING, Any @@ -49,13 +49,13 @@ from infrahub.core.schema.schema_branch import SchemaBranch -class MutateAction(str, Enum): +class MutateAction(StrEnum): CREATE = "create" DELETE = "delete" UPDATE = "update" -class ContextType(str, Enum): +class ContextType(StrEnum): EDGE = "edge" NODE = "node" DIRECT = "direct" @@ -80,7 +80,7 @@ def from_relationship_cardinality(cls, cardinality: RelationshipCardinality) -> return cls.NODE -class GraphQLOperation(str, Enum): +class GraphQLOperation(StrEnum): QUERY = "query" MUTATION = "mutation" SUBSCRIPTION = "subscription" diff --git a/backend/infrahub/graphql/mutations/relationship.py b/backend/infrahub/graphql/mutations/relationship.py index 287b8a63ce..0ef81ad59e 100644 --- a/backend/infrahub/graphql/mutations/relationship.py +++ b/backend/infrahub/graphql/mutations/relationship.py @@ -1,6 +1,6 @@ from __future__ import annotations -from enum import Enum +from enum import StrEnum from typing import TYPE_CHECKING, Self from graphene import Boolean, InputField, InputObjectType, List, Mutation, String @@ -48,7 +48,7 @@ RELATIONSHIP_PEERS_TO_IGNORE = [InfrahubKind.NODE] -class GroupUpdateType(str, Enum): +class GroupUpdateType(StrEnum): NONE = "none" MEMBERS = "members" MEMBER_OF_GROUPS = "member_of_groups" diff --git a/backend/infrahub/patch/constants.py b/backend/infrahub/patch/constants.py index 144b9c7143..e9e5122622 100644 --- a/backend/infrahub/patch/constants.py +++ b/backend/infrahub/patch/constants.py @@ -1,7 +1,7 @@ -from enum import Enum +from enum import StrEnum -class PatchPlanFilename(str, Enum): +class PatchPlanFilename(StrEnum): VERTICES_TO_ADD = "vertices_to_add.json" VERTICES_TO_UPDATE = "vertices_to_update.json" VERTICES_TO_DELETE = "vertices_to_delete.json" diff --git a/backend/infrahub/telemetry/constants.py b/backend/infrahub/telemetry/constants.py index 8ef794e7b7..8197ac1047 100644 --- a/backend/infrahub/telemetry/constants.py +++ b/backend/infrahub/telemetry/constants.py @@ -1,9 +1,9 @@ -from enum import Enum +from enum import StrEnum TELEMETRY_KIND: str = "community" TELEMETRY_VERSION: str = "20250318" -class InfrahubType(str, Enum): +class InfrahubType(StrEnum): COMMUNITY = "community" ENTERPRISE = "enterprise" diff --git a/backend/infrahub/trigger/models.py b/backend/infrahub/trigger/models.py index 72aec78a5e..c43008c49c 100644 --- a/backend/infrahub/trigger/models.py +++ b/backend/infrahub/trigger/models.py @@ -1,7 +1,7 @@ from __future__ import annotations from datetime import timedelta -from enum import Enum +from enum import StrEnum from typing import TYPE_CHECKING, Any from prefect.events.actions import RunDeployment @@ -30,7 +30,7 @@ def in_use_count(self) -> int: return len(self.created + self.updated + self.unchanged) -class TriggerType(str, Enum): +class TriggerType(StrEnum): ACTION_TRIGGER_RULE = "action_trigger_rule" BUILTIN = "builtin" WEBHOOK = "webhook" diff --git a/backend/infrahub/utils.py b/backend/infrahub/utils.py index 6808f27986..532eda0e9c 100644 --- a/backend/infrahub/utils.py +++ b/backend/infrahub/utils.py @@ -76,7 +76,7 @@ def get_nested_dict(nested_dict: dict[str, Any], keys: list[str]) -> dict[str, A return current_level if isinstance(current_level, dict) else {} -def get_all_subclasses(cls: AnyClass) -> list[AnyClass]: +def get_all_subclasses[AnyClass: type](cls: AnyClass) -> list[AnyClass]: """Recursively get all subclasses of the given class.""" subclasses: list[AnyClass] = [] for subclass in cls.__subclasses__(): diff --git a/backend/infrahub/validators/tasks.py b/backend/infrahub/validators/tasks.py index 3f3d05c057..db0b906ea6 100644 --- a/backend/infrahub/validators/tasks.py +++ b/backend/infrahub/validators/tasks.py @@ -12,7 +12,7 @@ ValidatorType = TypeVar("ValidatorType", bound=CoreValidator) -async def start_validator( +async def start_validator[ValidatorType: CoreValidator]( client: InfrahubClient, validator: CoreValidator | None, validator_type: type[ValidatorType], diff --git a/models/infrastructure_edge.py b/models/infrastructure_edge.py index 0cc9086df6..4698e21450 100644 --- a/models/infrastructure_edge.py +++ b/models/infrastructure_edge.py @@ -3,7 +3,7 @@ import time import uuid from collections import defaultdict -from enum import Enum +from enum import StrEnum from ipaddress import IPv4Network, IPv6Network from typing import cast @@ -444,7 +444,7 @@ class TemplateInfraPatchPanel(BaseModel): ) -class DevicePatternName(str, Enum): +class DevicePatternName(StrEnum): LEAF = "LEAF" CORE = "CORE" EDGE = "EDGE" diff --git a/pyproject.toml b/pyproject.toml index 287a9be6c0..bf30cd5b85 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -459,7 +459,7 @@ disable_error_code = [ [tool.ruff] line-length = 120 -target-version = "py310" +target-version = "py312" exclude = [ ".git", @@ -731,21 +731,22 @@ allow-dunder-method-names = [ ################################################################################################## # Review and change the below later # ################################################################################################## - "ANN001", # Missing type annotation for function argument - "ANN002", # Missing type annotation for `*args` - "ANN003", # Missing type annotation for `**kwargs` - "ANN201", # Missing return type annotation for public function - "ANN202", # Missing return type annotation for private function - "ANN401", # Dynamically typed expressions (typing.Any) are disallowed - "PLR0915", # Too many statements - "PT003", # `scope='function'` is implied in `@pytest.fixture()` - "PT007", # Wrong values type in `pytest.mark.parametrize` expected `list` of `tuple` - "PT006", # Wrong type passed to first argument of `pytest.mark.parametrize`; expected `tuple` - "PT011", # `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception - "PT012", # `pytest.raises()` block should contain a single simple statement - "PT013", # Incorrect import of `pytest`; use `import pytest` instead - "PT018", # Assertion should be broken down into multiple parts - "PT021", # Use `yield` instead of `request.addfinalizer` + "ANN001", # Missing type annotation for function argument + "ANN002", # Missing type annotation for `*args` + "ANN003", # Missing type annotation for `**kwargs` + "ANN201", # Missing return type annotation for public function + "ANN202", # Missing return type annotation for private function + "ANN401", # Dynamically typed expressions (typing.Any) are disallowed + "ASYNC109", # Async function definition with a `timeout` parameter + "PLR0915", # Too many statements + "PT003", # `scope='function'` is implied in `@pytest.fixture()` + "PT007", # Wrong values type in `pytest.mark.parametrize` expected `list` of `tuple` + "PT006", # Wrong type passed to first argument of `pytest.mark.parametrize`; expected `tuple` + "PT011", # `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception + "PT012", # `pytest.raises()` block should contain a single simple statement + "PT013", # Incorrect import of `pytest`; use `import pytest` instead + "PT018", # Assertion should be broken down into multiple parts + "PT021", # Use `yield` instead of `request.addfinalizer` ] "backend/tests/integration_docker/test_schema_migration.py" = [ diff --git a/python_testcontainers/infrahub_testcontainers/models.py b/python_testcontainers/infrahub_testcontainers/models.py index 56c88168c3..e07208c462 100644 --- a/python_testcontainers/infrahub_testcontainers/models.py +++ b/python_testcontainers/infrahub_testcontainers/models.py @@ -1,11 +1,11 @@ from datetime import UTC, datetime -from enum import Enum +from enum import StrEnum from typing import Any from pydantic import BaseModel, Field -class ContextUnit(str, Enum): +class ContextUnit(StrEnum): COUNT = "count" TIME = "msec" # time in milliseconds MEMORY = "memory" # memory in bytes diff --git a/tasks/shared.py b/tasks/shared.py index 2d7cbe1511..b3bd6a29b1 100644 --- a/tasks/shared.py +++ b/tasks/shared.py @@ -4,7 +4,7 @@ import platform import re import sys -from enum import Enum +from enum import StrEnum from pathlib import Path from typing import TYPE_CHECKING @@ -17,12 +17,12 @@ from ruamel.yaml.main import YAML -class DatabaseType(str, Enum): +class DatabaseType(StrEnum): NEO4J = "neo4j" MEMGRAPH = "memgraph" -class Namespace(str, Enum): +class Namespace(StrEnum): DEFAULT = "default" # aka demo DEV = "dev" TEST = "test"