litestar-org / litestar

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

Enhancement: Support generic types in DTOs #2500

Open guacs opened 1 year ago

guacs commented 1 year ago

Description

DTOs does not seem to support generic types.

URL to code causing the issue

No response

MCVE

from dataclasses import dataclass
from typing import Generic, TypeVar

from litestar import Litestar
from litestar import post
from litestar.dto import DTOConfig, DataclassDTO, DTOData

T = TypeVar("T")

@dataclass
class Foo(Generic[T]):
    foo: T

FooDTO = DataclassDTO[Foo[int]]

@post("/foo", dto=FooDTO)
async def foo_handler(data: DTOData[Foo[int]]) -> Foo[int]:
    return data.create_instance()

app = Litestar([foo_handler])

Steps to reproduce

Run `litestar run`.

Screenshots

No response

Logs

Traceback (most recent call last):
  File "/home/guacs/open-source/litestar/.venv/bin/litestar", line 8, in <module>
    sys.exit(run_cli())
  File "/home/guacs/open-source/litestar/litestar/__main__.py", line 6, in run_cli
    litestar_group()
  File "/home/guacs/open-source/litestar/.venv/lib/python3.8/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
  File "/home/guacs/open-source/litestar/.venv/lib/python3.8/site-packages/rich_click/rich_command.py", line 125, in main
    with self.make_context(prog_name, args, **extra) as ctx:
  File "/home/guacs/open-source/litestar/litestar/cli/_utils.py", line 242, in make_context
    self._prepare(ctx)
  File "/home/guacs/open-source/litestar/litestar/cli/_utils.py", line 224, in _prepare
    env = ctx.obj = LitestarEnv.from_env(ctx.params.get("app_path"), ctx.params.get("app_dir"))
  File "/home/guacs/open-source/litestar/litestar/cli/_utils.py", line 122, in from_env
    loaded_app = _autodiscover_app(cwd)
  File "/home/guacs/open-source/litestar/litestar/cli/_utils.py", line 332, in _autodiscover_app
    module = importlib.import_module(import_path)
  File "/home/guacs/.pyenv/versions/3.8.17/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 843, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/guacs/open-source/litestar/app.py", line 25, in <module>
    app = Litestar([foo_handler])
  File "/home/guacs/open-source/litestar/litestar/app.py", line 447, in __init__
    self.register(route_handler)
  File "/home/guacs/open-source/litestar/litestar/app.py", line 623, in register
    route_handler.on_registration(self)
  File "/home/guacs/open-source/litestar/litestar/handlers/http_handlers/base.py", line 492, in on_registration
    super().on_registration(app)
  File "/home/guacs/open-source/litestar/litestar/handlers/base.py", line 525, in on_registration
    self.resolve_data_dto()
  File "/home/guacs/open-source/litestar/litestar/handlers/base.py", line 451, in resolve_data_dto
    data_dto.create_for_field_definition(
  File "/home/guacs/open-source/litestar/litestar/dto/base_dto.py", line 176, in create_for_field_definition
    raise InvalidAnnotationException(
litestar.exceptions.dto_exceptions.InvalidAnnotationException: DTO narrowed with 'app.Foo[int]', handler type is 'litestar.dto.data_structures.DTOData[app.Foo[int]]'

Litestar Version

main

Platform


[!NOTE]
While we are open for sponsoring on GitHub Sponsors and OpenCollective, we also utilize Polar.sh to engage in pledge-based sponsorship.

Check out all issues funded or available for funding on our Polar.sh Litestar dashboard

  • If you would like to see an issue prioritized, make a pledge towards it!
  • We receive the pledge once the issue is completed & verified
  • This, along with engagement in the community, helps us know which features are a priority to our users.

Fund with Polar

provinzkraut commented 11 months ago

@peterschutt You started working on this, but closed the PR again. Is this blocked by something?

peterschutt commented 11 months ago

No, just ran into a dead-end with the approach I was taking and have been sidetracked since.

interifter commented 9 months ago

Encountered this on python 3.12 on Windows, as well