-
-
Notifications
You must be signed in to change notification settings - Fork 6.1k
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
Fix response_model_exclude_none
having problems with uncommon defaults and required fields
#4647
base: master
Are you sure you want to change the base?
Conversation
I just created an issue for this, as my feeling was the PR is not enough. Please correct me if this was a dumb idea ;-) |
response_model_exclude_none
having problems with uncommon defaults and required fields
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #4647 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 540 529 -11
Lines 13969 13519 -450
==========================================
- Hits 13969 13519 -450 ☔ View full report in Codecov by Sentry. |
📝 Docs preview for commit ba8e87e at: https://625334f5d7935435d5b7a7d8--fastapi.netlify.app |
📝 Docs preview for commit 270f5f7 at: https://639de2d618290c3257ff4888--fastapi.netlify.app |
@tiangolo As you updated the MR just 3 days ago. Can I hope this will get fixed soon? Thanks for your feedback! |
📝 Docs preview for commit a19a00c at: https://63fe6d18dce37c2ebcba0629--fastapi.netlify.app |
📝 Docs preview for commit 65458a5 at: https://64318b3e7e2e523d650bbe16--fastapi.netlify.app |
📝 Docs preview for commit 0eebcb9 at: https://647b4ea856364a0db7bbf9ed--fastapi.netlify.app |
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.
This issue isn't relevant to Pydantic v.2, but it's still relevant to Pydantic v.1 (tested on FastAPI 0.110.0 and Pydantic 1.10.14).
New added test fails before changes are made (on Pydantic v.1) and passes after.
Regarding the code. I would just remove the line with exclude_none
. Comment there is unnecessary.
# jsonable_encoder() below will apply exclude_none, so it is not | ||
# necessary here. Instead excluding None here may even cause issues | ||
# as not all fields with a value of None have a None default value | ||
# and by that would be initialized with None after the validation | ||
# phase again. | ||
exclude_none=False, |
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.
I Think this comment is unnecessary. I would just remove the line with exclude_none=
To output responses including a response_model FastAPI does something like (from my understanding):
Now if we add response_model_exclude_none FastAPI will change this to:
The issue now is that the
response_data
already did exclude all thoseNone
values. This means that when theresponse_model
is then instantiated again the dictionary you use here (in my code namedresponse_data
) already lost those values which may cause problems.Now if your response model is something like:
...we have two issues with
None
values (think ofModelNoneWithUncommonDefaults(x=None, y=None)
):x
is required, but may beNone
. Asresponse_data
does not includex
any more whenx == None
...the validation when instantiatingresponse_model
will fail with aValidationError
. The field has to be set.y
has a default value of"y"
but may beNone
. Asresponse_data
does not includey
any more wheny == None
...the response will actually containy = "y"
as the validation will add its default value again. This will result in a false response.The problem overall is the duplicate
exclude_none=True
and thus the missing values we already had when doing the validation.The PR will skip
exclude_none
on the first conversion todict
and thus fix the issue. Not sure if my change was done at the best place to fix this, but I hope it is. Also the PR includes a new test to show the issue and ensure it does not come back later.I believe
exclude_unset
andexclude_defaults
should not have the same issue as those always have the same default values and the validation would not break/change anything. Anyways it would be cleaner to also not use those on the first conversion todict
I think. This has not be changed by me.