diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 3753ca8..b862725 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,4 +1,4 @@ -name: "LINT: Run ruff & mypy" +name: "LINT: Run ruff & pyright" on: push: pull_request: @@ -17,7 +17,7 @@ jobs: run: | python -m pip install --upgrade poetry poetry install - - name: Lint with ruff & mypy + - name: Lint with ruff & pyright run: | poetry run ruff check pydantic_apply tests - poetry run mypy pydantic_apply + poetry run pyright pydantic_apply diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index edd9515..5058cd6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: end-of-file-fixer - id: check-added-large-files @@ -8,16 +8,16 @@ repos: - id: check-docstring-first - id: debug-statements - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.0.291 + rev: v0.2.1 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/Lucas-C/pre-commit-hooks-safety - rev: v1.3.2 + rev: v1.3.3 hooks: - id: python-safety-dependencies-check - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook - rev: v9.5.0 + rev: v9.11.0 hooks: - id: commitlint stages: [commit-msg] diff --git a/justfile b/justfile index 83f3667..cec9a4d 100644 --- a/justfile +++ b/justfile @@ -32,8 +32,8 @@ test-all: (poetry "run" "tox") ruff *args: (poetry "run" "ruff" "check" "pydantic_apply" "tests" args) -mypy *args: (poetry "run" "mypy" "pydantic_apply" args) +pyright *args: (poetry "run" "pyright" "pydantic_apply" args) -lint: ruff mypy +lint: ruff pyright publish: (poetry "publish" "--build") diff --git a/pydantic_apply/_compat.py b/pydantic_apply/_compat.py index 9b36055..35f2191 100644 --- a/pydantic_apply/_compat.py +++ b/pydantic_apply/_compat.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, Optional, Set, Type +from typing import Any, Dict, Set, Type import pydantic from pydantic.fields import FieldInfo @@ -9,7 +9,7 @@ if PYDANTIC_V1: # pragma: no cover - class PydanticCompat: + class PydanticCompat: # type: ignore obj: pydantic.BaseModel def __init__( @@ -60,7 +60,9 @@ def model_fields(self) -> Dict[str, FieldInfo]: def __pydantic_fields_set__(self) -> Set[str]: return self.obj.__pydantic_fields_set__ - def get_model_field_info_annotation(self, model_field: FieldInfo) -> Optional[Type[Any]]: + def get_model_field_info_annotation(self, model_field: FieldInfo) -> Type[Any]: + if model_field.annotation is None: + raise RuntimeError("model field has not typing annotation") return model_field.annotation def get_model_config_value(self, key: str) -> Any: diff --git a/pydantic_apply/apply.py b/pydantic_apply/apply.py index 1021e91..e6f4422 100644 --- a/pydantic_apply/apply.py +++ b/pydantic_apply/apply.py @@ -1,5 +1,5 @@ import warnings -from typing import Any, Dict, Union +from typing import Any, Dict, Union, cast import pydantic @@ -64,7 +64,7 @@ def model_apply( current_value = PydanticCompat(current_value).model_copy() # ...then use `.apply(...)` on the current value to prepare changes - current_value.model_apply(changed_field_value) + cast(ApplyModelMixin, current_value).model_apply(changed_field_value) prepared_changes[field_name] = current_value continue diff --git a/pyproject.toml b/pyproject.toml index b87ae6a..407955a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,18 +14,20 @@ pydantic = ">=1.9.0,<3.0.0" [tool.poetry.group.dev.dependencies] pytest = ">=7.1.2,<9.0.0" pytest-cov = ">=3,<5" -mypy = ">=0.971,<2.0" tox = ">=3.26,<5.0" -ruff = ">=0.0.284,<0.3.0" +ruff = ">=0.2.0,<0.3.0" +pyright = ">=1.1.350,<1.2" [tool.ruff] -select = ["F","E","W","C","I","N","UP","ANN","S","B","A","COM","C4","T20","PT","ARG","TD","RUF"] line-length = 115 target-version = "py38" -ignore = ["A001","A002","A003","ANN101","ANN102","ANN401","C901","N8","B008","F405","F821"] output-format = "grouped" -[tool.ruff.per-file-ignores] +[tool.ruff.lint] +select = ["F","E","W","C","I","N","UP","ANN","S","B","A","COM","C4","T20","PT","ARG","TD","RUF"] +ignore = ["A001","A002","A003","ANN101","ANN102","ANN401","C901","N8","B008","F405","F821"] + +[tool.ruff.lint.per-file-ignores] "__init__.py" = ["F401"] "conftest.py" = ["S101","ANN","F401"] "test_*.py" = ["S101","ANN","F401"]