Skip to content

Make ValidationInfo generic for context #1686

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ classifiers = [
'Operating System :: MacOS',
'Typing :: Typed',
]
dependencies = ['typing-extensions>=4.6.0,!=4.7.0']
dependencies = [
'typing-extensions>=4.12.0',
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to call this out in the changelog?

Copy link
Member Author

Choose a reason for hiding this comment

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

Pydantic already requires 4.12, so I don't think so.

]
dynamic = ['description', 'license', 'readme', 'version']

[project.urls]
Expand Down
9 changes: 6 additions & 3 deletions python/pydantic_core/core_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from re import Pattern
from typing import TYPE_CHECKING, Any, Callable, Literal, Union

from typing_extensions import deprecated
from typing_extensions import TypeVar, deprecated

if sys.version_info < (3, 12):
from typing_extensions import TypedDict
Expand Down Expand Up @@ -163,13 +163,16 @@ class FieldSerializationInfo(SerializationInfo, Protocol):
def field_name(self) -> str: ...


class ValidationInfo(Protocol):
ContextT = TypeVar('ContextT', covariant=True, default='Any | None')


class ValidationInfo(Protocol[ContextT]):
Comment on lines +166 to +169
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we add some mypy tests for this / maybe also the covariance?

Copy link
Member Author

Choose a reason for hiding this comment

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

We can do so in Pydantic after updating the core version. The covariance is required because it is a Protocol, but I'm wondering if it really makes sense. At runtime, it is defined as a pyo3 class: shouldn't we move it's definition to the stub file instead?

Copy link
Member Author

@Viicos Viicos Apr 9, 2025

Choose a reason for hiding this comment

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

I guess maybe it is defined this way so that it cannot be instantiated (at least for static type checkers, at runtime it would still be possible)?

Copy link
Contributor

@davidhewitt davidhewitt Apr 9, 2025

Choose a reason for hiding this comment

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

You mean move this ValidationInfo definition to _pydantic_core.pyi? That seems probably correct to me?

EDIT see below

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah actually it's not exported by the library, so having it in _pydantic_core.pyi seems slightly incorrect, it's not actually importable from there at runtime.

I guess this is why it's defined as a protocol here, the Rust type then satisfies the protocol without needing to actually be related to it in the hierarchy.

"""
Argument passed to validation functions.
"""

@property
def context(self) -> Any | None:
def context(self) -> ContextT:
"""Current validation context."""
...

Expand Down
3 changes: 2 additions & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading