Open flaeppe opened 3 months ago
Hopefully this won't play too bad with https://github.com/typeddjango/django-stubs/pull/1900
I'm hoping it should play along since #1900 is more about inferring and defaults?
This instead sets explicit and specific get/set types
This is quite ugly.
Something that I have been pondering about since mypy 1.10 implemented PEP 696 Type Defaults for Type Parameters is: we could add default=
to the TypeVars used for model fields.
The downside is that we would need separate TypeVar definitions for most field classes.
# before
class IntegerField(Field[_ST, _GT]):
_pyi_private_set_type: float | int | str | Combinable
_pyi_private_get_type: int
_pyi_lookup_exact_type: str | int
# after
_ST_IntegerField = TypeVar('_ST_IntegerField', default=float | int | str | Combinable)
_GT_IntegerField = TypeVar('_GT_IntegerField', default=int)
class IntegerField(Field[_ST_IntegerField, _GT_IntegerField]):
_pyi_private_set_type: float | int | str | Combinable
_pyi_private_get_type: int
_pyi_lookup_exact_type: str | int
This should improve experience in general for users who don't have the mypy django plugin enabled, and would remove the need for these manual generic arguments:
password: models.CharField[str | int | Combinable, str]
last_login: models.DateTimeField[str | datetime | date | Combinable, datetime | None]
is_active: bool | models.BooleanField[bool | Combinable, bool]
I don't mind the generic arguments per se, model fields are generic. And I find it great that we can declare them explicitly for models included in the stubs, because then it becomes very clear what types are allowed.
What I do find off is that e.g. CharField
declares int
as one of its set types. I know that CharField
casts/coerces to a string but to me that looks a bit like support for shotgun parsing.
I wouldn't mind a setup that's using default=
either. I looked at that initially but was unsure if we would run into any problems until https://github.com/python/mypy/issues/14851#issuecomment-1988786756 has been fixed. I'm happy to change to a default=
approach if we don't see any troubles with it.
There are quite a bit of changes in here, but it shouldn't produce any different results really.
It mainly allows
pyright
to also pick up types from the builtin models.One note about the types for the fields: they have been copied from what has been declared in
_pyi_private_set_type
and_pyi_private_get_type
for each field, so there shouldn't be any difference formypy
.Related issues