Skip to content

Commit b18cec3

Browse files
authored
chore: upgrade ruff and apply latest linting config (#4115)
1 parent 0d3fc00 commit b18cec3

37 files changed

+227
-168
lines changed

.pre-commit-config.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ default_language_version:
22
python: "3.12"
33
repos:
44
- repo: https://github.com/compilerla/conventional-pre-commit
5-
rev: v3.6.0
5+
rev: v4.0.0
66
hooks:
77
- id: conventional-pre-commit
88
stages: [commit-msg]
@@ -24,13 +24,13 @@ repos:
2424
- id: unasyncd
2525
additional_dependencies: ["ruff"]
2626
- repo: https://github.com/astral-sh/ruff-pre-commit
27-
rev: "v0.8.1"
27+
rev: "v0.11.5"
2828
hooks:
2929
- id: ruff
3030
args: ["--fix"]
3131
- id: ruff-format
3232
- repo: https://github.com/codespell-project/codespell
33-
rev: v2.3.0
33+
rev: v2.4.1
3434
hooks:
3535
- id: codespell
3636
exclude: "tests/openapi/typescript_converter/test_converter|README.md"

docs/_static/favicon.png

7.5 KB
Loading

docs/_static/favicon.svg

+1
Loading

docs/_static/litestar-sphinx-theme.css

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/_static/litestar-theme.js

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
function initDropdowns() {
2+
const dropdownToggles = document.querySelectorAll(".st-dropdown-toggle")
3+
4+
const dropdowns = [...dropdownToggles].map(toggleEl => ({
5+
toggleEl,
6+
contentEL: toggleEl.parentElement.querySelector(".st-dropdown-menu")
7+
}))
8+
9+
const close = (dropdown) => {
10+
const {toggleEl, contentEL} = dropdown
11+
toggleEl.setAttribute("aria-expanded", "false")
12+
contentEL.classList.toggle("hidden", true)
13+
}
14+
15+
const closeAll = () => dropdowns.forEach(close)
16+
17+
const open = (dropdown) => {
18+
closeAll()
19+
dropdown.toggleEl.setAttribute("aria-expanded", "true")
20+
dropdown.contentEL.classList.toggle("hidden", false)
21+
const boundaries = [dropdown.contentEL, ...dropdownToggles]
22+
const clickOutsideListener = (event) => {
23+
const target = event.target
24+
if (!target) return
25+
26+
if (!boundaries.some(b => b.contains(target))) {
27+
closeAll()
28+
document.removeEventListener("click", clickOutsideListener)
29+
}
30+
31+
}
32+
document.addEventListener("click", clickOutsideListener)
33+
}
34+
35+
36+
dropdowns.forEach(dropdown => {
37+
dropdown.toggleEl.addEventListener("click", () => {
38+
if (dropdown.toggleEl.getAttribute("aria-expanded") === "true") {
39+
close(dropdown)
40+
} else {
41+
open(dropdown)
42+
}
43+
})
44+
})
45+
}
46+
47+
window.addEventListener("DOMContentLoaded", () => {
48+
initDropdowns()
49+
})

docs/_static/logo-dark.png

157 KB
Loading

docs/_static/logo-light.png

155 KB
Loading

litestar/_openapi/schema_generation/constrained_fields.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def create_string_constrained_field_schema(
8080
schema.max_length = kwarg_definition.max_length
8181
if kwarg_definition.pattern:
8282
schema.pattern = (
83-
kwarg_definition.pattern.pattern # type: ignore[attr-defined]
83+
kwarg_definition.pattern.pattern
8484
if isinstance(kwarg_definition.pattern, Pattern) # type: ignore[unreachable]
8585
else kwarg_definition.pattern
8686
)

litestar/_openapi/schema_generation/schema.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ def for_constrained_field(self, field: FieldDefinition) -> Schema:
499499
Returns:
500500
A schema instance.
501501
"""
502-
kwarg_definition = cast(Union[ParameterKwarg, BodyKwarg], field.kwarg_definition)
502+
kwarg_definition = cast("Union[ParameterKwarg, BodyKwarg]", field.kwarg_definition)
503503
if any(is_class_and_subclass(field.annotation, t) for t in (int, float, Decimal)):
504504
return create_numerical_constrained_field_schema(field.annotation, kwarg_definition)
505505
if any(is_class_and_subclass(field.annotation, t) for t in (str, bytes)):
@@ -518,7 +518,7 @@ def for_collection_constrained_field(self, field_definition: FieldDefinition) ->
518518
A schema instance.
519519
"""
520520
schema = Schema(type=OpenAPIType.ARRAY)
521-
kwarg_definition = cast(Union[ParameterKwarg, BodyKwarg], field_definition.kwarg_definition)
521+
kwarg_definition = cast("Union[ParameterKwarg, BodyKwarg]", field_definition.kwarg_definition)
522522
if kwarg_definition.min_items:
523523
schema.min_items = kwarg_definition.min_items
524524
if kwarg_definition.max_items:

litestar/_signature/model.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,9 @@ def _build_error_message(cls, keys: Sequence[str], exc_msg: str, connection: ASG
158158
message["source"] = ParamType.PATH
159159

160160
elif key in cls._fields and isinstance(cls._fields[key].kwarg_definition, ParameterKwarg):
161-
if cast(ParameterKwarg, cls._fields[key].kwarg_definition).cookie:
161+
if cast("ParameterKwarg", cls._fields[key].kwarg_definition).cookie:
162162
message["source"] = ParamType.COOKIE
163-
elif cast(ParameterKwarg, cls._fields[key].kwarg_definition).header:
163+
elif cast("ParameterKwarg", cls._fields[key].kwarg_definition).header:
164164
message["source"] = ParamType.HEADER
165165
else:
166166
message["source"] = ParamType.QUERY

litestar/cli/commands/core.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ def _handle_http_route(self, route: HTTPRoute) -> None:
360360
else:
361361
handler_info.append("[yellow]sync[/yellow]")
362362

363-
handler_info.append(f'[cyan]{", ".join(sorted(handler.http_methods))}[/cyan]')
363+
handler_info.append(f"[cyan]{', '.join(sorted(handler.http_methods))}[/cyan]")
364364

365365
if len(handler.paths) > 1:
366366
for path in handler.paths:

litestar/contrib/htmx/_utils.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from litestar.utils import warn_deprecation
66

77
if TYPE_CHECKING:
8-
from litestar_htmx._utils import ( # noqa: TC004
8+
from litestar_htmx._utils import (
99
HTMXHeaders,
1010
get_headers,
1111
get_location_headers,

litestar/contrib/htmx/request.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from litestar.utils import warn_deprecation
66

77
if TYPE_CHECKING:
8-
from litestar_htmx import ( # noqa: TC004
8+
from litestar_htmx import (
99
HTMXDetails,
1010
HTMXRequest,
1111
)

litestar/contrib/htmx/response.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from litestar.utils import warn_deprecation
66

77
if TYPE_CHECKING:
8-
from litestar_htmx import ( # noqa: TC004
8+
from litestar_htmx import (
99
ClientRedirect,
1010
ClientRefresh,
1111
HTMXTemplate,

litestar/contrib/htmx/types.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from litestar.utils import warn_deprecation
66

77
if TYPE_CHECKING:
8-
from litestar_htmx import HtmxHeaderType, LocationType, TriggerEventType # noqa: TC004
8+
from litestar_htmx import HtmxHeaderType, LocationType, TriggerEventType
99
__all__ = (
1010
"HtmxHeaderType",
1111
"LocationType",

litestar/contrib/minijinja.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ def from_environment(cls, minijinja_environment: Environment) -> MiniJinjaTempla
206206
@pass_state
207207
def _minijinja_from_state(func: Callable, state: StateProtocol, *args: Any, **kwargs: Any) -> str: # pragma: no cover
208208
template_context = {"request": state.lookup("request"), "csrf_input": state.lookup("csrf_input")}
209-
return cast(str, func(template_context, *args, **kwargs))
209+
return cast("str", func(template_context, *args, **kwargs))
210210

211211

212212
def __getattr__(name: str) -> Any:

litestar/contrib/piccolo.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def _parse_piccolo_type(column: Column, extra: dict[str, Any]) -> FieldDefinitio
5151
if is_optional:
5252
meta = Meta(extra=extra)
5353
warnings.warn(
54-
f"Dropping max_length constraint for column {column!r} because the " "column is optional",
54+
f"Dropping max_length constraint for column {column!r} because the column is optional",
5555
category=LitestarWarning,
5656
stacklevel=2,
5757
)

litestar/datastructures/headers.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ def _encode_headers(headers: Iterable[tuple[str, str]]) -> "RawHeadersList":
4343
return [(key.lower().encode("latin-1"), value.encode("latin-1")) for key, value in headers]
4444

4545

46-
class Headers(CIMultiDictProxy[str], MultiMixin[str]):
46+
class Headers(CIMultiDictProxy[str], MultiMixin[str]): # pyright: ignore
4747
"""An immutable, case-insensitive multi dict for HTTP headers."""
4848

49-
def __init__(self, headers: Optional[Union[Mapping[str, str], "RawHeaders", MultiMapping]] = None) -> None:
49+
def __init__(self, headers: Optional[Union[Mapping[str, str], "RawHeaders", MultiMapping]] = None) -> None: # pyright: ignore
5050
"""Initialize ``Headers``.
5151
5252
Args:

litestar/datastructures/multi_dicts.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,17 @@ def multi_items(self) -> Generator[tuple[str, T], None, None]:
4242
yield key, value
4343

4444

45-
class MultiDict(BaseMultiDict[T], MultiMixin[T], Generic[T]):
45+
class MultiDict(BaseMultiDict[T], MultiMixin[T], Generic[T]): # pyright: ignore
4646
"""MultiDict, using :class:`MultiDict <multidict.MultiDictProxy>`."""
4747

48-
def __init__(self, args: MultiMapping | Mapping[str, T] | Iterable[tuple[str, T]] | None = None) -> None:
48+
def __init__(self, args: MultiMapping | Mapping[str, T] | Iterable[tuple[str, T]] | None = None) -> None: # pyright: ignore
4949
"""Initialize ``MultiDict`` from a`MultiMapping``,
5050
:class:`Mapping <typing.Mapping>` or an iterable of tuples.
5151
5252
Args:
5353
args: Mapping-like structure to create the ``MultiDict`` from
5454
"""
55-
super().__init__(args or {})
55+
super().__init__(args or {}) # pyright: ignore
5656

5757
def immutable(self) -> ImmutableMultiDict[T]:
5858
"""Create an.
@@ -69,17 +69,17 @@ def copy(self) -> Self:
6969
return type(self)(list(self.multi_items()))
7070

7171

72-
class ImmutableMultiDict(MultiDictProxy[T], MultiMixin[T], Generic[T]):
72+
class ImmutableMultiDict(MultiDictProxy[T], MultiMixin[T], Generic[T]): # pyright: ignore
7373
"""Immutable MultiDict, using class:`MultiDictProxy <multidict.MultiDictProxy>`."""
7474

75-
def __init__(self, args: MultiMapping | Mapping[str, Any] | Iterable[tuple[str, Any]] | None = None) -> None:
75+
def __init__(self, args: MultiMapping | Mapping[str, Any] | Iterable[tuple[str, Any]] | None = None) -> None: # pyright: ignore
7676
"""Initialize ``ImmutableMultiDict`` from a `MultiMapping``,
7777
:class:`Mapping <typing.Mapping>` or an iterable of tuples.
7878
7979
Args:
8080
args: Mapping-like structure to create the ``ImmutableMultiDict`` from
8181
"""
82-
super().__init__(BaseMultiDict(args or {}))
82+
super().__init__(BaseMultiDict(args or {})) # pyright: ignore
8383

8484
def mutable_copy(self) -> MultiDict[T]:
8585
"""Create a mutable copy as a :class:`MultiDict`
@@ -112,10 +112,10 @@ def from_form_data(cls, form_data: dict[str, list[str] | str | UploadFile]) -> F
112112
items = []
113113
for k, v in form_data.items():
114114
if not isinstance(v, list):
115-
items.append((k, v))
115+
items.append((k, v)) # pyright: ignore
116116
else:
117117
for sv in v:
118-
items.append((k, sv))
118+
items.append((k, sv)) # pyright: ignore
119119
return cls(items)
120120

121121
async def close(self) -> None:

litestar/file_system.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from __future__ import annotations
22

33
import abc
4-
import io
54
import os
65
import os.path
76
import pathlib
@@ -29,6 +28,7 @@
2928
)
3029

3130
if TYPE_CHECKING:
31+
import io
3232
from collections.abc import AsyncGenerator, Awaitable, Mapping
3333

3434
from fsspec import AbstractFileSystem as FsspecFileSystem
@@ -294,7 +294,7 @@ async def iter(
294294
end: Offset to stop reading at (inclusive)
295295
"""
296296

297-
fh = cast(io.BytesIO, await sync_to_thread(self.wrapped_fs.open, str(path), mode="rb"))
297+
fh = cast("io.BytesIO", await sync_to_thread(self.wrapped_fs.open, str(path), mode="rb"))
298298
try:
299299
if start != 0:
300300
await sync_to_thread(fh.seek, start)
@@ -358,7 +358,7 @@ async def read_bytes(
358358
end: Offset to stop reading at (inclusive)
359359
"""
360360
return cast(
361-
bytes,
361+
"bytes",
362362
await self.wrapped_fs._cat_file(
363363
str(path),
364364
start=start or None,
@@ -425,7 +425,7 @@ def maybe_wrap_fsspec_file_system(file_system: AnyFileSystem) -> BaseFileSystem:
425425
from fsspec import AbstractFileSystem
426426
from fsspec.asyn import AsyncFileSystem
427427
except ImportError:
428-
return cast(BaseFileSystem, file_system)
428+
return cast("BaseFileSystem", file_system)
429429

430430
if isinstance(file_system, AsyncFileSystem):
431431
return FsspecAsyncWrapper(file_system)

litestar/handlers/base.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from litestar.di import Provide
99
from litestar.dto import DTOData
1010
from litestar.exceptions import ImproperlyConfiguredException, LitestarException
11-
from litestar.router import Router
1211
from litestar.serialization import default_deserializer, default_serializer
1312
from litestar.types import (
1413
Dependencies,
@@ -36,6 +35,7 @@
3635
from litestar.app import Litestar
3736
from litestar.connection import ASGIConnection
3837
from litestar.dto import AbstractDTO
38+
from litestar.router import Router
3939
from litestar.routes import BaseRoute
4040
from litestar.types import AsyncAnyCallable
4141
from litestar.types.callable_types import AnyCallable, AsyncGuard
@@ -207,7 +207,7 @@ def _get_merge_opts(self, others: tuple[Router, ...]) -> dict[str, Any]:
207207
# whereas '.dto' on the handler is the fully resolved dto. The dto config on
208208
# the handler is stored under '._dto', so we have to do this little workaround
209209
if other is not self:
210-
other = cast(Router, other) # mypy cannot narrow with the 'is not self' check
210+
other = cast("Router", other) # mypy cannot narrow with the 'is not self' check
211211
merge_opts["dto"] = value_or_default(merge_opts.get("dto", Empty), other.dto)
212212
merge_opts["return_dto"] = value_or_default(merge_opts.get("return_dto", Empty), other.return_dto)
213213

litestar/handlers/http_handlers/base.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from __future__ import annotations
22

3-
from collections.abc import Awaitable, Iterable, Mapping, Sequence
43
from enum import Enum
54
from typing import TYPE_CHECKING, AnyStr, Callable, TypedDict, cast
65

@@ -60,6 +59,7 @@
6059
from litestar.utils.warnings import warn_implicit_sync_to_thread, warn_sync_to_thread_with_async_callable
6160

6261
if TYPE_CHECKING:
62+
from collections.abc import Awaitable, Iterable, Mapping, Sequence
6363
from typing import Any
6464

6565
from litestar import Litestar, Router
@@ -593,7 +593,11 @@ def _validate_handler_function(self) -> None:
593593
raise ImproperlyConfiguredException("'data' kwarg is unsupported for 'GET' request handlers")
594594

595595
if self.http_methods == {HttpMethod.HEAD} and not self.parsed_fn_signature.return_type.is_subclass_of(
596-
(NoneType, File, ASGIFileResponse)
596+
(
597+
NoneType,
598+
File,
599+
ASGIFileResponse,
600+
)
597601
):
598602
field_definition = self.parsed_fn_signature.return_type
599603
if not (
@@ -792,7 +796,7 @@ async def to_response(self, data: Any, request: Request) -> ASGIApp:
792796
data = return_dto_type(request).data_to_encodable_type(data)
793797

794798
handler = cast(
795-
Callable[..., Awaitable[ASGIApp]],
799+
"Callable[..., Awaitable[ASGIApp]]",
796800
self._response_type_handler if isinstance(data, Response) else self._default_response_handler,
797801
)
798802

litestar/handlers/websocket_handlers/stream.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ def on_registration(self, route: BaseRoute, app: Litestar) -> None:
230230
# be a reference to the unbound method. The bound method is patched in later
231231
# after the controller has been initialized. This is a workaround that should
232232
# go away with v3.0's static handlers
233-
stream_fn = cast(Callable[..., AsyncGenerator[Any, Any]], self.fn)
233+
stream_fn = cast("Callable[..., AsyncGenerator[Any, Any]]", self.fn)
234234

235235
# construct a fake signature for the kwargs modelling, using the generator
236236
# function passed to the handler as a base, to include all the dependencies,

litestar/plugins/base.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,10 @@ def get(self, type_: type[PluginT] | str) -> PluginT:
323323
else plugin.__class__.__qualname__
324324
)
325325
if type_ in {_name, _qualname}:
326-
return cast(PluginT, plugin)
326+
return cast("PluginT", plugin)
327327
raise KeyError(f"No plugin of type {type_!r} registered")
328328
try:
329-
return cast(PluginT, self._plugins_by_type[type_]) # type: ignore[index]
329+
return cast("PluginT", self._plugins_by_type[type_]) # type: ignore[index]
330330
except KeyError as e:
331331
raise KeyError(f"No plugin of type {type_.__name__!r} registered") from e
332332

litestar/plugins/pydantic/plugins/di.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ def get_typed_init(self, type_: Any) -> tuple[Signature, dict[str, Any]]:
2222
inspect.Parameter(name=field_name, kind=inspect.Parameter.KEYWORD_ONLY, annotation=Any)
2323
for field_name in model_fields
2424
]
25-
type_hints = {field_name: Any for field_name in model_fields}
25+
type_hints = dict.fromkeys(model_fields, Any)
2626
return Signature(parameters), type_hints

0 commit comments

Comments
 (0)