Skip to content

fix: use correct model validator signature#586

Merged
jsstevenson merged 1 commit into
mainfrom
fix-validator-signature
Oct 9, 2025
Merged

fix: use correct model validator signature#586
jsstevenson merged 1 commit into
mainfrom
fix-validator-signature

Conversation

@jsstevenson

@jsstevenson jsstevenson commented Oct 8, 2025

Copy link
Copy Markdown
Contributor

We had previously been using an incorrect method signature that was apparently working, but in an undefined way, and pydantic v 2.12 "fixed" (broke, for us) this -- see "after model validators" https://pydantic.dev/articles/pydantic-v2-12-release)

@theferrit32

Copy link
Copy Markdown
Contributor

Confirmed tests/validation/test_models.py::test_mappable_concept succeeds with these versions:

pydantic==2.11.9
pydantic-core==2.33.2

And fails with these:

pydantic==2.12.0
pydantic-core==2.41.1

Error:

FAILED tests/validation/test_models.py::test_mappable_concept - AttributeError: 'pydantic_core._pydantic_core.ValidationInfo' object has no attribute 'primaryCoding'

I am a little confused at how it's working with pydantic 2.11 because looking at the docs, 2.11 and 2.12 have the same signature for model after validators.

https://docs.pydantic.dev/2.11/concepts/validators/#model-validators

class UserModel(BaseModel):
    username: str
    password: str
    password_repeat: str

    @model_validator(mode='after')
    def check_passwords_match(self) -> Self:
        if self.password != self.password_repeat:
            raise ValueError('Passwords do not match')
        return self

https://docs.pydantic.dev/2.11/api/functional_validators/#pydantic.functional_validators.ModelAfterValidator

ModelAfterValidator = Callable[
    [_ModelType, ValidationInfo], _ModelType
]

https://docs.pydantic.dev/2.12/concepts/validators/#model-validators

class UserModel(BaseModel):
    username: str
    password: str
    password_repeat: str

    @model_validator(mode='after')
    def check_passwords_match(self) -> Self:
        if self.password != self.password_repeat:
            raise ValueError('Passwords do not match')
        return self

https://docs.pydantic.dev/2.12/api/functional_validators/#pydantic.functional_validators.ModelAfterValidator

ModelAfterValidator = Callable[
    [_ModelType, ValidationInfo[Any]], _ModelType
]

@jsstevenson

Copy link
Copy Markdown
Contributor Author

@theferrit32 what intrigues me is that the changelog makes it seem as though v2.12 will now raise some kind of validation error, and that's not what's happening to us -- rather, we're just getting some unexpected values and then the failure happens within the validator function

@theferrit32

Copy link
Copy Markdown
Contributor

@jsstevenson If I add this assert at the bottom in your branch using pydantic 2.12

def test_mappable_concept():
    """Test the MappableConcept model validator"""
    # Does not provide required fields
    with pytest.raises(
        ValueError, match="One of `name` or `primaryCoding` must be provided."
    ):
        core_models.MappableConcept(conceptType="test")

    # Valid models
    assert core_models.MappableConcept(name="Primary Label")
    assert core_models.MappableConcept(
        primaryCoding=core_models.Coding(
            code="HGNC:1097",
            system="https://www.genenames.org/data/gene-symbol-report/#!/hgnc_id/",
        )
    )
    assert core_models.MappableConcept(
        primaryCoding=core_models.Coding(
            # code="HGNC:1097",
            system="https://www.genenames.org/data/gene-symbol-report/#!/hgnc_id/",
        )
    )

I get

FAILED tests/validation/test_models.py::test_mappable_concept - pydantic_core._pydantic_core.ValidationError: 1 validation error for Coding

Which I think is right?

@theferrit32

Copy link
Copy Markdown
Contributor

This fix-validator-signature branch also works for

pydantic==2.11.9
pydantic-core==2.33.2

So I guess we don't need to constrain pyproject.toml to pydantic>=2.12

@jsstevenson jsstevenson merged commit b9d9887 into main Oct 9, 2025
20 of 24 checks passed
@jsstevenson jsstevenson deleted the fix-validator-signature branch October 9, 2025 00:13
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

Successfully merging this pull request may close these issues.

2 participants