When trying to set a sentinel to know which fields have actually been set, it seems the Pydantic converter sort of botches the process because it converts UNSET
to None
, hence losing the information about wether it's been set or not.
Code example:
from typing import Optional
import pydantic
import strawberry
from strawberry.arguments import UNSET, is_unset
class FooModel(pydantic.BaseModel):
bar: Optional[int] = pydantic.Field(
default=UNSET,
# default_factory=lambda: UNSET,
)
@strawberry.experimental.pydantic.input(model=FooModel, all_fields=True)
class FooInput:
pass
@strawberry.type
class Query:
@strawberry.field
def foo(self, input: FooInput) -> bool:
print(type(input.bar))
return is_unset(input.bar)
schema = strawberry.Schema(query=Query)
result = schema.execute_sync(
query="""
query {
foo(input: {})
}
"""
)
print(result.data["foo"])
>>> <class 'NoneType'>
>>> False
Note that I've commented the default_factory=lambda: UNSET
, which is a solution I've come up with to prevent Strawberry from replacing UNSET
with None
during conversion.
If we try without Pydantic (pure Strawberry), it works:
@strawberry.input
class FooInput:
bar: Optional[int] = UNSET
@strawberry.type
class Query:
@strawberry.field
def foo(self, input: FooInput) -> bool:
return is_unset(input.bar)
schema = strawberry.Schema(query=Query)
result = schema.execute_sync(query="""
query {
foo(input: {})
}
""")
print(result.data["foo"])
>>> True
Also, Pydantic has its own sentinel value named Undefined
(and an UndefinedType
):
from pydantic.fields import Undefined
It would be great if that sentinel was converted to UNSET
during the conversion process :)
This issue is related to this PR
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