The from_pydantic
function in Pydantic does not work with a specialized list class. When attempting to convert a specialized list instance, such as workList[WorkModel], an error is raised: ValueError: Not supported workList[types.Work]
.
import strawberry
from typing import TypeVar, List
from pydantic import BaseModel
SI = TypeVar("SI", covariant=True)
class SpecialList(List[SI]):
pass
class WorkModel(BaseModel):
name: str
class workList(SpecialList[SI]):
min_items = 1
class UserModel(BaseModel):
work: workList[WorkModel]
@strawberry.experimental.pydantic.type(WorkModel)
class Work:
name: strawberry.auto
@strawberry.experimental.pydantic.type(UserModel)
class User:
work: strawberry.auto
origin_user = UserModel(
work=[WorkModel(name="developer"), WorkModel(name="tester")]
)
user = User.from_pydantic(origin_user)
assert user == User(work=[Work(name="developer"), Work(name="tester")])
The conversion from the Pydantic model UserModel to the Strawberry model User should work properly, including the conversion of the specialized list workList[WorkModel] to a list of Work instances.
An error is raised: ValueError: Not supported tests.experimental.pydantic.test_conversion.test_can_convert_pydantic_type_to_strawberry_with_constrained_list..workList[types.Work].
I encountered this error while working on the orchestrator-core project. The error is similar to the one mentioned in the GitHub reference provided. Here is the relevant code snippet from that reference:
class SubscriptionInstanceList(ConstrainedList, List[SI]): # type: ignore
"""Shorthand to create constrained lists of product blocks."""
def __init_subclass__(cls, **kwargs: Any) -> None:
super().__init_subclass__(**kwargs)
# Copy generic argument (SI) if not set explicitly
# This makes a lot of assumptions about the internals of `typing`
if "__orig_bases__" in cls.__dict__ and cls.__dict__["__orig_bases__"]:
generic_base_cls = cls.__dict__["__orig_bases__"][0]
if not hasattr(generic_base_cls, "item_type") and get_args(generic_base_cls):
cls.item_type = get_args(generic_base_cls)[0]
# Make sure __args__ is set
cls.__args__ = (cls.item_type,)
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too