Skip to content

Bug: DTO: a computed field that returns optional structure causes exception on None (experimental_codegen bug?) #4458

@takeda

Description

@takeda

Description

When using a DTO in connection with a computed field, if the field returns an optional structure, if the result is None litestar produces following error:

TypeError: Missing required argument 'full_error'

Here's trace back:

Traceback (most recent call last):
  File "[...]/lib/python3.12/site-packages/litestar/middleware/_internal/exceptions/middleware.py", line 158, in __call__
    await self.app(scope, receive, capture_response_started)
  File "[...]/lib/python3.12/site-packages/litestar/_asgi/asgi_router.py", line 100, in __call__
    await asgi_app(scope, receive, send)
  File "[...]/lib/python3.12/site-packages/litestar/routes/http.py", line 81, in handle
    response = await self._get_response_for_request(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[...]/lib/python3.12/site-packages/litestar/routes/http.py", line 133, in _get_response_for_request
    return await self._call_handler_function(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[...]/lib/python3.12/site-packages/litestar/routes/http.py", line 184, in _call_handler_function
    return await route_handler.to_response(app=scope["litestar_app"], data=response_data, request=request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[...]/lib/python3.12/site-packages/litestar/handlers/http_handlers/base.py", line 581, in to_response
    data = return_dto_type(request).data_to_encodable_type(data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[...]/lib/python3.12/site-packages/litestar/dto/base_dto.py", line 124, in data_to_encodable_type
    return backend.encode_data(data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[...]/lib/python3.12/site-packages/litestar/dto/_codegen_backend.py", line 153, in encode_data
    return cast("LitestarEncodableType", self._encode_data(data))
                                         ^^^^^^^^^^^^^^^^^^^^^^^
  File "dto_transfer_function_766f5a0d34e2", line 51, in func
    tmp_return_type_0 = destination_type_0(**unstructured_data_0)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Missing required argument 'status'

Disabling experimental_codegen_backend makes the code work as expected.

URL to code causing the issue

No response

MCVE

from typing import Optional

from litestar import Litestar, get
from litestar.dto import DTOConfig
from litestar.logging import LoggingConfig
from litestar.plugins.pydantic import PydanticDTO
from pydantic import BaseModel, computed_field


class Status(BaseModel):
	a: str
	b: str

class Result(BaseModel):
	@computed_field
	@property
	def status(self) -> Optional[Status]:
		return None

class ResultDTO(PydanticDTO[Result]):
	config = DTOConfig(
		include={'status'},
		# experimental_codegen_backend=False,
	)


@get("/", return_dto=ResultDTO)
async def hello() -> Result:
	return Result()

app = Litestar(route_handlers=[hello], logging_config=LoggingConfig(log_exceptions='always'))

Steps to reproduce

  1. start the application
  2. request the root page
  3. see exception in the terminal
  4. uncomment experimental_codegen_backend=False
  5. see code working correctly

Screenshots

No response

Logs


Litestar Version

v2.17.0

Platform

  • Linux
  • Mac
  • Windows
  • Other (Please specify in the description above)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Bug 🐛This is something that is not working as expected

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions