From 0c48eda34f4257e99f137ed03974073a22214608 Mon Sep 17 00:00:00 2001 From: Stefan Tatschner Date: Wed, 18 Dec 2024 11:21:03 +0100 Subject: [PATCH] chore: Enable TypeAlias lint --- pyproject.toml | 1 - src/gallia/command/config.py | 7 +++---- src/gallia/log.py | 4 ++-- src/gallia/pydantic_argparse/argparse/parser.py | 10 +++++----- src/gallia/pydantic_argparse/utils/nesting.py | 16 ++++++++-------- src/gallia/pydantic_argparse/utils/pydantic.py | 12 +++--------- src/gallia/transports/flexray_vector.py | 4 ++-- 7 files changed, 23 insertions(+), 31 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bb17a363e..f67228111 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -122,7 +122,6 @@ ignore = [ "TD001", # Invalid TODO tag: {tag} "TD002", # Missing author in TODO; try: # TODO(): ... or # TODO @: ... "TD003", # Missing issue link on the line following this TODO - "UP040", # Type alias uses `TypeAlias` annotation instead of the `type` keyword ] [tool.pytest.ini_options] diff --git a/src/gallia/command/config.py b/src/gallia/command/config.py index c293ad6c7..8686776b3 100644 --- a/src/gallia/command/config.py +++ b/src/gallia/command/config.py @@ -13,7 +13,6 @@ TYPE_CHECKING, Annotated, Any, - TypeAlias, TypeVar, Unpack, get_args, @@ -132,9 +131,9 @@ def auto_enum(x: str, enum_type: type[EnumType]) -> EnumType: if TYPE_CHECKING: - Idempotent: TypeAlias = Annotated[T, ""] - EnumArg: TypeAlias = Annotated[EnumType, ""] - AutoLiteral: TypeAlias = Annotated[LiteralType, ""] + type Idempotent[T] = Annotated[T, ""] + type EnumArg[EnumType: Enum] = Annotated[EnumType, ""] + type AutoLiteral[LiteralType] = Annotated[LiteralType, ""] else: class _TrickType: diff --git a/src/gallia/log.py b/src/gallia/log.py index fdcbdf96f..519c71b48 100644 --- a/src/gallia/log.py +++ b/src/gallia/log.py @@ -25,7 +25,7 @@ from pathlib import Path from queue import Queue from types import TracebackType -from typing import TYPE_CHECKING, Any, BinaryIO, Self, TextIO, TypeAlias, cast +from typing import TYPE_CHECKING, Any, BinaryIO, Self, TextIO, cast import zstandard @@ -343,7 +343,7 @@ class _PenlogRecordV2: _python_func_name: str | None = None -_PenlogRecord: TypeAlias = _PenlogRecordV2 +type _PenlogRecord = _PenlogRecordV2 def _colorize_msg(data: str, levelno: int) -> tuple[str, int]: diff --git a/src/gallia/pydantic_argparse/argparse/parser.py b/src/gallia/pydantic_argparse/argparse/parser.py index 99c3bd748..6a1c7dfa8 100644 --- a/src/gallia/pydantic_argparse/argparse/parser.py +++ b/src/gallia/pydantic_argparse/argparse/parser.py @@ -20,7 +20,7 @@ import argparse import sys -from typing import Any, Generic, Never, NoReturn +from typing import Any, Never, NoReturn from pydantic import BaseModel, ValidationError @@ -29,10 +29,10 @@ from gallia.pydantic_argparse.parsers import command from gallia.pydantic_argparse.utils.field import ArgFieldInfo from gallia.pydantic_argparse.utils.nesting import _NestedArgumentParser -from gallia.pydantic_argparse.utils.pydantic import PydanticField, PydanticModelT +from gallia.pydantic_argparse.utils.pydantic import PydanticField -class ArgumentParser(argparse.ArgumentParser, Generic[PydanticModelT]): +class ArgumentParser[T: BaseModel](argparse.ArgumentParser): """Declarative and Typed Argument Parser. The `ArgumentParser` declaratively generates a command-line interface using @@ -60,7 +60,7 @@ class ArgumentParser(argparse.ArgumentParser, Generic[PydanticModelT]): def __init__( self, - model: type[PydanticModelT], + model: type[T], prog: str | None = None, description: str | None = None, version: str | None = None, @@ -116,7 +116,7 @@ def __init__( def parse_typed_args( self, args: list[str] | None = None, - ) -> tuple[PydanticModelT, BaseModel]: + ) -> tuple[T, BaseModel]: """Parses command line arguments. If `args` are not supplied by the user, then they are automatically diff --git a/src/gallia/pydantic_argparse/utils/nesting.py b/src/gallia/pydantic_argparse/utils/nesting.py index 0562450df..4e882fe0f 100644 --- a/src/gallia/pydantic_argparse/utils/nesting.py +++ b/src/gallia/pydantic_argparse/utils/nesting.py @@ -5,23 +5,21 @@ """Utilities to help with parsing arbitrarily nested `pydantic` models.""" from argparse import Namespace -from typing import Any, Generic, TypeAlias +from typing import Any from boltons.iterutils import get_path, remap # type: ignore from pydantic import BaseModel from .namespaces import to_dict -from .pydantic import PydanticField, PydanticModelT +from .pydantic import PydanticField -ModelT: TypeAlias = PydanticModelT | type[PydanticModelT] | BaseModel | type[BaseModel] - -class _NestedArgumentParser(Generic[PydanticModelT]): +class _NestedArgumentParser[T: BaseModel]: """Parses arbitrarily nested `pydantic` models and inserts values passed at the command line.""" def __init__( self, - model: PydanticModelT | type[PydanticModelT], + model: T | type[T], namespace: Namespace, ) -> None: self.model = model @@ -30,7 +28,9 @@ def __init__( self.schema: dict[str, Any] = self._get_nested_model_fields(self.model, namespace) self.schema = self._remove_null_leaves(self.schema) - def _get_nested_model_fields(self, model: ModelT[Any], namespace: Namespace) -> dict[str, Any]: + def _get_nested_model_fields( + self, model: T | type[T] | BaseModel | type[BaseModel], namespace: Namespace + ) -> dict[str, Any]: def contains_subcommand(ns: Namespace, subcommand_path: tuple[str, ...]) -> bool: for step in subcommand_path: tmp = getattr(ns, step, None) @@ -82,7 +82,7 @@ def _remove_null_leaves(self, schema: dict[str, Any]) -> Any: # the schema return remap(schema, visit=lambda p, k, v: v is not None) - def validate(self) -> tuple[PydanticModelT, BaseModel]: + def validate(self) -> tuple[T, BaseModel]: """Return the root of the model, as well as the sub-model for the bottom subcommand""" model = self.model.model_validate(self.schema) subcommand = model diff --git a/src/gallia/pydantic_argparse/utils/pydantic.py b/src/gallia/pydantic_argparse/utils/pydantic.py index e04da5073..9b26e4779 100644 --- a/src/gallia/pydantic_argparse/utils/pydantic.py +++ b/src/gallia/pydantic_argparse/utils/pydantic.py @@ -18,7 +18,7 @@ Annotated, Any, Literal, - TypeVar, + Self, Union, cast, get_args, @@ -33,12 +33,6 @@ from .types import all_types -# Constants -T = TypeVar("T") -PydanticModelT = TypeVar("PydanticModelT", bound=BaseModel) -PydanticValidator = classmethod -NoneType = type(None) - @dataclass class PydanticField: @@ -55,7 +49,7 @@ class PydanticField: extra_default: tuple[str, Any] | None = None @classmethod - def parse_model(cls, model: BaseModel | type[BaseModel]) -> Iterator["PydanticField"]: + def parse_model(cls, model: BaseModel | type[BaseModel]) -> Iterator[Self]: """Iterator over the pydantic model fields, yielding this wrapper class. Yields: @@ -71,7 +65,7 @@ def _get_type(self, annotation: type | None) -> type | tuple[type | None, ...] | return origin elif origin is Union or origin is UnionType: args = get_args(annotation) - types = [arg for arg in args if arg is not NoneType] + types = [arg for arg in args if arg is not type(None)] elif origin is None: types = [annotation] else: diff --git a/src/gallia/transports/flexray_vector.py b/src/gallia/transports/flexray_vector.py index 2ece6bb4e..01fd81490 100644 --- a/src/gallia/transports/flexray_vector.py +++ b/src/gallia/transports/flexray_vector.py @@ -6,7 +6,7 @@ import sys from enum import IntEnum, unique from itertools import batched -from typing import ClassVar, Self, TypeAlias +from typing import ClassVar, Self from pydantic import BaseModel, ConfigDict, field_validator @@ -281,7 +281,7 @@ def parse(cls, data: bytes) -> Self: ) -FlexRayTPFrame: TypeAlias = ( +type FlexRayTPFrame = ( FlexRayTPSingleFrame | FlexRayTPFirstFrame | FlexRayTPConsecutiveFrame