litestar-org/polyfactory

Bug: Using a bound generic type with msgspec DTO fails to decode

abdulhaq-e opened this issue · 1 comments

Description

Please see the MCVE and note the two possible ways to circumvent this. I'm not sure if this is expected behaviour. Regardless, the test failure happens at the assertion. The actual logic doesn't throw and silently returns: b'{"age":10,"data":{}} which it shouldn't do silently imo.

URL to code causing the issue

No response

MCVE

def test_dto_with_msgspec_and_generic_inherited_models(create_module: Callable[[str], ModuleType]) -> None:
    module = create_module(
        """
from typing import Dict, Generic, TypeVar
from typing_extensions import Annotated

from litestar import Litestar, post
from litestar.dto.factory import DTOConfig
from litestar.contrib.msgspec import MsgspecDTO

from msgspec import Struct

T = TypeVar("T", bound=Struct) # removing the bound argument solves the issue

class ClassicNameStyle(Struct):
    first_name: str
    surname: str

class User(Struct, Generic[T]):
    age: int
    data: T

class Superuser(User[ClassicNameStyle]):
    # uncommenting the line below also solves the issue (while keeping bound)
    # data: ClassicNameStyle 
    pass

class SuperUserDTO(MsgspecDTO[Superuser]):
    pass

@post(dto=SuperUserDTO)
def handler(data: Superuser) -> Superuser:
    return data

app = Litestar(route_handlers=[handler])
"""
    )
    with TestClient(app=module.app) as client:
        data = module.Superuser(data=module.ClassicNameStyle(first_name="A", surname="B"), age=10)
        headers = dict()
        headers["Content-Type"] = "application/json; charset=utf-8"
        received = client.post(
            "/",
            content=msgspec.json.encode(data),
            headers=headers,
        )
        print(received.content)
        assert msgspec.json.decode(received.content, type=module.Superuser) == data

Litestar Version

latest

Platform

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

Funding

  • You can sponsor this specific effort via a Polar.sh pledge below
  • We receive the pledge once the issue is completed & verified
Fund with Polar

wrong repository 😮‍💨