Skip to content

Validate Field(validators=[...]) more precisely#3239

Open
UnknownPlatypus wants to merge 3 commits into
typeddjango:masterfrom
UnknownPlatypus:fix-264
Open

Validate Field(validators=[...]) more precisely#3239
UnknownPlatypus wants to merge 3 commits into
typeddjango:masterfrom
UnknownPlatypus:fix-264

Conversation

@UnknownPlatypus
Copy link
Copy Markdown
Contributor

I have made things!

Make _ValidatorCallable more strict by adding a typevar and binding it to the getter type of the various fields:

-_ValidatorCallable: TypeAlias = Callable[[Any], None] # noqa: PYI047
+_VT = TypeVar("_VT", contravariant=True)
+_ValidatorCallable: TypeAlias = Callable[[_VT], None] 

Fixes #264

@github-actions
Copy link
Copy Markdown
Contributor

Diff from mypy_primer, showing the effect of this PR on type check results on a corpus of open source code:

zulip (https://github.com/zulip/zulip)
+ zerver/models/realm_emoji.py:34: error: Argument "validators" to "TextField" has incompatible type "list[_Deconstructible]"; expected "Iterable[Callable[[Never], None]]"  [arg-type]

@UnknownPlatypus
Copy link
Copy Markdown
Contributor Author

UnknownPlatypus commented Mar 28, 2026

  • zerver/models/realm_emoji.py:34: error: Argument "validators" to "TextField" has incompatible type "list[_Deconstructible]"; expected "Iterable[Callable[[Never], None]]" [arg-type]

This is very interesting, because we now have _GT in the init signature, mypy tries to resolve the typevar from it and seem to fail and pick Never.

I think it would work if we managed to remove the custom _pyi_private_get_type and replace _GT with typevar + defaults like TypeVar("_StrFieldGT", covariant=True, default=str) -> cf #1264

@UnknownPlatypus UnknownPlatypus changed the title Fix 264 Validate Field(validators=[...]) more precisely Mar 28, 2026
@UnknownPlatypus
Copy link
Copy Markdown
Contributor Author

@sobolevn Do you have any context on the _pyi_private_get_type special variable and if you think we could get rid of them ? I have a feeling we should ?

@sobolevn
Copy link
Copy Markdown
Member

Yes, we should totally try. We implemented _pyi_private_{g,s}et_type when there were no type var defaults.

@UnknownPlatypus UnknownPlatypus linked an issue Apr 8, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Use PEP 696 defaults for fields Model field validators type is incorrect

2 participants