KEMBAR78
model_json_schema export with Annotated types misses 'required' parameters by LouisGobert · Pull Request #8793 · pydantic/pydantic · GitHub
Skip to content

Conversation

@LouisGobert
Copy link
Contributor

@LouisGobert LouisGobert commented Feb 13, 2024

Change Summary

When using an Annotation with a FieldInfo and an Ellipsis, the Ellipsis was considered as a default value. Therefore, the field was not considered mandatory.

Related issue number

fix #8780
fix #8634

Checklist

  • The pull request title is a good summary of the changes - it will be used in the changelog
  • Unit tests for the changes exist
  • Tests pass on CI
  • Documentation reflects the changes where applicable
  • My PR is ready to review, please add a comment including the phrase "please review" to assign reviewers

Selected Reviewer: @lig

@codspeed-hq
Copy link

codspeed-hq bot commented Feb 13, 2024

CodSpeed Performance Report

Merging #8793 will not alter performance

Comparing LouisGobert:fix-annotation-with-field (093d05c) with main (832225b)

Summary

✅ 10 untouched benchmarks

@LouisGobert
Copy link
Contributor Author

please review

First open source contribution 🤞

@sydney-runkle sydney-runkle added the relnotes-fix Used for bugfixes. label Feb 13, 2024
Copy link
Contributor

@sydney-runkle sydney-runkle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great overall, just 2 quick change requests. Thanks!



def test_json_schema_annotated_with_field() -> None:
"""Check if the ellipsis in the signature is considered as a required field."""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Check if the ellipsis in the signature is considered as a required field."""
"""Ensure field specified with Annotated in create_model call is still marked as required."""


Model = create_model(
'test_model',
bar=(Annotated[int, Field(description='Bar description')], ...),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you include this example as well? baz=(Annotated[int, Field(..., description="Baz description")], ...),

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe with this model:

Model = create_model(
    'test_model',
    foo=(int, ...),
    bar=(Annotated[int, Field(description="Bar description")], ...),
    baz=(Annotated[int, Field(..., description="Baz description")], ...),
)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done 😄

@pydantic-hooky pydantic-hooky bot added awaiting author revision awaiting changes from the PR author and removed ready for review labels Feb 13, 2024
@sydney-runkle
Copy link
Contributor

So, with a slight modification to the logic in your PR, we can actually fix many related issues. My proposal is the following:

diff --git a/pydantic/fields.py b/pydantic/fields.py
index e369b52d..58332d79 100644
--- a/pydantic/fields.py
+++ b/pydantic/fields.py
@@ -402,6 +402,13 @@ class FieldInfo(_repr.Representation):
             # No merging necessary, but we still need to make a copy and apply the overrides
             field_info = copy(field_infos[0])
             field_info._attributes_set.update(overrides)
+
+            default_override = overrides.pop('default', PydanticUndefined)
+            if default_override is Ellipsis:
+                default_override = PydanticUndefined
+            if field_info.default is not PydanticUndefined and default_override is not PydanticUndefined:
+                field_info.default = default_override
+
             for k, v in overrides.items():
                 setattr(field_info, k, v)
             return field_info  # type: ignore

Which fixes:

Would you be willing to add a test for the second issue as well? Thanks for your contribution!

@LouisGobert
Copy link
Contributor Author

if field_info.default is not PydanticUndefined and default_override is not PydanticUndefined:
    field_info.default = default_override

I think this was the wrong proposal because if a field is initialized with a default = PydanticUndefined, the overide won't work 😄

My modification:

if default_override is not PydanticUndefined:
    field_info.default = default_override

@sydney-runkle
Copy link
Contributor

Looks great, thanks for the help with the fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting author revision awaiting changes from the PR author relnotes-fix Used for bugfixes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

model_json_schema export with Annotated types misses 'required' parameters Ellipsis does not mark annotated field as required in create_model

3 participants