Model.__init__ supporting same typing as assigment (#835)

* `Model.__init__` supporting same typing as assigment

* Update mypy_django_plugin/django/context.py
This commit is contained in:
Petter Friberg
2022-01-29 10:07:26 +01:00
committed by GitHub
parent c556668d7a
commit 8aae836a26
9 changed files with 177 additions and 18 deletions

View File

@@ -0,0 +1,19 @@
- case: union_combinable_reduced_to_non_union
main: |
from typing import List
from myapp.models import MyModel
array_val: List[int] = [1]
MyModel(array=array_val) # E: Incompatible type for "array" of "MyModel" (got "List[int]", expected "Union[Sequence[str], Combinable]")
non_init = MyModel()
non_init.array = array_val # E: Incompatible types in assignment (expression has type "List[int]", variable has type "Union[Sequence[str], Combinable]")
installed_apps:
- myapp
files:
- path: myapp/__init__.py
- path: myapp/models.py
content: |
from django.db import models
from django.contrib.postgres.fields import ArrayField
class MyModel(models.Model):
array = ArrayField(base_field=models.TextField())

View File

@@ -94,7 +94,7 @@
- case: blank_and_not_null_charfield_does_not_allow_none
main: |
from myapp.models import MyModel
MyModel(notnulltext=None) # Should allow None in constructor
MyModel(notnulltext=None) # E: Incompatible type for "notnulltext" of "MyModel" (got "None", expected "Union[str, int, Combinable]")
MyModel(notnulltext="")
MyModel().notnulltext = None # E: Incompatible types in assignment (expression has type "None", variable has type "Union[str, int, Combinable]")
reveal_type(MyModel().notnulltext) # N: Revealed type is "builtins.str*"

View File

@@ -357,13 +357,13 @@
reveal_type(Book().publisher_id) # N: Revealed type is "builtins.str*"
Book(publisher_id=1)
Book(publisher_id='hello')
Book(publisher_id=datetime.datetime.now()) # E: Incompatible type for "publisher_id" of "Book" (got "datetime", expected "Union[str, int, Combinable, None]")
Book(publisher_id=datetime.datetime.now()) # E: Incompatible type for "publisher_id" of "Book" (got "datetime", expected "Union[str, int, Combinable]")
Book.objects.create(publisher_id=1)
Book.objects.create(publisher_id='hello')
reveal_type(Book2().publisher_id) # N: Revealed type is "builtins.int*"
Book2(publisher_id=1)
Book2(publisher_id=[]) # E: Incompatible type for "publisher_id" of "Book2" (got "List[Any]", expected "Union[float, int, str, Combinable, None]")
Book2(publisher_id=[]) # E: Incompatible type for "publisher_id" of "Book2" (got "List[Any]", expected "Union[float, int, str, Combinable]")
Book2.objects.create(publisher_id=1)
Book2.objects.create(publisher_id=[]) # E: Incompatible type for "publisher_id" of "Book2" (got "List[Any]", expected "Union[float, int, str, Combinable]")
installed_apps:

View File

@@ -95,12 +95,28 @@
- case: when_default_for_primary_key_is_specified_allow_none_to_be_set
main: |
from myapp.models import MyModel
MyModel(id=None)
MyModel.objects.create(id=None)
first = MyModel(id=None)
reveal_type(first.id) # N: Revealed type is "builtins.int*"
first = MyModel.objects.create(id=None)
reveal_type(first.id) # N: Revealed type is "builtins.int*"
first = MyModel()
first.id = None
reveal_type(first.id) # N: Revealed type is "builtins.int*"
from myapp.models import MyModel2
MyModel2(id=None)
MyModel2(id=None) # E: Incompatible type for "id" of "MyModel2" (got "None", expected "Union[float, int, str, Combinable]")
MyModel2.objects.create(id=None) # E: Incompatible type for "id" of "MyModel2" (got "None", expected "Union[float, int, str, Combinable]")
second = MyModel2()
second.id = None # E: Incompatible types in assignment (expression has type "None", variable has type "Union[float, int, str, Combinable]")
reveal_type(second.id) # N: Revealed type is "builtins.int*"
# default set but no primary key doesn't allow None
from myapp.models import MyModel3
MyModel3(default=None) # E: Incompatible type for "default" of "MyModel3" (got "None", expected "Union[float, int, str, Combinable]")
MyModel3.objects.create(default=None) # E: Incompatible type for "default" of "MyModel3" (got "None", expected "Union[float, int, str, Combinable]")
third = MyModel3()
third.default = None # E: Incompatible types in assignment (expression has type "None", variable has type "Union[float, int, str, Combinable]")
reveal_type(third.default) # N: Revealed type is "builtins.int*"
installed_apps:
- myapp
files:
@@ -114,3 +130,5 @@
id = models.IntegerField(primary_key=True, default=return_int)
class MyModel2(models.Model):
id = models.IntegerField(primary_key=True)
class MyModel3(models.Model):
default = models.IntegerField(default=return_int)

View File

@@ -126,8 +126,8 @@
from myapp.models import Publisher, PublisherDatetime, Book
Book(publisher_id=1, publisher_dt_id=now)
Book(publisher_id=[], publisher_dt_id=now) # E: Incompatible type for "publisher_id" of "Book" (got "List[Any]", expected "Union[Combinable, int, str, None]")
Book(publisher_id=1, publisher_dt_id=1) # E: Incompatible type for "publisher_dt_id" of "Book" (got "int", expected "Union[str, datetime, date, Combinable, None]")
Book(publisher_id=[], publisher_dt_id=now) # E: Incompatible type for "publisher_id" of "Book" (got "List[Any]", expected "Union[Combinable, int, str]")
Book(publisher_id=1, publisher_dt_id=1) # E: Incompatible type for "publisher_dt_id" of "Book" (got "int", expected "Union[str, datetime, date, Combinable]")
installed_apps:
- myapp
files:
@@ -155,15 +155,17 @@
class NotAValid:
pass
array_val3: List[NotAValid] = [NotAValid()]
MyModel(array=array_val3) # E: Incompatible type for "array" of "MyModel" (got "List[NotAValid]", expected "Union[Sequence[Union[float, int, str, Combinable]], Combinable]")
MyModel(array=array_val3) # E: Incompatible type for "array" of "MyModel" (got "List[NotAValid]", expected "Union[Sequence[Union[float, int, str]], Combinable]")
non_init = MyModel()
non_init.array = array_val
non_init.array = array_val2
non_init.array = array_val3 # E: Incompatible types in assignment (expression has type "List[NotAValid]", variable has type "Union[Sequence[Union[float, int, str]], Combinable]")
installed_apps:
- myapp
files:
- path: myapp/__init__.py
- path: myapp/models.py
content: |
from typing import List, Tuple
from django.db import models
from django.contrib.postgres.fields import ArrayField
@@ -232,7 +234,7 @@
class Publisher(models.Model):
name = models.CharField(primary_key=True, max_length=100)
class Book(models.Model):
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE, null=True)
- case: init_in_abstract_model_classmethod_should_not_throw_error_for_valid_fields
@@ -255,3 +257,61 @@
return cls(text='mytext')
class MyModel(AbstractModel):
pass
- case: field_set_type_honors_type_redefinition
main: |
from typing import List
from myapp.models import MyModel
non_init = MyModel()
reveal_type(non_init.redefined_set_type)
reveal_type(non_init.redefined_union_set_type)
reveal_type(non_init.redefined_array_set_type)
reveal_type(non_init.default_set_type)
reveal_type(non_init.unset_set_type)
non_init.redefined_set_type = "invalid"
non_init.redefined_union_set_type = "invalid"
array_val: List[str] = ["invalid"]
non_init.redefined_array_set_type = array_val
non_init.default_set_type = []
non_init.unset_set_type = []
MyModel(
redefined_set_type="invalid",
redefined_union_set_type="invalid",
redefined_array_set_type=33,
default_set_type=[],
unset_set_type=[],
)
out: |
main:4: note: Revealed type is "builtins.int*"
main:5: note: Revealed type is "builtins.int*"
main:6: note: Revealed type is "builtins.list*[builtins.int]"
main:7: note: Revealed type is "builtins.int*"
main:8: note: Revealed type is "Any"
main:9: error: Incompatible types in assignment (expression has type "str", variable has type "int")
main:10: error: Incompatible types in assignment (expression has type "str", variable has type "Union[int, float]")
main:12: error: Incompatible types in assignment (expression has type "List[str]", variable has type "Sequence[Union[int, float]]")
main:13: error: Incompatible types in assignment (expression has type "List[<nothing>]", variable has type "Union[float, int, str, Combinable]")
main:15: error: Incompatible type for "redefined_set_type" of "MyModel" (got "str", expected "int")
main:15: error: Incompatible type for "redefined_union_set_type" of "MyModel" (got "str", expected "Union[int, float]")
main:15: error: Incompatible type for "redefined_array_set_type" of "MyModel" (got "int", expected "Sequence[Union[int, float]]")
main:15: error: Incompatible type for "default_set_type" of "MyModel" (got "List[Any]", expected "Union[float, int, str, Combinable]")
installed_apps:
- myapp
files:
- path: myapp/__init__.py
- path: myapp/models.py
content: |
from django.contrib.postgres.fields import ArrayField
from django.db import models
from typing import cast, List, Sequence, Union
class MyModel(models.Model):
redefined_set_type = cast("models.Field[int, int]", models.IntegerField())
redefined_union_set_type = cast("models.Field[Union[int, float], int]", models.IntegerField())
redefined_array_set_type = cast(
"ArrayField[Sequence[Union[int, float]], List[int]]",
ArrayField(base_field=models.IntegerField()),
)
default_set_type = models.IntegerField()
unset_set_type = cast("models.Field", models.IntegerField())