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

upgrade from pydantic v2.4.3 to v2.5.1 introduced a regression using BaseSettings with union-types #190

Closed
spex66 opened this issue Nov 17, 2023 · 5 comments
Assignees

Comments

@spex66
Copy link

spex66 commented Nov 17, 2023

I wasn't able to isolate the core of this problem yet which happens after updating dependencies

  • but as it looks like a regression to me
  • I decided sharing it for others which run into the same issue, and might be able to provide more insights

FYI pydantic v2.5 release notes mention:

Significant Change: replace ultra_strict with new smart union implementation, the way unions are validated has changed significantly to improve performance and correctness, we have worked hard to absolutely minimise the number of cases where behaviour has changed, see the PR for details - by @davidhewitt in pydantic/pydantic-core#867

Following is a stripped down example, in original code I need BaseSettings, so pls don't repond how I can by-pass the problem :)
And extra='forbid' is needed to (which is default for BaseSettings).

versions

which fail the test

pydantic              2.5.1        Data validation using Python type hints
pydantic-core         2.14.3       
pydantic-settings     2.1.0        Settings management using Pydantic

which pass the test

pydantic              2.4.2        Data validation using Python type hints
pydantic-core         2.10.1       
pydantic-settings     2.0.3        Settings management using Pydantic

reproduction steps

  • following pytest (or simply run test_steps_alternative()) fails
  • replacing BaseSettings with BaseModel makes the pass successful
  • using pydantic v2.4 makes this test pass successful AS IS
from pydantic_settings import BaseSettings

class StepSingle(BaseSettings):
    step: int

class StepRange(BaseSettings):
    range: int

class StepsAlternative(BaseSettings):
    steps: StepSingle | StepRange

def test_steps_alternative():
    StepsAlternative.model_validate({"steps": {"step": 1}}, strict=True)
    StepsAlternative.model_validate({"steps": {"range": 2}}, strict=True)

error message

ValidationError: 2 validation errors for StepRange
range
  Field required [type=missing, input_value={'step': 1}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.5/v/missing
step
  Extra inputs are not permitted [type=extra_forbidden, input_value=1, input_type=int]
    For further information visit https://errors.pydantic.dev/2.5/v/extra_forbidden
@hramezani
Copy link
Member

Thanks @spex66 for reporting this.

Yeah, as you mentioned the fix is the change StepSingle and StepRange to inherit from BaseModel.

The reason for this problem is when you initialize the StepsAlternative, Pydantic initializes the StepSingle and StepRange. the error message comes from StepRange.

we had the same behavior in 2.4.2 (initializing all the models) but I don't know what exactly was the change in 2.5.

probably @davidhewitt can explain.

@spex66
Copy link
Author

spex66 commented Nov 17, 2023

thx @hramezani for your quick feedback!

But I can confirm that I double checked today, switching versions back and forth, that this code was working.
So even if the behavior has not changed "behind the scenes", the error is new and smells like a regression.

@spex66
Copy link
Author

spex66 commented Dec 13, 2023

hi @hramezani
I've retested using latest releases

  • the reported error happened with pydantic 2.5.1, pydantic-core 2.14.3, pydantic-settings 2.1.0
  • but the error does not happen using (latest) pydantic 2.5.2, pydantic-core 2.14.5, pydantic-settings 2.1.0

ofc I have no idea which change in pydantic or core has resolved it, maybe you have an idea?
So from my side the ticket can be closed

@hramezani
Copy link
Member

I think it was a bug that was introduced and got fixed.
I don't have any idea probably @davidhewitt can help here.

Thanks for letting us know.

@davidhewitt
Copy link
Contributor

@spex66 @hramezani I'm not aware of a particular bug that would have caused this and since been fixed.

I tried to repro with the versions listed here, I cannot repro with any of 2.5.0, 2.5.1, or 2.5.2. Strange.

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

No branches or pull requests

4 participants