From 03b75a48ac8728dd6dfcadb5a713ae5c4253e718 Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Thu, 26 Oct 2023 19:53:07 -0500 Subject: [PATCH 1/7] feat: use ruff formatter --- .devcontainer/devcontainer.json | 3 +-- .pre-commit-config.yaml | 6 +----- Makefile | 2 +- README.md | 14 +++++++------- pyproject.toml | 11 +++++------ 5 files changed, 15 insertions(+), 21 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index bccc3c0030..c242ece3e6 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -29,12 +29,11 @@ "mhutchie.git-graph", "eamodio.gitlens", "github.vscode-github-actions", - "ms-python.black-formatter", "ms-python.mypy-type-checker", "charliermarsh.ruff" ], "settings": { - "python.editor.defaultFormatter": "ms-python.black-formatter", + "python.editor.defaultFormatter": "charliemarsh.ruff", "python.defaultInterpreterPath": "${workspaceFolder}/.venv", "python.terminal.activateEnvInCurrentTerminal": true, "python.testing.unittestEnabled": false, diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0da7241a8c..3adff0f625 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,6 +27,7 @@ repos: hooks: - id: ruff args: ["--fix"] + - id: ruff-format - repo: https://github.com/codespell-project/codespell rev: v2.2.6 hooks: @@ -34,11 +35,6 @@ repos: exclude: "tests/openapi/typescript_converter/test_converter|README.md" additional_dependencies: - tomli - - repo: https://github.com/psf/black - rev: 23.10.1 - hooks: - - id: black - args: [--config=./pyproject.toml] - repo: https://github.com/asottile/blacken-docs rev: 1.16.0 hooks: diff --git a/Makefile b/Makefile index 3e4f1615d3..910042b129 100644 --- a/Makefile +++ b/Makefile @@ -90,7 +90,7 @@ pyright: ## Run pyright type-check: mypy pyright ## Run all type checking .PHONY: pre-commit -pre-commit: ## Runs pre-commit hooks; includes ruff linting, codespell, black +pre-commit: ## Runs pre-commit hooks; includes ruff linting, codespell @echo "=> Running pre-commit process" @$(ENV_PREFIX)pre-commit run --all-files @echo "=> Pre-commit complete" diff --git a/README.md b/README.md index 8eb2c16f25..a5319c1ca0 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,13 @@ -| Project | | Status | -|-----------|:----|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| CI/CD | | [![Latest Release](https://github.com/litestar-org/litestar/actions/workflows/publish.yml/badge.svg)](https://github.com/litestar-org/litestar/actions/workflows/publish.yml) [![ci](https://github.com/litestar-org/litestar/actions/workflows/ci.yml/badge.svg)](https://github.com/litestar-org/litestar/actions/workflows/ci.yml) [![Documentation Building](https://github.com/litestar-org/litestar/actions/workflows/docs.yml/badge.svg?branch=main)](https://github.com/litestar-org/litestar/actions/workflows/docs.yml) | -| Quality | | [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=coverage)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) | -| Package | | [![PyPI - Version](https://img.shields.io/pypi/v/litestar?labelColor=202235&color=edb641&logo=python&logoColor=edb641)](https://badge.fury.io/py/litestar) ![PyPI - Support Python Versions](https://img.shields.io/pypi/pyversions/litestar?labelColor=202235&color=edb641&logo=python&logoColor=edb641) ![Starlite PyPI - Downloads](https://img.shields.io/pypi/dm/starlite?logo=python&label=starlite%20downloads&labelColor=202235&color=edb641&logoColor=edb641) ![Litestar PyPI - Downloads](https://img.shields.io/pypi/dm/litestar?logo=python&label=litestar%20downloads&labelColor=202235&color=edb641&logoColor=edb641) | -| Community | | [![Reddit](https://img.shields.io/reddit/subreddit-subscribers/litestarapi?label=r%2FLitestar&logo=reddit&labelColor=202235&color=edb641&logoColor=edb641)](https://reddit.com/r/litestarapi) [![Discord](https://img.shields.io/discord/919193495116337154?labelColor=202235&color=edb641&label=chat%20on%20discord&logo=discord&logoColor=edb641)](https://discord.gg/X3FJqy8d2j) [![Matrix](https://img.shields.io/badge/chat%20on%20Matrix-bridged-202235?labelColor=202235&color=edb641&logo=matrix&logoColor=edb641)](https://matrix.to/#/#litestar:matrix.org) [![Medium](https://img.shields.io/badge/Medium-202235?labelColor=202235&color=edb641&logo=medium&logoColor=edb641)](https://blog.litestar.dev) [![Twitter](https://img.shields.io/twitter/follow/LitestarAPI?labelColor=202235&color=edb641&logo=twitter&logoColor=edb641&style=flat)](https://twitter.com/LitestarAPI) [![Blog](https://img.shields.io/badge/Blog-litestar.dev-202235?logo=blogger&labelColor=202235&color=edb641&logoColor=edb641)](https://blog.litestar.dev) | -| Meta | | [![Litestar Project](https://img.shields.io/badge/Litestar%20Org-%E2%AD%90%20Litestar-202235.svg?logo=python&labelColor=202235&color=edb641&logoColor=edb641)](https://github.com/litestar-org/litestar) [![types - Mypy](https://img.shields.io/badge/types-Mypy-202235.svg?logo=python&labelColor=202235&color=edb641&logoColor=edb641)](https://github.com/python/mypy) [![License - MIT](https://img.shields.io/badge/license-MIT-202235.svg?logo=python&labelColor=202235&color=edb641&logoColor=edb641)](https://spdx.org/licenses/) [![Litestar Sponsors](https://img.shields.io/badge/Sponsor-%E2%9D%A4-%23edb641.svg?&logo=github&logoColor=edb641&labelColor=202235)](https://github.com/sponsors/litestar-org) [![linting - Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json&labelColor=202235)](https://github.com/astral-sh/ruff) [![code style - Black](https://img.shields.io/badge/code%20style-black-000000.svg?logo=python&labelColor=202235&logoColor=edb641)](https://github.com/psf/black) [![All Contributors](https://img.shields.io/github/all-contributors/litestar-org/litestar?labelColor=202235&color=edb641&logoColor=edb641)](#contributors-) | +| Project | | Status | +|-----------|:----|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| CI/CD | | [![Latest Release](https://github.com/litestar-org/litestar/actions/workflows/publish.yml/badge.svg)](https://github.com/litestar-org/litestar/actions/workflows/publish.yml) [![ci](https://github.com/litestar-org/litestar/actions/workflows/ci.yml/badge.svg)](https://github.com/litestar-org/litestar/actions/workflows/ci.yml) [![Documentation Building](https://github.com/litestar-org/litestar/actions/workflows/docs.yml/badge.svg?branch=main)](https://github.com/litestar-org/litestar/actions/workflows/docs.yml) | +| Quality | | [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=coverage)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) | +| Package | | [![PyPI - Version](https://img.shields.io/pypi/v/litestar?labelColor=202235&color=edb641&logo=python&logoColor=edb641)](https://badge.fury.io/py/litestar) ![PyPI - Support Python Versions](https://img.shields.io/pypi/pyversions/litestar?labelColor=202235&color=edb641&logo=python&logoColor=edb641) ![Starlite PyPI - Downloads](https://img.shields.io/pypi/dm/starlite?logo=python&label=starlite%20downloads&labelColor=202235&color=edb641&logoColor=edb641) ![Litestar PyPI - Downloads](https://img.shields.io/pypi/dm/litestar?logo=python&label=litestar%20downloads&labelColor=202235&color=edb641&logoColor=edb641) | +| Community | | [![Reddit](https://img.shields.io/reddit/subreddit-subscribers/litestarapi?label=r%2FLitestar&logo=reddit&labelColor=202235&color=edb641&logoColor=edb641)](https://reddit.com/r/litestarapi) [![Discord](https://img.shields.io/discord/919193495116337154?labelColor=202235&color=edb641&label=chat%20on%20discord&logo=discord&logoColor=edb641)](https://discord.gg/X3FJqy8d2j) [![Matrix](https://img.shields.io/badge/chat%20on%20Matrix-bridged-202235?labelColor=202235&color=edb641&logo=matrix&logoColor=edb641)](https://matrix.to/#/#litestar:matrix.org) [![Medium](https://img.shields.io/badge/Medium-202235?labelColor=202235&color=edb641&logo=medium&logoColor=edb641)](https://blog.litestar.dev) [![Twitter](https://img.shields.io/twitter/follow/LitestarAPI?labelColor=202235&color=edb641&logo=twitter&logoColor=edb641&style=flat)](https://twitter.com/LitestarAPI) [![Blog](https://img.shields.io/badge/Blog-litestar.dev-202235?logo=blogger&labelColor=202235&color=edb641&logoColor=edb641)](https://blog.litestar.dev) | +| Meta | | [![Litestar Project](https://img.shields.io/badge/Litestar%20Org-%E2%AD%90%20Litestar-202235.svg?logo=python&labelColor=202235&color=edb641&logoColor=edb641)](https://github.com/litestar-org/litestar) [![types - Mypy](https://img.shields.io/badge/types-Mypy-202235.svg?logo=python&labelColor=202235&color=edb641&logoColor=edb641)](https://github.com/python/mypy) [![License - MIT](https://img.shields.io/badge/license-MIT-202235.svg?logo=python&labelColor=202235&color=edb641&logoColor=edb641)](https://spdx.org/licenses/) [![Litestar Sponsors](https://img.shields.io/badge/Sponsor-%E2%9D%A4-%23edb641.svg?&logo=github&logoColor=edb641&labelColor=202235)](https://github.com/sponsors/litestar-org) [![linting - Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json&labelColor=202235)](https://github.com/astral-sh/ruff) [![code style - Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/format.json)](https://github.com/psf/black) [![All Contributors](https://img.shields.io/github/all-contributors/litestar-org/litestar?labelColor=202235&color=edb641&logoColor=edb641)](#contributors-) | diff --git a/pyproject.toml b/pyproject.toml index b952fd9ed0..3588f7b38a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -120,7 +120,6 @@ docs = [ ] linting = [ "ruff", - "black", "mypy", "pre-commit", "slotscheck", @@ -172,10 +171,6 @@ docs-serve = "sphinx-autobuild docs docs/_build/ -j auto --watch litestar --watc lint = "pre-commit run --all-files" test = "pytest tests docs/examples" -[tool.black] -include = '\.pyi?$' -line-length = 120 - [tool.codespell] ignore-words-list = "selectin" skip = 'pdm.lock,docs/examples/contrib/sqlalchemy/us_state_lookup.json' @@ -332,7 +327,7 @@ ignore = [ "D202", # pydocstyle - no blank lines allowed after function docstring "D205", # pydocstyle - 1 blank line required between summary line and description "D415", # pydocstyle - first line should end with a period, question mark, or exclamation point - "E501", # pycodestyle line too long, handled by black + "E501", # pycodestyle line too long, handled by ruff-fmt "PLW2901", # pylint - for loop variable overwritten by assignment target "RUF012", # Ruff-specific rule - annotated with classvar ] @@ -359,6 +354,10 @@ classmethod-decorators = [ [tool.ruff.isort] known-first-party = ["litestar", "tests", "examples"] +[tool.ruff.format] +quote-style = "double" +indent-style = "space" + [tool.ruff.per-file-ignores] "docs/**/*.*" = ["S", "B", "DTZ", "A", "TCH", "ERA", "D", "RET"] "docs/examples/**" = ["T201"] From f918cf111cb22e0b453a03260c0f1d3eb5a623c4 Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Thu, 26 Oct 2023 20:01:58 -0500 Subject: [PATCH 2/7] ci: apply ruff formatter --- .pre-commit-config.yaml | 2 +- docs/PYPI_README.md | 14 +++++++------- docs/examples/parameters/path_parameters_3.py | 2 +- litestar/_asgi/routing_trie/mapping.py | 3 ++- litestar/_openapi/responses.py | 18 ++++++++++++------ .../schema_generation/constrained_fields.py | 4 +++- litestar/app.py | 3 ++- litestar/connection/request.py | 12 +++++++++--- litestar/dto/dataclass_dto.py | 8 +++++--- litestar/handlers/base.py | 4 +--- litestar/handlers/http_handlers/_utils.py | 5 ++++- litestar/handlers/http_handlers/base.py | 12 +++++++++--- litestar/serialization/msgspec_hooks.py | 4 +++- litestar/testing/request_factory.py | 4 +++- litestar/testing/transport.py | 8 ++------ litestar/utils/signature.py | 3 +-- pyproject.toml | 2 +- tests/unit/test_cli/conftest.py | 3 ++- tests/unit/test_connection/test_request.py | 4 +++- .../test_htmx/test_htmx_response.py | 5 ++++- tests/unit/test_contrib/test_jwt/test_auth.py | 4 +++- .../test_asgi_handlers/test_handle_asgi.py | 5 ++++- .../test_signature_namespace.py | 6 +++++- .../test_handle_websocket.py | 7 ++++++- 24 files changed, 93 insertions(+), 49 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3adff0f625..7e4c1e5d81 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,7 +23,7 @@ repos: - id: unasyncd additional_dependencies: ["ruff"] - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: "v0.1.2" + rev: "v0.1.3" hooks: - id: ruff args: ["--fix"] diff --git a/docs/PYPI_README.md b/docs/PYPI_README.md index a636648635..74993e447a 100644 --- a/docs/PYPI_README.md +++ b/docs/PYPI_README.md @@ -8,13 +8,13 @@ -| Project | | Status | -|-----------|:----|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| CI/CD | | [![Latest Release](https://github.com/litestar-org/litestar/actions/workflows/publish.yml/badge.svg)](https://github.com/litestar-org/litestar/actions/workflows/publish.yml) [![ci](https://github.com/litestar-org/litestar/actions/workflows/ci.yml/badge.svg)](https://github.com/litestar-org/litestar/actions/workflows/ci.yml) [![Documentation Building](https://github.com/litestar-org/litestar/actions/workflows/docs.yml/badge.svg?branch=main)](https://github.com/litestar-org/litestar/actions/workflows/docs.yml) | -| Quality | | [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=coverage)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) | -| Package | | [![PyPI - Version](https://img.shields.io/pypi/v/litestar?labelColor=202235&color=edb641&logo=python&logoColor=edb641)](https://badge.fury.io/py/litestar) ![PyPI - Support Python Versions](https://img.shields.io/pypi/pyversions/litestar?labelColor=202235&color=edb641&logo=python&logoColor=edb641) ![Starlite PyPI - Downloads](https://img.shields.io/pypi/dm/starlite?logo=python&label=starlite%20downloads&labelColor=202235&color=edb641&logoColor=edb641) ![Litestar PyPI - Downloads](https://img.shields.io/pypi/dm/litestar?logo=python&label=litestar%20downloads&labelColor=202235&color=edb641&logoColor=edb641) | -| Community | | [![Reddit](https://img.shields.io/reddit/subreddit-subscribers/litestarapi?label=r%2FLitestar&logo=reddit&labelColor=202235&color=edb641&logoColor=edb641)](https://reddit.com/r/litestarapi) [![Discord](https://img.shields.io/discord/919193495116337154?labelColor=202235&color=edb641&label=chat%20on%20discord&logo=discord&logoColor=edb641)](https://discord.gg/X3FJqy8d2j) [![Matrix](https://img.shields.io/badge/chat%20on%20Matrix-bridged-202235?labelColor=202235&color=edb641&logo=matrix&logoColor=edb641)](https://matrix.to/#/#litestar:matrix.org) [![Medium](https://img.shields.io/badge/Medium-202235?labelColor=202235&color=edb641&logo=medium&logoColor=edb641)](https://blog.litestar.dev) [![Twitter](https://img.shields.io/twitter/follow/LitestarAPI?labelColor=202235&color=edb641&logo=twitter&logoColor=edb641&style=flat)](https://twitter.com/LitestarAPI) [![Blog](https://img.shields.io/badge/Blog-litestar.dev-202235?logo=blogger&labelColor=202235&color=edb641&logoColor=edb641)](https://blog.litestar.dev) | -| Meta | | [![Litestar Project](https://img.shields.io/badge/Litestar%20Org-%E2%AD%90%20Litestar-202235.svg?logo=python&labelColor=202235&color=edb641&logoColor=edb641)](https://github.com/litestar-org/litestar) [![types - Mypy](https://img.shields.io/badge/types-Mypy-202235.svg?logo=python&labelColor=202235&color=edb641&logoColor=edb641)](https://github.com/python/mypy) [![License - MIT](https://img.shields.io/badge/license-MIT-202235.svg?logo=python&labelColor=202235&color=edb641&logoColor=edb641)](https://spdx.org/licenses/) [![Litestar Sponsors](https://img.shields.io/badge/Sponsor-%E2%9D%A4-%23edb641.svg?&logo=github&logoColor=edb641&labelColor=202235)](https://github.com/sponsors/litestar-org) [![linting - Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json&labelColor=202235)](https://github.com/astral-sh/ruff) [![code style - Black](https://img.shields.io/badge/code%20style-black-000000.svg?logo=python&labelColor=202235&logoColor=edb641)](https://github.com/psf/black) [![All Contributors](https://img.shields.io/github/all-contributors/litestar-org/litestar?labelColor=202235&color=edb641&logoColor=edb641)](#contributors-) | +| Project | | Status | +|-----------|:----|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| CI/CD | | [![Latest Release](https://github.com/litestar-org/litestar/actions/workflows/publish.yml/badge.svg)](https://github.com/litestar-org/litestar/actions/workflows/publish.yml) [![ci](https://github.com/litestar-org/litestar/actions/workflows/ci.yml/badge.svg)](https://github.com/litestar-org/litestar/actions/workflows/ci.yml) [![Documentation Building](https://github.com/litestar-org/litestar/actions/workflows/docs.yml/badge.svg?branch=main)](https://github.com/litestar-org/litestar/actions/workflows/docs.yml) | +| Quality | | [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=coverage)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=litestar-org_litestar&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=litestar-org_litestar) | +| Package | | [![PyPI - Version](https://img.shields.io/pypi/v/litestar?labelColor=202235&color=edb641&logo=python&logoColor=edb641)](https://badge.fury.io/py/litestar) ![PyPI - Support Python Versions](https://img.shields.io/pypi/pyversions/litestar?labelColor=202235&color=edb641&logo=python&logoColor=edb641) ![Starlite PyPI - Downloads](https://img.shields.io/pypi/dm/starlite?logo=python&label=starlite%20downloads&labelColor=202235&color=edb641&logoColor=edb641) ![Litestar PyPI - Downloads](https://img.shields.io/pypi/dm/litestar?logo=python&label=litestar%20downloads&labelColor=202235&color=edb641&logoColor=edb641) | +| Community | | [![Reddit](https://img.shields.io/reddit/subreddit-subscribers/litestarapi?label=r%2FLitestar&logo=reddit&labelColor=202235&color=edb641&logoColor=edb641)](https://reddit.com/r/litestarapi) [![Discord](https://img.shields.io/discord/919193495116337154?labelColor=202235&color=edb641&label=chat%20on%20discord&logo=discord&logoColor=edb641)](https://discord.gg/X3FJqy8d2j) [![Matrix](https://img.shields.io/badge/chat%20on%20Matrix-bridged-202235?labelColor=202235&color=edb641&logo=matrix&logoColor=edb641)](https://matrix.to/#/#litestar:matrix.org) [![Medium](https://img.shields.io/badge/Medium-202235?labelColor=202235&color=edb641&logo=medium&logoColor=edb641)](https://blog.litestar.dev) [![Twitter](https://img.shields.io/twitter/follow/LitestarAPI?labelColor=202235&color=edb641&logo=twitter&logoColor=edb641&style=flat)](https://twitter.com/LitestarAPI) [![Blog](https://img.shields.io/badge/Blog-litestar.dev-202235?logo=blogger&labelColor=202235&color=edb641&logoColor=edb641)](https://blog.litestar.dev) | +| Meta | | [![Litestar Project](https://img.shields.io/badge/Litestar%20Org-%E2%AD%90%20Litestar-202235.svg?logo=python&labelColor=202235&color=edb641&logoColor=edb641)](https://github.com/litestar-org/litestar) [![types - Mypy](https://img.shields.io/badge/types-Mypy-202235.svg?logo=python&labelColor=202235&color=edb641&logoColor=edb641)](https://github.com/python/mypy) [![License - MIT](https://img.shields.io/badge/license-MIT-202235.svg?logo=python&labelColor=202235&color=edb641&logoColor=edb641)](https://spdx.org/licenses/) [![Litestar Sponsors](https://img.shields.io/badge/Sponsor-%E2%9D%A4-%23edb641.svg?&logo=github&logoColor=edb641&labelColor=202235)](https://github.com/sponsors/litestar-org) [![linting - Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json&labelColor=202235)](https://github.com/astral-sh/ruff) [![code style - Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/format.json)](https://github.com/psf/black) [![All Contributors](https://img.shields.io/github/all-contributors/litestar-org/litestar?labelColor=202235&color=edb641&logoColor=edb641)](#contributors-) | diff --git a/docs/examples/parameters/path_parameters_3.py b/docs/examples/parameters/path_parameters_3.py index 960726542b..18adb5afa0 100644 --- a/docs/examples/parameters/path_parameters_3.py +++ b/docs/examples/parameters/path_parameters_3.py @@ -29,7 +29,7 @@ def get_product_version( url="https://mywebsite.com/documentation/product#versions", # type: ignore[arg-type] ), ), - ] + ], ) -> Version: return VERSIONS[version] diff --git a/litestar/_asgi/routing_trie/mapping.py b/litestar/_asgi/routing_trie/mapping.py index d0f0fe5b7f..4b2e2cfe55 100644 --- a/litestar/_asgi/routing_trie/mapping.py +++ b/litestar/_asgi/routing_trie/mapping.py @@ -191,7 +191,8 @@ def build_route_middleware_stack( # we wrap the route.handle method in the ExceptionHandlerMiddleware asgi_handler = wrap_in_exception_handler( - app=route.handle, exception_handlers=route_handler.resolve_exception_handlers() # type: ignore[arg-type] + app=route.handle, + exception_handlers=route_handler.resolve_exception_handlers(), # type: ignore[arg-type] ) if app.csrf_config: diff --git a/litestar/_openapi/responses.py b/litestar/_openapi/responses.py index 8e22b12a50..acf4efb386 100644 --- a/litestar/_openapi/responses.py +++ b/litestar/_openapi/responses.py @@ -226,9 +226,12 @@ def create_error_responses(exceptions: list[type[HTTPException]]) -> Iterator[tu with contextlib.suppress(Exception): group_description = HTTPStatus(status_code).description - yield str(status_code), OpenAPIResponse( - description=group_description, - content={MediaType.JSON: OpenAPIMediaType(schema=schema)}, + yield ( + str(status_code), + OpenAPIResponse( + description=group_description, + content={MediaType.JSON: OpenAPIMediaType(schema=schema)}, + ), ) @@ -245,9 +248,12 @@ def create_additional_responses( schema = schema_creator.for_field_definition( FieldDefinition.from_annotation(additional_response.data_container) ) - yield str(status_code), OpenAPIResponse( - description=additional_response.description, - content={additional_response.media_type: OpenAPIMediaType(schema=schema)}, + yield ( + str(status_code), + OpenAPIResponse( + description=additional_response.description, + content={additional_response.media_type: OpenAPIMediaType(schema=schema)}, + ), ) diff --git a/litestar/_openapi/schema_generation/constrained_fields.py b/litestar/_openapi/schema_generation/constrained_fields.py index fe57a37960..f4f5c716db 100644 --- a/litestar/_openapi/schema_generation/constrained_fields.py +++ b/litestar/_openapi/schema_generation/constrained_fields.py @@ -80,7 +80,9 @@ def create_string_constrained_field_schema( schema.max_length = kwarg_definition.max_length if kwarg_definition.pattern: schema.pattern = ( - kwarg_definition.pattern.pattern if isinstance(kwarg_definition.pattern, Pattern) else kwarg_definition.pattern # type: ignore[attr-defined,unreachable] + kwarg_definition.pattern.pattern + if isinstance(kwarg_definition.pattern, Pattern) + else kwarg_definition.pattern # type: ignore[attr-defined,unreachable] ) if kwarg_definition.lower_case: schema.description = "must be in lower case" diff --git a/litestar/app.py b/litestar/app.py index 3c9fa08938..9a87c2bf9c 100644 --- a/litestar/app.py +++ b/litestar/app.py @@ -791,7 +791,8 @@ def _create_asgi_handler(self) -> ASGIApp: asgi_handler = CORSMiddleware(app=asgi_handler, config=self.cors_config) return wrap_in_exception_handler( - app=asgi_handler, exception_handlers=self.exception_handlers or {} # pyright: ignore + app=asgi_handler, + exception_handlers=self.exception_handlers or {}, # pyright: ignore ) def _wrap_send(self, send: Send, scope: Scope) -> Send: diff --git a/litestar/connection/request.py b/litestar/connection/request.py index 0cb0928651..162664eede 100644 --- a/litestar/connection/request.py +++ b/litestar/connection/request.py @@ -82,7 +82,9 @@ def content_type(self) -> tuple[str, dict[str, str]]: A tuple with the parsed value and a dictionary containing any options send in it. """ if self._content_type is Empty: - self._content_type = self.scope["_content_type"] = parse_content_header(self.headers.get("Content-Type", "")) # type: ignore[typeddict-unknown-key] + self._content_type = self.scope["_content_type"] = parse_content_header( + self.headers.get("Content-Type", "") + ) # type: ignore[typeddict-unknown-key] return cast("tuple[str, dict[str, str]]", self._content_type) @property @@ -104,7 +106,9 @@ async def json(self) -> Any: """ if self._json is Empty: body = await self.body() - self._json = self.scope["_json"] = decode_json(body or b"null", type_decoders=self.route_handler.resolve_type_decoders()) # type: ignore[typeddict-unknown-key] + self._json = self.scope["_json"] = decode_json( + body or b"null", type_decoders=self.route_handler.resolve_type_decoders() + ) # type: ignore[typeddict-unknown-key] return self._json async def msgpack(self) -> Any: @@ -115,7 +119,9 @@ async def msgpack(self) -> Any: """ if self._msgpack is Empty: body = await self.body() - self._msgpack = self.scope["_msgpack"] = decode_msgpack(body or b"\xc0", type_decoders=self.route_handler.resolve_type_decoders()) # type: ignore[typeddict-unknown-key] + self._msgpack = self.scope["_msgpack"] = decode_msgpack( + body or b"\xc0", type_decoders=self.route_handler.resolve_type_decoders() + ) # type: ignore[typeddict-unknown-key] return self._msgpack async def stream(self) -> AsyncGenerator[bytes, None]: diff --git a/litestar/dto/dataclass_dto.py b/litestar/dto/dataclass_dto.py index a7952d4902..554b0f3343 100644 --- a/litestar/dto/dataclass_dto.py +++ b/litestar/dto/dataclass_dto.py @@ -47,9 +47,11 @@ def generate_field_definitions( default=default, ) - yield replace(field_defintion, default=Empty, kwarg_definition=default) if isinstance( - default, (KwargDefinition, DependencyKwarg) - ) else field_defintion + yield ( + replace(field_defintion, default=Empty, kwarg_definition=default) + if isinstance(default, (KwargDefinition, DependencyKwarg)) + else field_defintion + ) @classmethod def detect_nested_field(cls, field_definition: FieldDefinition) -> bool: diff --git a/litestar/handlers/base.py b/litestar/handlers/base.py index 5d6aefabd0..e18b018117 100644 --- a/litestar/handlers/base.py +++ b/litestar/handlers/base.py @@ -148,9 +148,7 @@ def __init__( self.type_encoders = type_encoders self.paths = ( - {normalize_path(p) for p in path} - if path and isinstance(path, list) - else {normalize_path(path or "/")} # type: ignore + {normalize_path(p) for p in path} if path and isinstance(path, list) else {normalize_path(path or "/")} # type: ignore ) def __call__(self, fn: AsyncAnyCallable) -> Self: diff --git a/litestar/handlers/http_handlers/_utils.py b/litestar/handlers/http_handlers/_utils.py index da59a42c91..3bca52117c 100644 --- a/litestar/handlers/http_handlers/_utils.py +++ b/litestar/handlers/http_handlers/_utils.py @@ -147,7 +147,10 @@ def create_response_handler( cookie_list = list(cookies) async def handler( - data: Response, app: Litestar, request: Request, **kwargs: Any # kwargs is for return dto + data: Response, + app: Litestar, + request: Request, + **kwargs: Any, # kwargs is for return dto ) -> ASGIApp: response = await after_request(data) if after_request else data # type:ignore[arg-type,misc] return response.to_asgi_response( # type: ignore diff --git a/litestar/handlers/http_handlers/base.py b/litestar/handlers/http_handlers/base.py index 7fbacab3d3..85358a9e70 100644 --- a/litestar/handlers/http_handlers/base.py +++ b/litestar/handlers/http_handlers/base.py @@ -367,7 +367,9 @@ def resolve_before_request(self) -> AsyncCallable | None: """ if self._resolved_before_request is Empty: before_request_handlers: list[AsyncCallable] = [ - layer.before_request for layer in self.ownership_layers if layer.before_request # type: ignore[misc] + layer.before_request + for layer in self.ownership_layers + if layer.before_request # type: ignore[misc] ] self._resolved_before_request = before_request_handlers[-1] if before_request_handlers else None return cast("AsyncCallable | None", self._resolved_before_request) @@ -383,7 +385,9 @@ def resolve_after_response(self) -> AsyncCallable | None: """ if self._resolved_after_response is Empty: after_response_handlers: list[AsyncCallable] = [ - layer.after_response for layer in self.ownership_layers if layer.after_response # type: ignore[misc] + layer.after_response + for layer in self.ownership_layers + if layer.after_response # type: ignore[misc] ] self._resolved_after_response = after_response_handlers[-1] if after_response_handlers else None @@ -419,7 +423,9 @@ def get_response_handler(self, is_response_type_data: bool = False) -> Callable[ """ if self._response_handler_mapping["default_handler"] is Empty: after_request_handlers: list[AsyncCallable] = [ - layer.after_request for layer in self.ownership_layers if layer.after_request # type: ignore[misc] + layer.after_request + for layer in self.ownership_layers + if layer.after_request # type: ignore[misc] ] after_request = cast( "AfterRequestHookHandler | None", diff --git a/litestar/serialization/msgspec_hooks.py b/litestar/serialization/msgspec_hooks.py index e7f561f853..837c72a66c 100644 --- a/litestar/serialization/msgspec_hooks.py +++ b/litestar/serialization/msgspec_hooks.py @@ -232,7 +232,9 @@ def decode_msgpack(value: bytes, target_type: type[T], type_decoders: TypeDecode ... -def decode_msgpack(value: bytes, target_type: type[T] | EmptyType = Empty, type_decoders: TypeDecodersSequence | None = None) -> Any: # type: ignore[misc] +def decode_msgpack( + value: bytes, target_type: type[T] | EmptyType = Empty, type_decoders: TypeDecodersSequence | None = None +) -> Any: # type: ignore[misc] """Decode a MessagePack string/bytes into an object. Args: diff --git a/litestar/testing/request_factory.py b/litestar/testing/request_factory.py index 2d693ee082..1c2e63082f 100644 --- a/litestar/testing/request_factory.py +++ b/litestar/testing/request_factory.py @@ -291,7 +291,9 @@ def _create_request_with_data( if request_media_type == RequestEncodingType.JSON: encoding_headers, stream = httpx_encode_json(data) elif request_media_type == RequestEncodingType.MULTI_PART: - encoding_headers, stream = encode_multipart_data(cast("dict[str, Any]", data), files=files or [], boundary=None) # type: ignore[assignment] + encoding_headers, stream = encode_multipart_data( + cast("dict[str, Any]", data), files=files or [], boundary=None + ) # type: ignore[assignment] else: encoding_headers, stream = encode_urlencoded_data(decode_json(value=encode_json(data))) headers.update(encoding_headers) diff --git a/litestar/testing/transport.py b/litestar/testing/transport.py index b5683041d8..ffa76a46ac 100644 --- a/litestar/testing/transport.py +++ b/litestar/testing/transport.py @@ -83,18 +83,14 @@ async def receive() -> ReceiveMessage: def create_send(request: Request, context: SendReceiveContext) -> Send: async def send(message: Message) -> None: if message["type"] == "http.response.start": - assert not context[ # noqa: S101 - "response_started" - ], 'Received multiple "http.response.start" messages.' + assert not context["response_started"], 'Received multiple "http.response.start" messages.' # noqa: S101 context["raw_kwargs"]["status_code"] = message["status"] context["raw_kwargs"]["headers"] = [ (k.decode("utf-8"), v.decode("utf-8")) for k, v in message.get("headers", []) ] context["response_started"] = True elif message["type"] == "http.response.body": - assert context[ # noqa: S101 - "response_started" - ], 'Received "http.response.body" without "http.response.start".' + assert context["response_started"], 'Received "http.response.body" without "http.response.start".' # noqa: S101 assert not context[ # noqa: S101 "response_complete" ].is_set(), 'Received "http.response.body" after response completed.' diff --git a/litestar/utils/signature.py b/litestar/utils/signature.py index 43e2f782bf..4bdb5d4b42 100644 --- a/litestar/utils/signature.py +++ b/litestar/utils/signature.py @@ -43,8 +43,7 @@ def _get_defaults(_: Any) -> Any: for namespace, export in chain( tuple(getmembers(types)), tuple(getmembers(connection)), tuple(getmembers(datastructures)) ) - if namespace[0].isupper() - and namespace in chain(types.__all__, connection.__all__, datastructures.__all__) # pyright: ignore + if namespace[0].isupper() and namespace in chain(types.__all__, connection.__all__, datastructures.__all__) # pyright: ignore } """A mapping of names used for handler signature forward-ref resolution. diff --git a/pyproject.toml b/pyproject.toml index 3588f7b38a..92fccddf68 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -292,7 +292,7 @@ select = [ "G", # flake8-logging-format "I", # isort "ICN", # flake8-import-conventions - "ISC", # flake8-implicit-str-concat + "ISC", # flake8-implicit-str-concat # Ruff Formatter conflicts with this "N", # pep8-naming "PIE", # flake8-pie "PLC", # pylint - convention diff --git a/tests/unit/test_cli/conftest.py b/tests/unit/test_cli/conftest.py index 996ab39c4b..6cd2f4fb19 100644 --- a/tests/unit/test_cli/conftest.py +++ b/tests/unit/test_cli/conftest.py @@ -100,7 +100,8 @@ def _create_app_file( request.addfinalizer(lambda: rmtree(directory)) request.addfinalizer( lambda: _purge_module( - [directory, _path_to_dotted_path(tmp_app_file.relative_to(Path.cwd()))], tmp_app_file # type: ignore[list-item] + [directory, _path_to_dotted_path(tmp_app_file.relative_to(Path.cwd()))], + tmp_app_file, # type: ignore[list-item] ) ) else: diff --git a/tests/unit/test_connection/test_request.py b/tests/unit/test_connection/test_request.py index a5260592ea..feff10b537 100644 --- a/tests/unit/test_connection/test_request.py +++ b/tests/unit/test_connection/test_request.py @@ -353,7 +353,9 @@ async def receiver() -> dict: return {"type": "http.disconnect"} with pytest.raises(InternalServerException): - await app({"type": "http", "route_handler": _route_handler, "method": "POST", "path": "/"}, receiver, empty_send) # type: ignore + await app( + {"type": "http", "route_handler": _route_handler, "method": "POST", "path": "/"}, receiver, empty_send + ) # type: ignore def test_request_state() -> None: diff --git a/tests/unit/test_contrib/test_htmx/test_htmx_response.py b/tests/unit/test_contrib/test_htmx/test_htmx_response.py index abd700c7e3..91feaefac6 100644 --- a/tests/unit/test_contrib/test_htmx/test_htmx_response.py +++ b/tests/unit/test_contrib/test_htmx/test_htmx_response.py @@ -185,7 +185,10 @@ async def test_trigger_event_response_invalid_after() -> None: @get("/") def handler() -> TriggerEvent: return TriggerEvent( - content="Success!", name="alert", after="invalid", params={"warning": "Confirm your choice!"} # type: ignore + content="Success!", + name="alert", + after="invalid", + params={"warning": "Confirm your choice!"}, # type: ignore ) with create_test_client(route_handlers=[handler], request_class=HTMXRequest) as client: diff --git a/tests/unit/test_contrib/test_jwt/test_auth.py b/tests/unit/test_contrib/test_jwt/test_auth.py index 4285c811e4..0fbbc3d4d6 100644 --- a/tests/unit/test_contrib/test_jwt/test_auth.py +++ b/tests/unit/test_contrib/test_jwt/test_auth.py @@ -346,7 +346,9 @@ async def retrieve_user_handler(token: Token, connection: Any) -> Any: return await mock_db.get(token.sub) jwt_auth = OAuth2PasswordBearerAuth( - token_url="/login", token_secret="abc123", retrieve_user_handler=retrieve_user_handler # type: ignore + token_url="/login", + token_secret="abc123", + retrieve_user_handler=retrieve_user_handler, # type: ignore ) @get("/login") diff --git a/tests/unit/test_handlers/test_asgi_handlers/test_handle_asgi.py b/tests/unit/test_handlers/test_asgi_handlers/test_handle_asgi.py index da310bf452..2e92b91acd 100644 --- a/tests/unit/test_handlers/test_asgi_handlers/test_handle_asgi.py +++ b/tests/unit/test_handlers/test_asgi_handlers/test_handle_asgi.py @@ -40,7 +40,10 @@ class MyController(Controller): @asgi(signature_namespace={"c": Send}) async def root_asgi_handler( - self, scope: "a", receive: "b", send: "c" # type:ignore[name-defined] # noqa: F821 + self, + scope: "a", # noqa: F821 + receive: "b", # noqa: F821 + send: "c", # type:ignore[name-defined] # noqa: F821 ) -> None: await ASGIResponse(body=scope["path"].encode(), media_type=MediaType.TEXT)(scope, receive, send) diff --git a/tests/unit/test_handlers/test_http_handlers/test_signature_namespace.py b/tests/unit/test_handlers/test_http_handlers/test_signature_namespace.py index 8b9fd59832..c9edb0497f 100644 --- a/tests/unit/test_handlers/test_http_handlers/test_signature_namespace.py +++ b/tests/unit/test_handlers/test_http_handlers/test_signature_namespace.py @@ -18,7 +18,11 @@ class MyController(Controller): @decorator(path="/", signature_namespace={"d": List[str], "dict": Dict}, status_code=200) # type:ignore[misc] async def simple_handler( - self, a: a, b: b, c: c, d: d # type:ignore[name-defined] # noqa: F821 + self, + a: a, # noqa: F821 + b: b, # noqa: F821 + c: c, # noqa: F821 + d: d, # type:ignore[name-defined] # noqa: F821 ) -> dict[str, Any]: return {"a": a, "b": b, "c": c, "d": d} diff --git a/tests/unit/test_handlers/test_websocket_handlers/test_handle_websocket.py b/tests/unit/test_handlers/test_websocket_handlers/test_handle_websocket.py index f0ddaf3b64..704653cd7e 100644 --- a/tests/unit/test_handlers/test_websocket_handlers/test_handle_websocket.py +++ b/tests/unit/test_handlers/test_websocket_handlers/test_handle_websocket.py @@ -28,7 +28,12 @@ class MyController(Controller): @websocket(path="/", signature_namespace={"d": List[str]}) async def simple_websocket_handler( - self, socket: WebSocket, a: "a", b: "b", c: "c", d: "d" # type:ignore[name-defined] # noqa: F821 + self, + socket: WebSocket, + a: "a", # noqa: F821 + b: "b", # noqa: F821 + c: "c", # noqa: F821 + d: "d", # type:ignore[name-defined] # noqa: F821 ) -> None: await socket.accept() data = await socket.receive_json() From f1dbe6f0d957ae2485c9c35b7796848e37cc6d95 Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Thu, 26 Oct 2023 22:00:15 -0500 Subject: [PATCH 3/7] ci(mypy): make mypy happy --- litestar/_asgi/routing_trie/mapping.py | 4 ++-- litestar/_openapi/schema_generation/constrained_fields.py | 6 +++--- litestar/channels/backends/redis.py | 2 +- litestar/connection/request.py | 4 ++-- litestar/handlers/http_handlers/base.py | 4 ++-- litestar/serialization/msgspec_hooks.py | 8 +++++--- litestar/testing/request_factory.py | 4 ++-- tests/unit/test_cli/conftest.py | 4 ++-- tests/unit/test_connection/test_request.py | 6 ++++-- tests/unit/test_contrib/test_htmx/test_htmx_response.py | 4 ++-- .../test_handlers/test_asgi_handlers/test_handle_asgi.py | 4 ++-- .../test_http_handlers/test_signature_namespace.py | 6 +++--- .../test_websocket_handlers/test_handle_websocket.py | 6 +++--- 13 files changed, 33 insertions(+), 29 deletions(-) diff --git a/litestar/_asgi/routing_trie/mapping.py b/litestar/_asgi/routing_trie/mapping.py index 4b2e2cfe55..96095c0895 100644 --- a/litestar/_asgi/routing_trie/mapping.py +++ b/litestar/_asgi/routing_trie/mapping.py @@ -190,9 +190,9 @@ def build_route_middleware_stack( from litestar.routes import HTTPRoute # we wrap the route.handle method in the ExceptionHandlerMiddleware - asgi_handler = wrap_in_exception_handler( + asgi_handler = wrap_in_exception_handler( # type: ignore[arg-type] app=route.handle, - exception_handlers=route_handler.resolve_exception_handlers(), # type: ignore[arg-type] + exception_handlers=route_handler.resolve_exception_handlers(), ) if app.csrf_config: diff --git a/litestar/_openapi/schema_generation/constrained_fields.py b/litestar/_openapi/schema_generation/constrained_fields.py index f4f5c716db..80f355d2c8 100644 --- a/litestar/_openapi/schema_generation/constrained_fields.py +++ b/litestar/_openapi/schema_generation/constrained_fields.py @@ -80,9 +80,9 @@ def create_string_constrained_field_schema( schema.max_length = kwarg_definition.max_length if kwarg_definition.pattern: schema.pattern = ( - kwarg_definition.pattern.pattern - if isinstance(kwarg_definition.pattern, Pattern) - else kwarg_definition.pattern # type: ignore[attr-defined,unreachable] + kwarg_definition.pattern.pattern # type: ignore[attr-defined] + if isinstance(kwarg_definition.pattern, Pattern) # type: ignore[unreachable] + else kwarg_definition.pattern ) if kwarg_definition.lower_case: schema.description = "must be in lower case" diff --git a/litestar/channels/backends/redis.py b/litestar/channels/backends/redis.py index c84c061c88..3ce4c26025 100644 --- a/litestar/channels/backends/redis.py +++ b/litestar/channels/backends/redis.py @@ -4,7 +4,7 @@ import sys if sys.version_info < (3, 9): - import importlib_resources + import importlib_resources # type: ignore[import-not-found] else: import importlib.resources as importlib_resources from abc import ABC diff --git a/litestar/connection/request.py b/litestar/connection/request.py index 162664eede..ee2d264c6f 100644 --- a/litestar/connection/request.py +++ b/litestar/connection/request.py @@ -119,9 +119,9 @@ async def msgpack(self) -> Any: """ if self._msgpack is Empty: body = await self.body() - self._msgpack = self.scope["_msgpack"] = decode_msgpack( + self._msgpack = self.scope["_msgpack"] = decode_msgpack( # type: ignore[typeddict-unknown-key] body or b"\xc0", type_decoders=self.route_handler.resolve_type_decoders() - ) # type: ignore[typeddict-unknown-key] + ) return self._msgpack async def stream(self) -> AsyncGenerator[bytes, None]: diff --git a/litestar/handlers/http_handlers/base.py b/litestar/handlers/http_handlers/base.py index 85358a9e70..0d77f889e5 100644 --- a/litestar/handlers/http_handlers/base.py +++ b/litestar/handlers/http_handlers/base.py @@ -423,9 +423,9 @@ def get_response_handler(self, is_response_type_data: bool = False) -> Callable[ """ if self._response_handler_mapping["default_handler"] is Empty: after_request_handlers: list[AsyncCallable] = [ - layer.after_request + layer.after_request # type: ignore[misc] for layer in self.ownership_layers - if layer.after_request # type: ignore[misc] + if layer.after_request ] after_request = cast( "AfterRequestHookHandler | None", diff --git a/litestar/serialization/msgspec_hooks.py b/litestar/serialization/msgspec_hooks.py index 837c72a66c..29dd29558d 100644 --- a/litestar/serialization/msgspec_hooks.py +++ b/litestar/serialization/msgspec_hooks.py @@ -232,9 +232,11 @@ def decode_msgpack(value: bytes, target_type: type[T], type_decoders: TypeDecode ... -def decode_msgpack( - value: bytes, target_type: type[T] | EmptyType = Empty, type_decoders: TypeDecodersSequence | None = None -) -> Any: # type: ignore[misc] +def decode_msgpack( # type: ignore[misc] + value: bytes, + target_type: type[T] | EmptyType = Empty, + type_decoders: TypeDecodersSequence | None = None, +) -> Any: """Decode a MessagePack string/bytes into an object. Args: diff --git a/litestar/testing/request_factory.py b/litestar/testing/request_factory.py index 1c2e63082f..6a672aec8f 100644 --- a/litestar/testing/request_factory.py +++ b/litestar/testing/request_factory.py @@ -291,9 +291,9 @@ def _create_request_with_data( if request_media_type == RequestEncodingType.JSON: encoding_headers, stream = httpx_encode_json(data) elif request_media_type == RequestEncodingType.MULTI_PART: - encoding_headers, stream = encode_multipart_data( + encoding_headers, stream = encode_multipart_data( # type: ignore[assignment] cast("dict[str, Any]", data), files=files or [], boundary=None - ) # type: ignore[assignment] + ) else: encoding_headers, stream = encode_urlencoded_data(decode_json(value=encode_json(data))) headers.update(encoding_headers) diff --git a/tests/unit/test_cli/conftest.py b/tests/unit/test_cli/conftest.py index 6cd2f4fb19..5db2c055ee 100644 --- a/tests/unit/test_cli/conftest.py +++ b/tests/unit/test_cli/conftest.py @@ -100,8 +100,8 @@ def _create_app_file( request.addfinalizer(lambda: rmtree(directory)) request.addfinalizer( lambda: _purge_module( - [directory, _path_to_dotted_path(tmp_app_file.relative_to(Path.cwd()))], - tmp_app_file, # type: ignore[list-item] + [directory, _path_to_dotted_path(tmp_app_file.relative_to(Path.cwd()))], # type: ignore[list-item] + tmp_app_file, ) ) else: diff --git a/tests/unit/test_connection/test_request.py b/tests/unit/test_connection/test_request.py index feff10b537..82f9a03141 100644 --- a/tests/unit/test_connection/test_request.py +++ b/tests/unit/test_connection/test_request.py @@ -354,8 +354,10 @@ async def receiver() -> dict: with pytest.raises(InternalServerException): await app( - {"type": "http", "route_handler": _route_handler, "method": "POST", "path": "/"}, receiver, empty_send - ) # type: ignore + {"type": "http", "route_handler": _route_handler, "method": "POST", "path": "/"}, # type: ignore + receiver, + empty_send, + ) def test_request_state() -> None: diff --git a/tests/unit/test_contrib/test_htmx/test_htmx_response.py b/tests/unit/test_contrib/test_htmx/test_htmx_response.py index 91feaefac6..8a7b4e3bcc 100644 --- a/tests/unit/test_contrib/test_htmx/test_htmx_response.py +++ b/tests/unit/test_contrib/test_htmx/test_htmx_response.py @@ -187,8 +187,8 @@ def handler() -> TriggerEvent: return TriggerEvent( content="Success!", name="alert", - after="invalid", - params={"warning": "Confirm your choice!"}, # type: ignore + after="invalid", # type: ignore + params={"warning": "Confirm your choice!"}, ) with create_test_client(route_handlers=[handler], request_class=HTMXRequest) as client: diff --git a/tests/unit/test_handlers/test_asgi_handlers/test_handle_asgi.py b/tests/unit/test_handlers/test_asgi_handlers/test_handle_asgi.py index 2e92b91acd..84d9320c98 100644 --- a/tests/unit/test_handlers/test_asgi_handlers/test_handle_asgi.py +++ b/tests/unit/test_handlers/test_asgi_handlers/test_handle_asgi.py @@ -41,8 +41,8 @@ class MyController(Controller): @asgi(signature_namespace={"c": Send}) async def root_asgi_handler( self, - scope: "a", # noqa: F821 - receive: "b", # noqa: F821 + scope: "a", # type:ignore[name-defined] # noqa: F821 + receive: "b", # type:ignore[name-defined] # noqa: F821 send: "c", # type:ignore[name-defined] # noqa: F821 ) -> None: await ASGIResponse(body=scope["path"].encode(), media_type=MediaType.TEXT)(scope, receive, send) diff --git a/tests/unit/test_handlers/test_http_handlers/test_signature_namespace.py b/tests/unit/test_handlers/test_http_handlers/test_signature_namespace.py index c9edb0497f..eff63bf2b0 100644 --- a/tests/unit/test_handlers/test_http_handlers/test_signature_namespace.py +++ b/tests/unit/test_handlers/test_http_handlers/test_signature_namespace.py @@ -19,9 +19,9 @@ class MyController(Controller): @decorator(path="/", signature_namespace={"d": List[str], "dict": Dict}, status_code=200) # type:ignore[misc] async def simple_handler( self, - a: a, # noqa: F821 - b: b, # noqa: F821 - c: c, # noqa: F821 + a: a, # type:ignore[name-defined] # noqa: F821 + b: b, # type:ignore[name-defined] # noqa: F821 + c: c, # type:ignore[name-defined] # noqa: F821 d: d, # type:ignore[name-defined] # noqa: F821 ) -> dict[str, Any]: return {"a": a, "b": b, "c": c, "d": d} diff --git a/tests/unit/test_handlers/test_websocket_handlers/test_handle_websocket.py b/tests/unit/test_handlers/test_websocket_handlers/test_handle_websocket.py index 704653cd7e..da4175158e 100644 --- a/tests/unit/test_handlers/test_websocket_handlers/test_handle_websocket.py +++ b/tests/unit/test_handlers/test_websocket_handlers/test_handle_websocket.py @@ -30,9 +30,9 @@ class MyController(Controller): async def simple_websocket_handler( self, socket: WebSocket, - a: "a", # noqa: F821 - b: "b", # noqa: F821 - c: "c", # noqa: F821 + a: "a", # type:ignore[name-defined] # noqa: F821 + b: "b", # type:ignore[name-defined] # noqa: F821 + c: "c", # type:ignore[name-defined] # noqa: F821 d: "d", # type:ignore[name-defined] # noqa: F821 ) -> None: await socket.accept() From 4031f6801d547c1d3614a96c76f59bbfe8fdd891 Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Thu, 26 Oct 2023 22:25:44 -0500 Subject: [PATCH 4/7] ci(mypy): make mypy happy.. maybe --- Makefile | 6 ++++++ litestar/_asgi/routing_trie/mapping.py | 4 ++-- litestar/connection/request.py | 8 ++++---- litestar/handlers/http_handlers/base.py | 8 ++++---- tests/helpers.py | 4 ++-- tests/unit/test_connection/test_request.py | 4 ++-- 6 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 910042b129..0828d697bf 100644 --- a/Makefile +++ b/Makefile @@ -80,6 +80,12 @@ mypy: ## Run mypy @$(ENV_PREFIX)dmypy run @echo "=> mypy complete" +.PHONY: mypy-nocache +mypy-nocache: ## Run Mypy without cache + @echo "=> Running mypy without a cache" + @$(ENV_PREFIX)dmypy run -- --cache-dir=/dev/null + @echo "=> mypy complete" + .PHONY: pyright pyright: ## Run pyright @echo "=> Running pyright" diff --git a/litestar/_asgi/routing_trie/mapping.py b/litestar/_asgi/routing_trie/mapping.py index 96095c0895..8ef4a27c56 100644 --- a/litestar/_asgi/routing_trie/mapping.py +++ b/litestar/_asgi/routing_trie/mapping.py @@ -190,8 +190,8 @@ def build_route_middleware_stack( from litestar.routes import HTTPRoute # we wrap the route.handle method in the ExceptionHandlerMiddleware - asgi_handler = wrap_in_exception_handler( # type: ignore[arg-type] - app=route.handle, + asgi_handler = wrap_in_exception_handler( + app=route.handle, # type: ignore[arg-type] exception_handlers=route_handler.resolve_exception_handlers(), ) diff --git a/litestar/connection/request.py b/litestar/connection/request.py index ee2d264c6f..6f22b8d342 100644 --- a/litestar/connection/request.py +++ b/litestar/connection/request.py @@ -82,9 +82,9 @@ def content_type(self) -> tuple[str, dict[str, str]]: A tuple with the parsed value and a dictionary containing any options send in it. """ if self._content_type is Empty: - self._content_type = self.scope["_content_type"] = parse_content_header( + self._content_type = self.scope["_content_type"] = parse_content_header( # type: ignore[typeddict-unknown-key] self.headers.get("Content-Type", "") - ) # type: ignore[typeddict-unknown-key] + ) return cast("tuple[str, dict[str, str]]", self._content_type) @property @@ -106,9 +106,9 @@ async def json(self) -> Any: """ if self._json is Empty: body = await self.body() - self._json = self.scope["_json"] = decode_json( + self._json = self.scope["_json"] = decode_json( # type: ignore[typeddict-unknown-key] body or b"null", type_decoders=self.route_handler.resolve_type_decoders() - ) # type: ignore[typeddict-unknown-key] + ) return self._json async def msgpack(self) -> Any: diff --git a/litestar/handlers/http_handlers/base.py b/litestar/handlers/http_handlers/base.py index 0d77f889e5..f4b12ee9c8 100644 --- a/litestar/handlers/http_handlers/base.py +++ b/litestar/handlers/http_handlers/base.py @@ -367,9 +367,9 @@ def resolve_before_request(self) -> AsyncCallable | None: """ if self._resolved_before_request is Empty: before_request_handlers: list[AsyncCallable] = [ - layer.before_request + layer.before_request # type: ignore[misc] for layer in self.ownership_layers - if layer.before_request # type: ignore[misc] + if layer.before_request ] self._resolved_before_request = before_request_handlers[-1] if before_request_handlers else None return cast("AsyncCallable | None", self._resolved_before_request) @@ -385,9 +385,9 @@ def resolve_after_response(self) -> AsyncCallable | None: """ if self._resolved_after_response is Empty: after_response_handlers: list[AsyncCallable] = [ - layer.after_response + layer.after_response # type: ignore[misc] for layer in self.ownership_layers - if layer.after_response # type: ignore[misc] + if layer.after_response ] self._resolved_after_response = after_response_handlers[-1] if after_response_handlers else None diff --git a/tests/helpers.py b/tests/helpers.py index 2820aa68ed..21c78b6fb9 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -58,6 +58,6 @@ def get_exception_group() -> type[BaseException]: try: return cast("type[BaseException]", ExceptionGroup) # type:ignore[name-defined] except NameError: - from exceptiongroup import ExceptionGroup as _ExceptionGroup + from exceptiongroup import ExceptionGroup as _ExceptionGroup # type: ignore[import-not-found] - return _ExceptionGroup + return _ExceptionGroup # type: ignore[no-any-return] diff --git a/tests/unit/test_connection/test_request.py b/tests/unit/test_connection/test_request.py index 82f9a03141..35f34d0d26 100644 --- a/tests/unit/test_connection/test_request.py +++ b/tests/unit/test_connection/test_request.py @@ -354,8 +354,8 @@ async def receiver() -> dict: with pytest.raises(InternalServerException): await app( - {"type": "http", "route_handler": _route_handler, "method": "POST", "path": "/"}, # type: ignore - receiver, + {"type": "http", "route_handler": _route_handler, "method": "POST", "path": "/"}, # type: ignore[arg-type] + receiver, # type: ignore[arg-type] empty_send, ) From 58f71127f2455c82830aa993fa07887c7343a0a9 Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Thu, 26 Oct 2023 22:28:35 -0500 Subject: [PATCH 5/7] ci(mypy): make mypy happy.. for real this time --- litestar/channels/backends/redis.py | 2 +- tests/helpers.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/litestar/channels/backends/redis.py b/litestar/channels/backends/redis.py index 3ce4c26025..c84c061c88 100644 --- a/litestar/channels/backends/redis.py +++ b/litestar/channels/backends/redis.py @@ -4,7 +4,7 @@ import sys if sys.version_info < (3, 9): - import importlib_resources # type: ignore[import-not-found] + import importlib_resources else: import importlib.resources as importlib_resources from abc import ABC diff --git a/tests/helpers.py b/tests/helpers.py index 21c78b6fb9..2820aa68ed 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -58,6 +58,6 @@ def get_exception_group() -> type[BaseException]: try: return cast("type[BaseException]", ExceptionGroup) # type:ignore[name-defined] except NameError: - from exceptiongroup import ExceptionGroup as _ExceptionGroup # type: ignore[import-not-found] + from exceptiongroup import ExceptionGroup as _ExceptionGroup - return _ExceptionGroup # type: ignore[no-any-return] + return _ExceptionGroup From 29f79f81b175886df4541a5e3d1dbea746a99e7f Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Thu, 26 Oct 2023 22:39:15 -0500 Subject: [PATCH 6/7] ci(mypy): make pyright happy --- litestar/serialization/msgspec_hooks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/litestar/serialization/msgspec_hooks.py b/litestar/serialization/msgspec_hooks.py index 29dd29558d..b13dfb79e8 100644 --- a/litestar/serialization/msgspec_hooks.py +++ b/litestar/serialization/msgspec_hooks.py @@ -234,7 +234,7 @@ def decode_msgpack(value: bytes, target_type: type[T], type_decoders: TypeDecode def decode_msgpack( # type: ignore[misc] value: bytes, - target_type: type[T] | EmptyType = Empty, + target_type: type[T] | EmptyType = Empty, # pyright: ignore type_decoders: TypeDecodersSequence | None = None, ) -> Any: """Decode a MessagePack string/bytes into an object. From cab54f0f261fcd80e4b92bf0ebd8f82874880559 Mon Sep 17 00:00:00 2001 From: Jacob Coffee Date: Fri, 3 Nov 2023 21:14:00 -0500 Subject: [PATCH 7/7] chore: rebase on main --- .pre-commit-config.yaml | 4 ++-- litestar/contrib/pydantic/pydantic_dto_factory.py | 3 ++- litestar/contrib/pydantic/pydantic_schema_plugin.py | 8 ++------ litestar/types/serialization.py | 4 +--- pyproject.toml | 1 + tests/unit/test_contrib/test_pydantic/test_openapi.py | 5 ++++- 6 files changed, 12 insertions(+), 13 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7e4c1e5d81..4d8ad99a88 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,7 +23,7 @@ repos: - id: unasyncd additional_dependencies: ["ruff"] - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: "v0.1.3" + rev: "v0.1.4" hooks: - id: ruff args: ["--fix"] @@ -51,7 +51,7 @@ repos: exclude: "test*|examples*|tools" args: ["--use-tuple"] - repo: https://github.com/ariebovenberg/slotscheck - rev: v0.17.0 + rev: v0.17.1 hooks: - id: slotscheck exclude: "test_*|docs" diff --git a/litestar/contrib/pydantic/pydantic_dto_factory.py b/litestar/contrib/pydantic/pydantic_dto_factory.py index 005f248b3d..72cca5baef 100644 --- a/litestar/contrib/pydantic/pydantic_dto_factory.py +++ b/litestar/contrib/pydantic/pydantic_dto_factory.py @@ -75,7 +75,8 @@ def generate_field_definitions( model_fields = dict(model_type.model_fields) # type: ignore[union-attr] except AttributeError: model_fields = { - k: model_field.field_info for k, model_field in model_type.__fields__.items() # type: ignore[union-attr] + k: model_field.field_info + for k, model_field in model_type.__fields__.items() # type: ignore[union-attr] } for field_name, field_info in model_fields.items(): diff --git a/litestar/contrib/pydantic/pydantic_schema_plugin.py b/litestar/contrib/pydantic/pydantic_schema_plugin.py index 29dab304c1..c17253a22e 100644 --- a/litestar/contrib/pydantic/pydantic_schema_plugin.py +++ b/litestar/contrib/pydantic/pydantic_schema_plugin.py @@ -231,9 +231,7 @@ def to_openapi_schema(self, field_definition: FieldDefinition, schema_creator: S return PYDANTIC_TYPE_MAP[field_definition.annotation] # pragma: no cover @classmethod - def for_pydantic_model( - cls, field_definition: FieldDefinition, schema_creator: SchemaCreator - ) -> Schema: # pyright: ignore + def for_pydantic_model(cls, field_definition: FieldDefinition, schema_creator: SchemaCreator) -> Schema: # pyright: ignore """Create a schema object for a given pydantic model class. Args: @@ -265,9 +263,7 @@ def for_pydantic_model( } field_definitions = { - f.alias - if f.alias and schema_creator.prefer_alias - else k: FieldDefinition.from_kwarg( + f.alias if f.alias and schema_creator.prefer_alias else k: FieldDefinition.from_kwarg( annotation=Annotated[annotation_hints[k], f, f.metadata] # type: ignore[union-attr] if is_v2_model else Annotated[annotation_hints[k], f], # pyright: ignore diff --git a/litestar/types/serialization.py b/litestar/types/serialization.py index 1c2074fe3c..50bb5684a8 100644 --- a/litestar/types/serialization.py +++ b/litestar/types/serialization.py @@ -56,6 +56,4 @@ ) EncodableMsgSpecType: TypeAlias = "Ext | Raw | Struct" LitestarEncodableType: TypeAlias = "EncodableBuiltinType | EncodableBuiltinCollectionType | EncodableStdLibType | EncodableStdLibIPType | EncodableMsgSpecType | BaseModel | AttrsInstance" # pyright: ignore -DataContainerType: TypeAlias = ( - "Struct | BaseModel | AttrsInstance | TypedDictClass | DataclassProtocol" # pyright: ignore -) +DataContainerType: TypeAlias = "Struct | BaseModel | AttrsInstance | TypedDictClass | DataclassProtocol" # pyright: ignore diff --git a/pyproject.toml b/pyproject.toml index 92fccddf68..0d5826d492 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -330,6 +330,7 @@ ignore = [ "E501", # pycodestyle line too long, handled by ruff-fmt "PLW2901", # pylint - for loop variable overwritten by assignment target "RUF012", # Ruff-specific rule - annotated with classvar + "ISC001", # flake8-implicit-str-concat - implicit string concatenation - ruff formatter has issue with this ] line-length = 120 src = ["litestar", "tests", "docs/examples"] diff --git a/tests/unit/test_contrib/test_pydantic/test_openapi.py b/tests/unit/test_contrib/test_pydantic/test_openapi.py index 8ef86544c4..ea079cd76e 100644 --- a/tests/unit/test_contrib/test_pydantic/test_openapi.py +++ b/tests/unit/test_contrib/test_pydantic/test_openapi.py @@ -497,7 +497,10 @@ def handler(data: RequestWithAlias) -> ResponseWithAlias: def test_create_schema_for_field_v1() -> None: class Model(pydantic_v1.BaseModel): value: str = pydantic_v1.Field( - title="title", description="description", example="example", max_length=16 # pyright: ignore + title="title", + description="description", + example="example", + max_length=16, # pyright: ignore ) schemas: Dict[str, Schema] = {}