preliminary support for strict_optional

This commit is contained in:
Maxim Kurnikov
2019-02-17 18:07:53 +03:00
parent 6763217a80
commit e9f9202ed1
23 changed files with 614 additions and 343 deletions

View File

@@ -6,7 +6,7 @@ class User(models.Model):
array = ArrayField(base_field=models.Field())
user = User()
reveal_type(user.array) # E: Revealed type is 'builtins.list[Any]'
reveal_type(user.array) # E: Revealed type is 'builtins.list*[Any]'
[CASE array_field_base_field_parsed_into_generic_typevar]
from django.db import models
@@ -17,8 +17,8 @@ class User(models.Model):
members_as_text = ArrayField(base_field=models.CharField(max_length=255))
user = User()
reveal_type(user.members) # E: Revealed type is 'builtins.list[builtins.int*]'
reveal_type(user.members_as_text) # E: Revealed type is 'builtins.list[builtins.str*]'
reveal_type(user.members) # E: Revealed type is 'builtins.list*[builtins.int]'
reveal_type(user.members_as_text) # E: Revealed type is 'builtins.list*[builtins.str]'
[CASE test_model_fields_classes_present_as_primitives]
from django.db import models
@@ -31,13 +31,13 @@ class User(models.Model):
text = models.TextField()
user = User()
reveal_type(user.id) # E: Revealed type is 'builtins.int'
reveal_type(user.small_int) # E: Revealed type is 'builtins.int'
reveal_type(user.name) # E: Revealed type is 'builtins.str'
reveal_type(user.slug) # E: Revealed type is 'builtins.str'
reveal_type(user.text) # E: Revealed type is 'builtins.str'
reveal_type(user.id) # E: Revealed type is 'builtins.int*'
reveal_type(user.small_int) # E: Revealed type is 'builtins.int*'
reveal_type(user.name) # E: Revealed type is 'builtins.str*'
reveal_type(user.slug) # E: Revealed type is 'builtins.str*'
reveal_type(user.text) # E: Revealed type is 'builtins.str*'
[CASE test_model_field_classes_from_exciting_locations]
[CASE test_model_field_classes_from_existing_locations]
from django.db import models
from django.contrib.postgres import fields as pg_fields
from decimal import Decimal
@@ -48,9 +48,9 @@ class Booking(models.Model):
some_decimal = models.DecimalField(max_digits=10, decimal_places=5)
booking = Booking()
reveal_type(booking.id) # E: Revealed type is 'builtins.int'
reveal_type(booking.id) # E: Revealed type is 'builtins.int*'
reveal_type(booking.time_range) # E: Revealed type is 'Any'
reveal_type(booking.some_decimal) # E: Revealed type is 'decimal.Decimal'
reveal_type(booking.some_decimal) # E: Revealed type is 'decimal.Decimal*'
[CASE test_add_id_field_if_no_primary_key_defined]
from django.db import models
@@ -66,7 +66,7 @@ from django.db import models
class User(models.Model):
my_pk = models.IntegerField(primary_key=True)
reveal_type(User().my_pk) # E: Revealed type is 'builtins.int'
reveal_type(User().my_pk) # E: Revealed type is 'builtins.int*'
reveal_type(User().id) # E: Revealed type is 'Any'
[out]
@@ -102,5 +102,5 @@ class ParentModel(models.Model):
pass
class MyModel(ParentModel):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
reveal_type(MyModel().id) # E: Revealed type is 'uuid.UUID'
reveal_type(MyModel().id) # E: Revealed type is 'uuid.UUID*'
[out]

View File

@@ -31,4 +31,15 @@ class Child1(Parent1, Parent2):
value = models.IntegerField()
class Child4(Child1):
value4 = models.IntegerField()
Child4.objects.create(name1='n1', name2='n2', value=1, value4=4)
Child4.objects.create(name1='n1', name2='n2', value=1, value4=4)
[CASE create_through_related_manager_of_manytomany_field]
from django.db import models
class Publication(models.Model):
title = models.CharField(max_length=100)
class Article(models.Model):
publications = models.ManyToManyField(Publication)
article = Article.objects.create()
article.publications.create(title='my title')
[out]

View File

