litestar-org / litestar

Production-ready, Light, Flexible and Extensible ASGI API framework | Effortlessly Build Performant APIs
https://litestar.dev/
MIT License
5.64k stars 382 forks source link

Bug: DTOFactory not excluding fields set in `exclude` #1435

Closed Alc-Alc closed 1 year ago

Alc-Alc commented 1 year ago

Description

DTOFactory does not seem to exclude the fields if the returned DTO is optional (NoPassUser | None for this example). The code works fine if the return type is just the DTO (NoPassUser - not optional)

Current Response - password is in the response

{
    "name": "name",
    "password": "password"
}

Expected Response - password should not be in the response

{
    "name": "name"
}

URL to code causing the issue

No response

MCVE

from pydantic import BaseModel
from starlite import Starlite, get
from starlite.dto import DTOFactory
class User(BaseModel):
    name: str = 'name'
    password: str = 'password'
dto_factory = DTOFactory()
NoPassUser = dto_factory('NoPassUser', User, ['password'])
@get()
def route_1() -> NoPassUser | None:
    return User()
app = Starlite([route_1])

Steps to reproduce

Start the app and do `GET: localhost:8000`

Screenshots

No response

Logs

No response

Starlite Version

1.51.7, also seems to happen on 2.0.0a2

Platform

peterschutt commented 1 year ago

Closing as this is the v1 pattern for DTOs.

I believe that returning an optional type from a handler is still not supported with v2 DTOs as they do a check to ensure that the type being returned from the handler is a sub-type of the dto declared data type, and an optional union isn't. LMK if you want to look at that and we can open an issue for it.