Skip to content

Commit bb40c87

Browse files
committed
chore: Prepare release 2.23.0
1 parent 442ed46 commit bb40c87

4 files changed

Lines changed: 117 additions & 4 deletions

File tree

docs/examples/dependency_injection/dependency_skip_validation.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import Any, Dict
22

33
from litestar import Litestar, get
4+
from litestar.di import NamedDependency
45
from litestar.params import SkipValidation
56

67

@@ -10,7 +11,7 @@ async def provide_str() -> str:
1011

1112

1213
@get("/", dependencies={"injected": provide_str})
13-
async def hello_world(injected: SkipValidation[int]) -> Dict[str, Any]:
14+
async def hello_world(injected: NamedDependency[SkipValidation[int]]) -> Dict[str, Any]:
1415
"""Handler expects an `int`, but we've provided a `str`."""
1516
return {"hello": injected}
1617

docs/release-notes/changelog.rst

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,118 @@
33
Litestar 2 Changelog
44
====================
55

6+
.. changelog:: 2.23.0
7+
:date: 2026-05-29
8+
9+
.. change:: Introduce generic request body markers
10+
:type: feature
11+
:pr: 4801
12+
13+
Introduce generic request body markers, following the pattern established
14+
by the enhanced request parameter declarations.
15+
16+
New body marker generics:
17+
18+
- :data:`JSONBody[\<type\>] <litestar.params.JSONBody>`
19+
- :data:`MsgPackBody[\<type\>] <litestar.params.MsgPackBody>`
20+
- :data:`MultipartBody[\<type\>] <litestar.params.MultipartBody>`
21+
- :data:`URLEncodedBody[\<type\>] <litestar.params.URLEncodedBody>`
22+
23+
They can be used just like the request parameter markers, and replace the
24+
more verbose forms of e.g.
25+
``Annotated[T, Body(media_type=RequestEncodingType.MULTI_PART)]`` form:
26+
27+
.. code-block:: python
28+
29+
@post("/")
30+
async def handler(data: Annotated[dict, Body(media_type=RequestEncodingType.MULTI_PART)]) -> None:
31+
pass
32+
33+
can be replaced with
34+
35+
.. code-block:: python
36+
37+
@post("/")
38+
async def handler(data: MultipartBody[dict]) -> None:
39+
pass
40+
41+
**Migrating**
42+
43+
- Replace ``Annotated[T, Body(media_type=RequestEncodingType.JSON)]`` with ``JSONBody[T]``
44+
- Replace ``Annotated[T, Body(media_type=RequestEncodingType.MESSAGEPACK)]`` with ``MsgPackBody[T]``
45+
- Replace ``Annotated[T, Body(media_type=RequestEncodingType.MULTI_PART)]`` with ``MultipartBody[T]``
46+
- Replace ``Annotated[T, Body(media_type=RequestEncodingType.URL_ENCODED)]`` with ``URLEncodedBody[T]``
47+
48+
.. change:: Deprecate ``params.Dependency``, introduce ``di.NamedDependency`` and ``params.SkipValidation``
49+
:type: feature
50+
:pr: 4808
51+
52+
Add a new ``NamedDependency`` marker, completing the move to generic parameter
53+
markers to indicate the value source.
54+
55+
``NamedDependency`` is also a preparation for the overhauled DI that will be
56+
introduced in version 3, which supports type-based DI alongside the current
57+
name-based DI, and will feature its counterpart ``TypeDependency``.
58+
59+
- Add :data:`di.NamedDependency <litestar.di.NamedDependency>` generic,
60+
replacing ``Annotated[<type>, Dependency()]`` as a marker
61+
- Deprecate ``params.Dependency``
62+
- Introduce :data:`params.SkipValidation <litestar.params.SkipValidation>`
63+
generic. ``Dependency(skip_validation=True)`` can be cleanly migrated to
64+
this. In addition, ``SkipValidation`` works on all parameters, not just
65+
dependencies.
66+
67+
**Migration**
68+
69+
- Replace ``foo: int = Dependency()`` with ``foo: NamedDependency[int]``
70+
- Replace ``foo: Annotated[int, Dependency(default=1)]`` by hoisting the
71+
default into the parameter default: ``foo: NamedDependency[int] = 1``
72+
- Replace ``foo: Annotated[int, Dependency(skip_validation=True)`` with
73+
``foo: NamedDependency[SkipValidation[int]]``
74+
75+
.. change:: Reject invalid host headers
76+
:type: feature
77+
:pr: 4813
78+
79+
Abort requests with a ``400 - Bad Request`` if a malformed ``Host`` header is
80+
sent.
81+
82+
.. important::
83+
This change was prompted by https://github.com/Kludex/starlette/security/advisories/GHSA-86qp-5c8j-p5mr
84+
However, Litestar does *not* share this vulnerability, as the ``Host``
85+
header was not used to reconstruct the URL
86+
87+
.. change:: Fix ``Annotated`` parameters implicitly treated as query parameters
88+
:type: bugfix
89+
:pr: 4805
90+
:issue: 4804
91+
92+
Fix a regression introduced in ``2.22.0`` that would cause bare handler
93+
parameters wrapped in ``Annotated`` and not explicitly marked with the new
94+
parameter markers (:data:`~litestar.params.FromQuery` etc.) to be treated as a
95+
query parameter, causing validation issues.
96+
97+
.. change:: Handle ``Annotated`` metadata in ``Optional[Literal[...]]`` schemas
98+
:type: bugfix
99+
:pr: 4814
100+
101+
``Optional[Annotated[Literal[...], Meta(...)]]`` raised a ``KeyError`` during
102+
schema generation because ``make_non_optional_union`` preserves the
103+
``Annotated`` wrapper, and ``_iter_flat_literal_args`` then iterated the PEP
104+
593 metadata as if it were a literal value. Wrapper annotations are now
105+
stripped at the top of ``_iter_flat_literal_args`` so the function is robust
106+
regardless of where it is entered from.
107+
108+
.. change:: Propagate ``msgspec.Meta`` on ``Optional[Annotated[...]]`` struct fields
109+
:type: bugfix
110+
:pr: 4815
111+
:issue: 4650
112+
113+
Fix a bug that would cause metadata from a ``msgspec.Meta`` placed inside an
114+
``Optional`` on a ``Struct`` field - ``Optional[Annotated[T, Meta(...)]]`` - to
115+
be silently dropped from the generated OpenAPI schema.
116+
117+
6118
.. changelog:: 2.22.0
7119
:date: 2026-05-20
8120

@@ -6800,4 +6912,4 @@ Litestar 2 Changelog
68006912
:issue: 1149
68016913

68026914
A middleware's ``exclude`` parameter would sometimes not be honoured if the path was used to serve static files
6803-
using ``StaticFilesConfig``
6915+
using ``StaticFilesConfig``

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ maintainers = [
6565
name = "litestar"
6666
readme = "docs/PYPI_README.md"
6767
requires-python = ">=3.8,<4.0"
68-
version = "2.22.0"
68+
version = "2.23.0"
6969

7070
[project.urls]
7171
Blog = "https://blog.litestar.dev"

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)