@@ -71,14 +71,15 @@ from django.db import models
class Publisher(models.Model):
pass
class PublisherWithCharPK(models.Model):
id = models.IntegerField(primary_key=True)
class PublisherDatetime(models.Model):
dt_pk = models.DateTimeField(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)
publisher_dt = models.ForeignKey(PublisherDatetime, on_delete=models.CASCADE)
Book(publisher_id=1, publisher_with_char_pk_id=1)
Book(publisher_id=1, publisher_with_char_pk_id='hello') # E: Incompatible type for "publisher_with_char_pk_id" of "Book" (got "str", expected "Union[int, Combinable, Literal['']]")
Book(publisher_id=1)
Book(publisher_id=[]) # E: Incompatible type for "publisher_id" of "Book" (got "List[Any]", expected "Union[Combinable, int, str]")
Book(publisher_dt_id=11) # E: Incompatible type for "publisher_dt_id" of "Book" (got "int", expected "Union[str, date, datetime, Combinable]")
[out]
[CASE setting_value_to_an_array_of_ints]
@@ -94,7 +95,7 @@ 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]")
MyModel(array=array_val3) # E: Incompatible type for "array" of "MyModel" (got "List[str]", expected "Union[Sequence[int], Combinable]")
[out]
[CASE if_no_explicit_primary_key_id_can_be_passed]
@@ -135,20 +136,6 @@ Restaurant(place_ptr=place)
Restaurant(place_ptr_id=place.id)
[out]
[CASE extract_type_of_init_param_from_set_method]
from typing import Union
from datetime import time
from django.db import models
class MyField(models.Field):
def __set__(self, instance, value: Union[str, time]) -> None: pass
def __get__(self, instance, owner) -> time: pass
class MyModel(models.Model):
field = MyField()
MyModel(field=time())
MyModel(field='12:00')
MyModel(field=100) # E: Incompatible type for "field" of "MyModel" (got "int", expected "Union[str, time]")
[CASE charfield_with_integer_choices]
from django.db import models
class MyModel(models.Model):

View File

@@ -0,0 +1,42 @@
[CASE nullable_field_with_strict_optional_true]
from django.db import models
class MyModel(models.Model):
text_nullable = models.CharField(max_length=100, null=True)
text = models.CharField(max_length=100)
reveal_type(MyModel().text) # E: Revealed type is 'builtins.str*'
reveal_type(MyModel().text_nullable) # E: Revealed type is 'Union[builtins.str, None]'
MyModel().text = None # E: Incompatible types in assignment (expression has type "None", variable has type "Union[str, int, Combinable]")
MyModel().text_nullable = None
[out]
[CASE nullable_array_field]
from django.db import models
from django.contrib.postgres.fields import ArrayField
class MyModel(models.Model):
lst = ArrayField(base_field=models.CharField(max_length=100), null=True)
reveal_type(MyModel().lst) # E: Revealed type is 'Union[builtins.list[builtins.str], None]'
[out]
[CASE nullable_foreign_key]
from django.db import models
class Publisher(models.Model):
pass
class Book(models.Model):
publisher = models.ForeignKey(to=Publisher, on_delete=models.CASCADE, null=True)
reveal_type(Book().publisher) # E: Revealed type is 'Union[main.Publisher, None]'
Book().publisher = 11 # E: Incompatible types in assignment (expression has type "int", variable has type "Union[Publisher, Combinable, None]")
[out]
[CASE nullable_self_foreign_key]
from django.db import models
class Inventory(models.Model):
parent = models.ForeignKey('self', on_delete=models.SET_NULL, null=True)
parent = Inventory()
core = Inventory(parent_id=parent.id)
reveal_type(core.parent_id) # E: Revealed type is 'Union[builtins.int, None]'
reveal_type(core.parent) # E: Revealed type is 'Union[main.Inventory, None]'
Inventory(parent=None)
Inventory(parent_id=None)
[out]

View File

@@ -198,7 +198,7 @@ class App(models.Model):
pass
class Member(models.Model):
apps = models.ManyToManyField(to=App, related_name='members')
reveal_type(Member().apps) # E: Revealed type is 'django.db.models.manager.RelatedManager[main.App*]'
reveal_type(Member().apps) # E: Revealed type is 'django.db.models.manager.RelatedManager*[main.App]'
reveal_type(App().members) # E: Revealed type is 'django.db.models.manager.RelatedManager[main.Member]'
[out]
@@ -207,7 +207,7 @@ from django.db import models
from myapp.models import App
class Member(models.Model):
apps = models.ManyToManyField(to='myapp.App', related_name='members')
reveal_type(Member().apps) # E: Revealed type is 'django.db.models.manager.RelatedManager[myapp.models.App*]'
reveal_type(Member().apps) # E: Revealed type is 'django.db.models.manager.RelatedManager*[myapp.models.App]'
[file myapp/__init__.py]
[file myapp/models.py]
@@ -226,8 +226,8 @@ reveal_type(User().parent) # E: Revealed type is 'main.User*'
[CASE many_to_many_with_self]
from django.db import models
class User(models.Model):
friends = models.ManyToManyField('self', on_delete=models.CASCADE)
reveal_type(User().friends) # E: Revealed type is 'django.db.models.manager.RelatedManager[main.User*]'
friends = models.ManyToManyField('self')
reveal_type(User().friends) # E: Revealed type is 'django.db.models.manager.RelatedManager*[main.User]'
[out]
[CASE recursively_checking_for_base_model_in_to_parameter]
@@ -274,4 +274,4 @@ Book2(publisher_id=1)
Book2(publisher_id='hello') # E: Incompatible type for "publisher_id" of "Book2" (got "str", expected "Union[int, Combinable, Literal['']]")
Book2.objects.create(publisher_id=1)
Book2.objects.create(publisher_id='hello') # E: Incompatible type for "publisher_id" of "Book2" (got "str", expected "Union[int, Combinable, Literal['']]")
[out]
[out]