Skip to content
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

Ellipsis does not mark annotated field as required in create_model #8634

Closed
1 task done
jackmpcollins opened this issue Jan 25, 2024 · 7 comments · Fixed by #8793
Closed
1 task done

Ellipsis does not mark annotated field as required in create_model #8634

jackmpcollins opened this issue Jan 25, 2024 · 7 comments · Fixed by #8793
Assignees
Labels
bug V2 Bug related to Pydantic V2

Comments

@jackmpcollins
Copy link

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

Ellipsis is being recognized as a default value for fields that have Annotated[<type>, Field()] type annotation. These fields should instead be marked as required with no default.

This works correctly in v2.1.0 and is broken in v2.1.1 and in the latest version v2.5.3.

This is mainly an issue for me using create_model where Ellipsis must be used to indicate the absence of a default value.

Relevant docs https://docs.pydantic.dev/latest/concepts/models/#required-fields

Example Code

from typing import Annotated
from pydantic import BaseModel, Field


class Model(BaseModel):
    a: int = ...
    b: Annotated[int, "placeholder"] = ...
    c: Annotated[int, Field()] = ...

for f in Model.model_fields.items():
    print(f)

# v2.1.0
# ('a', FieldInfo(annotation=int, required=True))
# ('b', FieldInfo(annotation=int, required=True, metadata=['placeholder']))
# ('c', FieldInfo(annotation=int, required=True))

# v2.1.1
# ('a', FieldInfo(annotation=int, required=True))
# ('b', FieldInfo(annotation=int, required=True, metadata=['placeholder']))
# ('c', FieldInfo(annotation=int, required=False, default=Ellipsis))


# ---


from typing import Annotated
from pydantic import Field, create_model


m = create_model(
    "Test",
    a=(int, ...),
    b=(Annotated[int, "placeholder"], ...),
    c=(Annotated[int, Field()], ...),
)
for f in m.model_fields.items():
    print(f)

# v2.1.0
# ('a', FieldInfo(annotation=int, required=True))
# ('b', FieldInfo(annotation=int, required=True, metadata=['placeholder']))
# ('c', FieldInfo(annotation=int, required=True))

# v2.1.1
# ('a', FieldInfo(annotation=int, required=True))
# ('b', FieldInfo(annotation=int, required=True, metadata=['placeholder']))
# ('c', FieldInfo(annotation=int, required=False, default=Ellipsis))

Python, Pydantic & OS Version

pydantic version: 2.5.3
        pydantic-core version: 2.14.6
          pydantic-core build: profile=release pgo=true
                 install path: /Users/jack/Code/magentic/.venv/lib/python3.10/site-packages/pydantic
               python version: 3.10.8 (main, Apr  2 2023, 18:27:17) [Clang 14.0.3 (clang-1403.0.22.14.1)]
                     platform: macOS-14.2.1-arm64-arm-64bit
             related packages: typing_extensions-4.7.1 pydantic-settings-2.0.3 mypy-1.8.0
@jackmpcollins jackmpcollins added bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation labels Jan 25, 2024
@jackmpcollins
Copy link
Author

There was minimal change from v2.1.0 to v2.1.1 so hopefully the cause should be easy to identify for someone familiar with the code. v2.1.0...v2.1.1

@sydney-runkle
Copy link
Member

@jackmpcollins,

Thanks for reporting this. This does look like a bug. We'll look to fix this for v2.7!

@Evenfire
Copy link

@sydney-runkle

I just had a quick look. The symptoms are similar too #8629 but this is indeed a bug. As @jackmpcollins pointed out, the changes introduced between 2.1.0 and 2.1.1 are the source.

Just a few details:
With those changes, applying the overrides bypasses the FieldInfo.__init__ method where the default attribute is set to a special value when the default parameter value is.... You guessed it: Ellipsis.

I'll open a PR

@sydney-runkle
Copy link
Member

@Evenfire,

Fantastic! Ping me when you need a review 🚀 !

@sydney-runkle
Copy link
Member

I think this was the change that caused the bug in the first place: https://github.com/pydantic/pydantic/pull/6862/files

@dmarteau
Copy link

Is the fix released ?

As with version 2.6.3 this appears not yet fixed:

class Foo(BaseModel):
    x: Annotated[int, Field()] = ...
   
from f in Foo.model_fields.items():
    print(f)

# 2.6.3
# ('x', FieldInfo(annotation=int, required=False, default=Ellipsis))

Thanks

@sydney-runkle
Copy link
Member

It's fixed on main, and should be released in v2.7.0!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug V2 Bug related to Pydantic V2
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants