Skip to content

Commit 69a1ad9

Browse files
Peopl3sаппаап
andauthored
fix(dto/msgspec_dto): Fix KeyError when ClassVar exists on msgspec dto struct (#4669)
Co-authored-by: аппаап <email@example.com>
1 parent 1a133ca commit 69a1ad9

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

docs/release-notes/changelog.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,3 +362,9 @@
362362
Add a new attribute :attr:`~litestar.middleware.ASGIMiddleware.should_bypass_for_scope`;
363363
A callable which takes in a :class:`~litestar.types.Scope` and returns a boolean
364364
to indicate whether to bypass the middleware for the current request.
365+
366+
.. change:: Fix KeyError when ClassVar exists on msgspec Struct
367+
:type: bugfix
368+
:pr: 4665
369+
370+
Fix a bug in :class:`MsgspecDTO` where a KeyError was raised if a :class:`msgspec.Struct` contained a :class:`~typing.ClassVar`. ClassVars are now correctly skipped when generating field definitions.

litestar/dto/msgspec_dto.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ def generate_field_definitions(cls, model_type: type[Struct]) -> Generator[DTOFi
4848
property_fields = cls.get_property_fields(model_type)
4949

5050
for key, field_definition in cls.get_model_type_hints(model_type).items():
51+
if key not in inspect_fields:
52+
continue
5153
kwarg_definition, extra = kwarg_definition_from_field(inspect_fields[key])
5254
field_definition = dataclasses.replace(field_definition, kwarg_definition=kwarg_definition)
5355
field_definition.extra.update(extra)

tests/unit/test_contrib/test_msgspec.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import itertools
44
from dataclasses import replace
5-
from typing import TYPE_CHECKING, Annotated
5+
from typing import TYPE_CHECKING, Annotated, ClassVar
66
from unittest.mock import ANY
77

88
import pytest
@@ -216,3 +216,15 @@ def handler_3(data: Model3) -> None:
216216
"required": ["foo", "regular_field"],
217217
"title": "Model3",
218218
}
219+
220+
221+
def test_msgspec_dto_with_classvar() -> None:
222+
class ModelWithClassVar(Struct):
223+
regular_field: str
224+
class_field: ClassVar[str] = "a string in the class"
225+
226+
field_defs = list(MsgspecDTO.generate_field_definitions(ModelWithClassVar))
227+
228+
# Only the regular field should be included, not the ClassVar
229+
assert len(field_defs) == 1
230+
assert field_defs[0].name == "regular_field"

0 commit comments

Comments
 (0)