add Model.__init__ typechecking

This commit is contained in:
Maxim Kurnikov
2019-02-08 17:16:03 +03:00
parent dead370244
commit 916df1efb6
16 changed files with 359 additions and 108 deletions

View File

@@ -93,4 +93,4 @@ class Abstract(models.Model):
abstract = True
class User(Abstract):
id = models.AutoField(primary_key=True)
[out]
[out]

View File

@@ -0,0 +1,106 @@
[CASE arguments_to_init_unexpected_attributes]
from django.db import models
class MyUser(models.Model):
pass
user = MyUser(name=1, age=12)
[out]
main:5: error: Unexpected attribute "name" for model "MyUser"
main:5: error: Unexpected attribute "age" for model "MyUser"
[CASE arguments_to_init_from_class_incompatible_type]
from django.db import models
class MyUser(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
user = MyUser(name=1, age=12)
[out]
main:6: error: Incompatible type for "name" of "MyUser" (got "int", expected "str")
[CASE arguments_to_init_combined_from_base_classes]
from django.db import models
class BaseUser(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
class ChildUser(BaseUser):
lastname = models.CharField(max_length=100)
user = ChildUser(name='Max', age=12, lastname='Lastname')
[out]
[CASE fields_from_abstract_user_propagate_to_init]
from django.contrib.auth.models import AbstractUser
class MyUser(AbstractUser):
pass
user = MyUser(username='maxim', password='password', first_name='Max', last_name='MaxMax')
[out]
[CASE generic_foreign_key_field_no_typechecking]
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
class MyUser(models.Model):
content_object = GenericForeignKey()
user = MyUser(content_object=1)
[out]
[CASE pk_refers_to_primary_key_and_could_be_passed_to_init]
from django.db import models
class MyUser1(models.Model):
mypk = models.CharField(primary_key=True)
class MyUser2(models.Model):
pass
user2 = MyUser1(pk='hello')
user3= MyUser2(pk=1)
[out]
[CASE typechecking_of_pk]
from django.db import models
class MyUser1(models.Model):
mypk = models.CharField(primary_key=True)
user = MyUser1(pk=1) # E: Incompatible type for "pk" of "MyUser1" (got "int", expected "str")
[out]
[CASE can_set_foreign_key_by_its_primary_key]
from django.db import models
class Publisher(models.Model):
pass
class PublisherWithCharPK(models.Model):
id = models.CharField(max_length=100, primary_key=True)
class Book(models.Model):
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
publisher_with_char_pk = models.ForeignKey(PublisherWithCharPK, on_delete=models.CASCADE)
Book(publisher_id=1, publisher_with_char_pk_id='hello')
Book(publisher_id=1, publisher_with_char_pk_id=1) # E: Incompatible type for "publisher_with_char_pk_id" of "Book" (got "int", expected "str")
[out]
[CASE setting_value_to_an_array_of_ints]
from typing import List, Tuple
from django.db import models
from django.contrib.postgres.fields import ArrayField
class MyModel(models.Model):
array = ArrayField(base_field=models.IntegerField())
array_val: Tuple[int, ...] = (1,)
MyModel(array=array_val)
array_val2: List[int] = [1]
MyModel(array=array_val2)
array_val3: List[str] = ['hello']
MyModel(array=array_val3) # E: Incompatible type for "array" of "MyModel" (got "List[str]", expected "Sequence[int]")
[out]
[CASE if_no_explicit_primary_key_id_can_be_passed]
from django.db import models
class MyModel(models.Model):
pass
MyModel(id=1)
[out]