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

Conversation

Viicos
Copy link
Member

@Viicos Viicos commented Apr 8, 2025

Change Summary

Fixes pydantic/pydantic#11485.

Example usage:

@dataclass
class MyContext:
    some_value: int

def validator(value: int, info: ValidationInfo[MyContext]):
    ...

One one hand, it isn't strictly correct to give the validator implementation a way to "enforce" (at least from a static type checking perspective) a context type, as ultimately this can be unsafe if provide a different context value in the validate functions. On the other hand, it is convenient if you are guaranteed that the correct context will be used during validation.

If users don't control how validation is performed, they can still leave ValidationInfo unparameterized (and have the context type fallback to Any | None) and have safety guards on the info.context value.

Related issue number

Checklist

  • Unit tests for the changes exist
  • Documentation reflects the changes where applicable
  • Pydantic tests pass with this pydantic-core (except for expected changes)
  • My PR is ready to review, please add a comment including the phrase "please review" to assign reviewers

Copy link

codspeed-hq bot commented Apr 8, 2025

CodSpeed Performance Report

Merging #1686 will not alter performance

Comparing validation-info-generic (3f378eb) with main (0a5bbfc)

Summary

✅ 157 untouched benchmarks

@@ -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.

Comment on lines +166 to +169
ContextT = TypeVar('ContextT', covariant=True, default='Any | None')


class ValidationInfo(Protocol[ContextT]):
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.

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.

Make ValidationInfo generic
2 participants