-
-
Notifications
You must be signed in to change notification settings - Fork 603
feat: add flag to support for UNSET tristate when using pydantic #4051
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: add flag to support for UNSET tristate when using pydantic #4051
Conversation
Reviewer's GuideIntroduce a flag to control whether Pydantic defaults are materialized for GraphQL inputs, enabling true tri-state semantics by preserving UNSET values when opted out. File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
Hi, thanks for contributing to Strawberry 🍓! We noticed that this PR is missing a So as soon as this PR is merged, a release will be made 🚀. Here's an example of Release type: patch
Description of the changes, ideally with some examples, if adding a new feature.Release type can be one of patch, minor or major. We use semver, so make sure to pick the appropriate type. If in doubt feel free to ask :) Here's the tweet text: |
Greptile OverviewGreptile SummaryThis PR adds a Key Changes:
Behavior:
Confidence Score: 4/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
participant Client as GraphQL Client
participant Schema as Strawberry Schema
participant Input as UpdateUserInput
participant Pydantic as UserModel (Pydantic)
Note over Client,Pydantic: use_pydantic_default=False flow
Client->>Schema: mutation { updateUser(userData: {name: "John"}) }
Schema->>Input: Create UpdateUserInput(name="John")
alt Field Construction (use_pydantic_default=False)
Note over Input: interests field gets UNSET<br/>via _default_unset() factory
Input->>Input: name = "John"
Input->>Input: interests = UNSET
end
Input->>Input: Check field with `is UNSET`
alt Converting to Pydantic (to_pydantic)
Input->>Pydantic: to_pydantic()
Note over Input,Pydantic: Skip UNSET fields when<br/>use_pydantic_default=False
Input->>Pydantic: model(name="John")
Note over Pydantic: Pydantic applies default_factory<br/>interests=[]
end
Pydantic-->>Client: Updated user data
Note over Client,Pydantic: use_pydantic_default=True (default) flow
Client->>Schema: mutation { updateUser(userData: {name: "Alice"}) }
Schema->>Input: Create UpdateUserInput(name="Alice")
alt Field Construction (use_pydantic_default=True)
Note over Input: interests field gets Pydantic default<br/>via get_default_factory_for_field()
Input->>Input: name = "Alice"
Input->>Input: interests = []
end
Input->>Pydantic: to_pydantic()
Input->>Pydantic: model(name="Alice", interests=[])
Pydantic-->>Client: Updated user data
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 file reviewed, no comments
bellini666
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks :)
Can we have a test for this?
| # local helper to satisfy E731 (no lambda assignment) | ||
| def _default_unset() -> object: | ||
| return UNSET | ||
|
|
||
| # for inputs with use_pydantic_default, default_factory should be used | ||
| if is_input and not use_pydantic_default: | ||
| default_factory = _default_unset |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thought: We have UnsetType, which is UNSET's class, and it overrides __new__ to make sure it is always a singleton. Maybe we can also override __call__ to return itself, so we could just do default_factory = UNSET?
/cc @patrick91
…ntics; make UnsetType a callable singleton for default_factory; update docs.
for more information, see https://pre-commit.ci
pydantic inputs (strawberry.auto): honor UNSET / allow opt-out of Pydantic defaults.
Pydantic defaults can mask omitted input fields in GraphQL. This opt-out preserves strict input semantics while keeping current behavior as default.
Fixes #4042
Example code:
Output of example code above:
Summary by Sourcery
Introduce use_pydantic_default flag to preserve true tri-state input semantics for Pydantic-backed GraphQL inputs.
New Features:
Bug Fixes:
Enhancements:
Documentation: