mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-06 20:24:31 +08:00
remove -semanal suffix
This commit is contained in:
5
test-data/plugins.ini
Normal file
5
test-data/plugins.ini
Normal file
@@ -0,0 +1,5 @@
|
||||
[mypy]
|
||||
incremental = True
|
||||
strict_optional = True
|
||||
plugins =
|
||||
mypy_django_plugin.main
|
||||
129
test-data/typecheck/fields/test_base.yml
Normal file
129
test-data/typecheck/fields/test_base.yml
Normal file
@@ -0,0 +1,129 @@
|
||||
- case: test_model_fields_classes_present_as_primitives
|
||||
main: |
|
||||
from myapp.models import User
|
||||
user = User(small_int=1, name='user', slug='user', text='user')
|
||||
reveal_type(user.id) # N: Revealed type is 'builtins.int*'
|
||||
reveal_type(user.small_int) # N: Revealed type is 'builtins.int*'
|
||||
reveal_type(user.name) # N: Revealed type is 'builtins.str*'
|
||||
reveal_type(user.slug) # N: Revealed type is 'builtins.str*'
|
||||
reveal_type(user.text) # N: Revealed type is 'builtins.str*'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
small_int = models.SmallIntegerField()
|
||||
name = models.CharField(max_length=255)
|
||||
slug = models.SlugField(max_length=255)
|
||||
text = models.TextField()
|
||||
|
||||
- case: test_model_field_classes_from_existing_locations
|
||||
main: |
|
||||
from myapp.models import Booking
|
||||
booking = Booking()
|
||||
reveal_type(booking.id) # N: Revealed type is 'builtins.int*'
|
||||
reveal_type(booking.time_range) # N: Revealed type is 'Any'
|
||||
reveal_type(booking.some_decimal) # N: Revealed type is 'decimal.Decimal*'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
from django.contrib.postgres import fields as pg_fields
|
||||
from decimal import Decimal
|
||||
|
||||
class Booking(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
time_range = pg_fields.DateTimeRangeField(null=False)
|
||||
some_decimal = models.DecimalField(max_digits=10, decimal_places=5)
|
||||
|
||||
- case: test_add_id_field_if_no_primary_key_defined
|
||||
disable_cache: true
|
||||
main: |
|
||||
from myapp.models import User
|
||||
reveal_type(User().id) # N: Revealed type is 'builtins.int*'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
pass
|
||||
|
||||
- case: test_do_not_add_id_if_field_with_primary_key_True_defined
|
||||
disable_cache: true
|
||||
main: |
|
||||
from myapp.models import User
|
||||
reveal_type(User().my_pk) # N: Revealed type is 'builtins.int*'
|
||||
reveal_type(User().id)
|
||||
out: |
|
||||
main:3: note: Revealed type is 'Any'
|
||||
main:3: error: "User" has no attribute "id"
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
my_pk = models.IntegerField(primary_key=True)
|
||||
|
||||
- case: test_primary_key_on_optional_queryset_method
|
||||
main: |
|
||||
from myapp.models import User
|
||||
reveal_type(User.objects.first().id)
|
||||
out: |
|
||||
main:2: note: Revealed type is 'Union[builtins.int*, Any]'
|
||||
main:2: error: Item "None" of "Optional[User]" has no attribute "id"
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
pass
|
||||
|
||||
- case: blank_and_null_char_field_allows_none
|
||||
main: |
|
||||
from myapp.models import MyModel
|
||||
MyModel(nulltext="")
|
||||
MyModel(nulltext=None)
|
||||
MyModel().nulltext=None
|
||||
reveal_type(MyModel().nulltext) # N: Revealed type is 'Union[builtins.str, None]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class MyModel(models.Model):
|
||||
nulltext=models.CharField(max_length=1, blank=True, null=True)
|
||||
|
||||
- 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="")
|
||||
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*'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class MyModel(models.Model):
|
||||
notnulltext=models.CharField(max_length=1, blank=True, null=False)
|
||||
70
test-data/typecheck/fields/test_nullable.yml
Normal file
70
test-data/typecheck/fields/test_nullable.yml
Normal file
@@ -0,0 +1,70 @@
|
||||
- case: nullable_field_with_strict_optional_true
|
||||
main: |
|
||||
from myapp.models import MyModel
|
||||
reveal_type(MyModel().text) # N: Revealed type is 'builtins.str*'
|
||||
reveal_type(MyModel().text_nullable) # N: 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
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class MyModel(models.Model):
|
||||
text_nullable = models.CharField(max_length=100, null=True)
|
||||
text = models.CharField(max_length=100)
|
||||
|
||||
- case: nullable_array_field
|
||||
main: |
|
||||
from myapp.models import MyModel
|
||||
reveal_type(MyModel().lst) # N: Revealed type is 'Union[builtins.list[builtins.str], None]'
|
||||
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):
|
||||
lst = ArrayField(base_field=models.CharField(max_length=100), null=True)
|
||||
|
||||
- case: nullable_foreign_key
|
||||
main: |
|
||||
from myapp.models import Publisher, Book
|
||||
reveal_type(Book().publisher) # N: Revealed type is 'Union[myapp.models.Publisher, None]'
|
||||
Book().publisher = 11 # E: Incompatible types in assignment (expression has type "int", variable has type "Union[Publisher, Combinable, None]")
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
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)
|
||||
|
||||
- case: nullable_self_foreign_key
|
||||
main: |
|
||||
from myapp.models import Inventory
|
||||
parent = Inventory()
|
||||
core = Inventory(parent_id=parent.id)
|
||||
reveal_type(core.parent_id) # N: Revealed type is 'Union[builtins.int, None]'
|
||||
reveal_type(core.parent) # N: Revealed type is 'Union[myapp.models.Inventory, None]'
|
||||
Inventory(parent=None)
|
||||
Inventory(parent_id=None)
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Inventory(models.Model):
|
||||
parent = models.ForeignKey('self', on_delete=models.SET_NULL, null=True)
|
||||
35
test-data/typecheck/fields/test_postgres_fields.yml
Normal file
35
test-data/typecheck/fields/test_postgres_fields.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
- case: array_field_descriptor_access
|
||||
main: |
|
||||
from myapp.models import User
|
||||
user = User(array=[])
|
||||
reveal_type(user.array) # N: Revealed type is 'builtins.list*[Any]'
|
||||
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 User(models.Model):
|
||||
array = ArrayField(base_field=models.Field())
|
||||
|
||||
- case: array_field_base_field_parsed_into_generic_typevar
|
||||
main: |
|
||||
from myapp.models import User
|
||||
user = User()
|
||||
reveal_type(user.members) # N: Revealed type is 'builtins.list*[builtins.int]'
|
||||
reveal_type(user.members_as_text) # N: Revealed type is 'builtins.list*[builtins.str]'
|
||||
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 User(models.Model):
|
||||
members = ArrayField(base_field=models.IntegerField())
|
||||
members_as_text = ArrayField(base_field=models.CharField(max_length=255))
|
||||
414
test-data/typecheck/fields/test_related.yml
Normal file
414
test-data/typecheck/fields/test_related.yml
Normal file
@@ -0,0 +1,414 @@
|
||||
- case: test_foreign_key_field_with_related_name
|
||||
main: |
|
||||
from myapp.models import Book, Publisher
|
||||
book = Book()
|
||||
reveal_type(book.publisher) # N: Revealed type is 'myapp.models.Publisher*'
|
||||
publisher = Publisher()
|
||||
reveal_type(publisher.books) # N: Revealed type is 'django.db.models.manager.RelatedManager[myapp.models.Book]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Publisher(models.Model):
|
||||
pass
|
||||
class Book(models.Model):
|
||||
publisher = models.ForeignKey(to=Publisher, on_delete=models.CASCADE,
|
||||
related_name='books')
|
||||
|
||||
- case: foreign_key_field_creates_attribute_with_underscore_id
|
||||
main: |
|
||||
from myapp.models import Book
|
||||
book = Book()
|
||||
reveal_type(book.publisher_id) # N: Revealed type is 'builtins.int*'
|
||||
reveal_type(book.owner_id) # N: Revealed type is 'builtins.int*'
|
||||
installed_apps:
|
||||
- django.contrib.contenttypes
|
||||
- django.contrib.auth
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Publisher(models.Model):
|
||||
pass
|
||||
class Book(models.Model):
|
||||
publisher = models.ForeignKey(to=Publisher, on_delete=models.CASCADE)
|
||||
owner = models.ForeignKey(db_column='model_id', to='auth.User', on_delete=models.CASCADE)
|
||||
|
||||
- case: foreign_key_field_different_order_of_params
|
||||
main: |
|
||||
from myapp.models import Book, Publisher
|
||||
book = Book()
|
||||
reveal_type(book.publisher) # N: Revealed type is 'myapp.models.Publisher*'
|
||||
reveal_type(book.publisher2) # N: Revealed type is 'myapp.models.Publisher*'
|
||||
|
||||
publisher = Publisher()
|
||||
reveal_type(publisher.books) # N: Revealed type is 'django.db.models.manager.RelatedManager[myapp.models.Book]'
|
||||
reveal_type(publisher.books2) # N: Revealed type is 'django.db.models.manager.RelatedManager[myapp.models.Book]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Publisher(models.Model):
|
||||
pass
|
||||
class Book(models.Model):
|
||||
publisher = models.ForeignKey(on_delete=models.CASCADE, to=Publisher,
|
||||
related_name='books')
|
||||
publisher2 = models.ForeignKey(to=Publisher, related_name='books2', on_delete=models.CASCADE)
|
||||
|
||||
- case: to_parameter_as_string_with_application_name__model_imported
|
||||
main: |
|
||||
from myapp2.models import Book
|
||||
book = Book()
|
||||
reveal_type(book.publisher) # N: Revealed type is 'myapp.models.Publisher*'
|
||||
installed_apps:
|
||||
- myapp
|
||||
- myapp2
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Publisher(models.Model):
|
||||
pass
|
||||
- path: myapp2/__init__.py
|
||||
- path: myapp2/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Book(models.Model):
|
||||
publisher = models.ForeignKey(to='myapp.Publisher', on_delete=models.CASCADE)
|
||||
|
||||
- case: test_circular_dependency_in_imports_with_foreign_key
|
||||
main: |
|
||||
from myapp import models
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class App(models.Model):
|
||||
def method(self) -> None:
|
||||
reveal_type(self.views) # N: Revealed type is 'django.db.models.manager.RelatedManager[myapp.models.View]'
|
||||
reveal_type(self.members) # N: Revealed type is 'django.db.models.manager.RelatedManager[myapp.models.Member]'
|
||||
reveal_type(self.sheets) # N: Revealed type is 'django.db.models.manager.RelatedManager[myapp.models.Sheet]'
|
||||
reveal_type(self.profile) # N: Revealed type is 'myapp.models.Profile'
|
||||
class View(models.Model):
|
||||
app = models.ForeignKey(to=App, related_name='views', on_delete=models.CASCADE)
|
||||
class Member(models.Model):
|
||||
app = models.ForeignKey(related_name='members', on_delete=models.CASCADE, to=App)
|
||||
class Sheet(models.Model):
|
||||
app = models.ForeignKey(App, related_name='sheets', on_delete=models.CASCADE)
|
||||
class Profile(models.Model):
|
||||
app = models.OneToOneField(App, related_name='profile', on_delete=models.CASCADE)
|
||||
|
||||
- case: test_circular_dependency_in_imports_with_string_based
|
||||
main: |
|
||||
from myapp.models import View
|
||||
reveal_type(View().app.views) # N: Revealed type is 'django.db.models.manager.RelatedManager[myapp.models.View]'
|
||||
reveal_type(View().app.unknown)
|
||||
out: |
|
||||
main:3: note: Revealed type is 'Any'
|
||||
main:3: error: "App" has no attribute "unknown"
|
||||
installed_apps:
|
||||
- myapp
|
||||
- myapp2
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
from myapp2.models import App
|
||||
class View(models.Model):
|
||||
app = models.ForeignKey(to=App, related_name='views', on_delete=models.CASCADE)
|
||||
- path: myapp2/__init__.py
|
||||
- path: myapp2/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class App(models.Model):
|
||||
def method(self) -> None:
|
||||
reveal_type(self.views) # N: Revealed type is 'django.db.models.manager.RelatedManager[myapp.models.View]'
|
||||
|
||||
- case: models_related_managers_work_with_direct_model_inheritance_and_with_inheritance_from_other_model
|
||||
main: |
|
||||
from myapp.models import App
|
||||
reveal_type(App().views) # N: Revealed type is 'django.db.models.manager.RelatedManager[myapp.models.View]'
|
||||
reveal_type(App().views2) # N: Revealed type is 'django.db.models.manager.RelatedManager[myapp.models.View2]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class App(models.Model):
|
||||
pass
|
||||
class View(models.Model):
|
||||
app = models.ForeignKey(to=App, on_delete=models.CASCADE, related_name='views')
|
||||
class View2(View):
|
||||
app2 = models.ForeignKey(to=App, on_delete=models.CASCADE, related_name='views2')
|
||||
|
||||
- case: models_imported_inside_init_file_foreign_key
|
||||
main: |
|
||||
from myapp2.models import View
|
||||
reveal_type(View().app.views) # N: Revealed type is 'django.db.models.manager.RelatedManager[myapp2.models.View]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
- myapp2
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models/__init__.py
|
||||
content: |
|
||||
from .app import App
|
||||
- path: myapp/models/app.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class App(models.Model):
|
||||
pass
|
||||
- path: myapp2/__init__.py
|
||||
- path: myapp2/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
from myapp.models import App
|
||||
class View(models.Model):
|
||||
app = models.ForeignKey(to='myapp.App', related_name='views', on_delete=models.CASCADE)
|
||||
|
||||
- case: models_imported_inside_init_file_one_to_one_field
|
||||
main: |
|
||||
from myapp2.models import Profile
|
||||
reveal_type(Profile().user.profile) # N: Revealed type is 'myapp2.models.Profile'
|
||||
installed_apps:
|
||||
- myapp
|
||||
- myapp2
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models/__init__.py
|
||||
content: |
|
||||
from .user import User
|
||||
- path: myapp/models/user.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
pass
|
||||
- path: myapp2/__init__.py
|
||||
- path: myapp2/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
from myapp.models import User
|
||||
class Profile(models.Model):
|
||||
user = models.OneToOneField(to='myapp.User', related_name='profile', on_delete=models.CASCADE)
|
||||
|
||||
- case: models_triple_circular_reference
|
||||
main: |
|
||||
from myapp.models import App
|
||||
reveal_type(App().owner) # N: Revealed type is 'myapp.models.user.User*'
|
||||
reveal_type(App().owner.profile) # N: Revealed type is 'myapp.models.profile.Profile'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models/__init__.py
|
||||
content: |
|
||||
from .user import User
|
||||
from .profile import Profile
|
||||
from .app import App
|
||||
- path: myapp/models/user.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
pass
|
||||
- path: myapp/models/profile.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Profile(models.Model):
|
||||
user = models.OneToOneField(to='myapp.User', related_name='profile', on_delete=models.CASCADE)
|
||||
- path: myapp/models/app.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class App(models.Model):
|
||||
owner = models.ForeignKey(to='myapp.User', on_delete=models.CASCADE, related_name='apps')
|
||||
|
||||
- case: many_to_many_field_converts_to_queryset_of_model_type
|
||||
main: |
|
||||
from myapp.models import App, Member
|
||||
reveal_type(Member().apps) # N: Revealed type is 'django.db.models.manager.RelatedManager*[myapp.models.App]'
|
||||
reveal_type(App().members) # N: Revealed type is 'django.db.models.manager.RelatedManager[myapp.models.Member]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class App(models.Model):
|
||||
pass
|
||||
class Member(models.Model):
|
||||
apps = models.ManyToManyField(to=App, related_name='members')
|
||||
|
||||
- case: many_to_many_works_with_string_if_imported
|
||||
main: |
|
||||
from myapp.models import Member
|
||||
reveal_type(Member().apps) # N: Revealed type is 'django.db.models.manager.RelatedManager*[myapp2.models.App]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
- myapp2
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Member(models.Model):
|
||||
apps = models.ManyToManyField(to='myapp2.App', related_name='members')
|
||||
- path: myapp2/__init__.py
|
||||
- path: myapp2/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class App(models.Model):
|
||||
pass
|
||||
|
||||
- case: foreign_key_with_self
|
||||
main: |
|
||||
from myapp.models import User
|
||||
reveal_type(User().parent) # N: Revealed type is 'myapp.models.User*'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
parent = models.ForeignKey('self', on_delete=models.CASCADE)
|
||||
|
||||
- case: many_to_many_with_self
|
||||
main: |
|
||||
from myapp.models import User
|
||||
reveal_type(User().friends) # N: Revealed type is 'django.db.models.manager.RelatedManager*[myapp.models.User]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
friends = models.ManyToManyField('self')
|
||||
|
||||
- case: recursively_checking_for_base_model_in_to_parameter
|
||||
main: |
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
|
||||
class BaseModel(models.Model):
|
||||
pass
|
||||
class ParkingSpot(BaseModel):
|
||||
pass
|
||||
class Booking(BaseModel):
|
||||
parking_spot = models.ForeignKey(to=ParkingSpot, null=True, on_delete=models.SET_NULL)
|
||||
|
||||
- case: if_no_related_name_is_passed_create_default_related_managers
|
||||
main: |
|
||||
from myapp.models import Publisher
|
||||
reveal_type(Publisher().book_set) # N: Revealed type is 'django.db.models.manager.RelatedManager[myapp.models.Book]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Publisher(models.Model):
|
||||
pass
|
||||
class Book(models.Model):
|
||||
publisher = models.ForeignKey(to=Publisher, on_delete=models.CASCADE)
|
||||
|
||||
- case: underscore_id_attribute_has_set_type_of_primary_key_if_explicit
|
||||
main: |
|
||||
import datetime
|
||||
from myapp.models import Book, Book2
|
||||
|
||||
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.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.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:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
import datetime
|
||||
class Publisher(models.Model):
|
||||
mypk = models.CharField(max_length=100, primary_key=True)
|
||||
class Book(models.Model):
|
||||
publisher = models.ForeignKey(to=Publisher, on_delete=models.CASCADE)
|
||||
|
||||
class Publisher2(models.Model):
|
||||
mypk = models.IntegerField(primary_key=True)
|
||||
class Book2(models.Model):
|
||||
publisher = models.ForeignKey(to=Publisher2, on_delete=models.CASCADE)
|
||||
|
||||
- case: if_model_is_defined_as_name_of_the_class_look_for_it_in_the_same_file
|
||||
main: |
|
||||
from myapp.models import Book
|
||||
reveal_type(Book().publisher) # N: Revealed type is 'myapp.models.Publisher*'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Book(models.Model):
|
||||
publisher = models.ForeignKey(to='Publisher', on_delete=models.CASCADE)
|
||||
class Publisher(models.Model):
|
||||
pass
|
||||
|
||||
- case: test_foreign_key_field_without_backwards_relation
|
||||
main: |
|
||||
from myapp.models import Book, Publisher
|
||||
book = Book()
|
||||
reveal_type(book.publisher) # N: Revealed type is 'myapp.models.Publisher*'
|
||||
|
||||
publisher = Publisher()
|
||||
reveal_type(publisher.books)
|
||||
reveal_type(publisher.books2) # N: Revealed type is 'django.db.models.manager.RelatedManager[myapp.models.Book]'
|
||||
out: |
|
||||
main:6: error: "Publisher" has no attribute "books"; maybe "books2"?
|
||||
main:6: note: Revealed type is 'Any'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Publisher(models.Model):
|
||||
pass
|
||||
class Book(models.Model):
|
||||
publisher = models.ForeignKey(to=Publisher, on_delete=models.CASCADE,
|
||||
related_name='+')
|
||||
publisher2 = models.ForeignKey(to=Publisher, on_delete=models.CASCADE,
|
||||
related_name='books2')
|
||||
@@ -0,0 +1,31 @@
|
||||
- case: queryset_basic_methods_return_type
|
||||
main: |
|
||||
from myapp.models import Blog
|
||||
|
||||
qs = Blog.objects.all()
|
||||
reveal_type(qs) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.Blog*, myapp.models.Blog*]'
|
||||
reveal_type(qs.get(id=1)) # N: Revealed type is 'myapp.models.Blog*'
|
||||
reveal_type(iter(qs)) # N: Revealed type is 'typing.Iterator[myapp.models.Blog*]'
|
||||
reveal_type(qs.iterator()) # N: Revealed type is 'typing.Iterator[myapp.models.Blog*]'
|
||||
reveal_type(qs.first()) # N: Revealed type is 'Union[myapp.models.Blog*, None]'
|
||||
reveal_type(qs.earliest()) # N: Revealed type is 'myapp.models.Blog*'
|
||||
reveal_type(qs[0]) # N: Revealed type is 'myapp.models.Blog*'
|
||||
reveal_type(qs[:9]) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.Blog*, myapp.models.Blog*]'
|
||||
reveal_type(qs.in_bulk()) # N: Revealed type is 'builtins.dict[Any, myapp.models.Blog*]'
|
||||
|
||||
# .dates / .datetimes
|
||||
reveal_type(Blog.objects.dates("created_at", "day")) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.Blog*, datetime.date]'
|
||||
reveal_type(Blog.objects.datetimes("created_at", "day")) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.Blog*, datetime.datetime]'
|
||||
|
||||
# AND-ing QuerySets
|
||||
reveal_type(Blog.objects.all() & Blog.objects.all()) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.Blog*, myapp.models.Blog*]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
|
||||
class Blog(models.Model):
|
||||
created_at = models.DateTimeField()
|
||||
62
test-data/typecheck/managers/querysets/test_values.yml
Normal file
62
test-data/typecheck/managers/querysets/test_values.yml
Normal file
@@ -0,0 +1,62 @@
|
||||
- case: queryset_values_method_returns_typeddict
|
||||
main: |
|
||||
from myapp.models import Blog
|
||||
values = Blog.objects.values('num_posts', 'text').get()
|
||||
reveal_type(values) # N: Revealed type is 'TypedDict({'num_posts': builtins.int, 'text': builtins.str})'
|
||||
reveal_type(values["num_posts"]) # N: Revealed type is 'builtins.int'
|
||||
reveal_type(values["text"]) # N: Revealed type is 'builtins.str'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Blog(models.Model):
|
||||
num_posts = models.IntegerField()
|
||||
text = models.CharField(max_length=100)
|
||||
|
||||
- case: queryset_values_all_values
|
||||
main: |
|
||||
from myapp.models import Blog
|
||||
all_values_dict = Blog.objects.values().get()
|
||||
reveal_type(all_values_dict) # N: Revealed type is 'TypedDict({'id': builtins.int, 'num_posts': builtins.int, 'text': builtins.str})'
|
||||
reveal_type(all_values_dict["id"]) # N: Revealed type is 'builtins.int'
|
||||
reveal_type(all_values_dict["num_posts"]) # N: Revealed type is 'builtins.int'
|
||||
reveal_type(all_values_dict["text"]) # N: Revealed type is 'builtins.str'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Blog(models.Model):
|
||||
num_posts = models.IntegerField()
|
||||
text = models.CharField(max_length=100)
|
||||
|
||||
- case: queryset_foreign_key_object_always_a_primary_key
|
||||
main: |
|
||||
from myapp.models import Blog
|
||||
values1 = Blog.objects.values('publisher').get()
|
||||
reveal_type(values1) # N: Revealed type is 'TypedDict({'publisher': builtins.int})'
|
||||
reveal_type(values1['publisher']) # N: Revealed type is 'builtins.int'
|
||||
|
||||
values2 = Blog.objects.values('publisher_id').get()
|
||||
reveal_type(values2) # N: Revealed type is 'TypedDict({'publisher_id': builtins.int})'
|
||||
reveal_type(values2["publisher_id"]) # N: Revealed type is 'builtins.int'
|
||||
|
||||
# all values return _id version
|
||||
all_values = Blog.objects.values().get()
|
||||
reveal_type(all_values) # N: Revealed type is 'TypedDict({'id': builtins.int, 'publisher_id': builtins.int})'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Publisher(models.Model):
|
||||
pass
|
||||
class Blog(models.Model):
|
||||
publisher = models.ForeignKey(to=Publisher, on_delete=models.CASCADE)
|
||||
142
test-data/typecheck/managers/querysets/test_values_list.yml
Normal file
142
test-data/typecheck/managers/querysets/test_values_list.yml
Normal file
@@ -0,0 +1,142 @@
|
||||
- case: values_list_simple_field
|
||||
main: |
|
||||
from myapp.models import MyUser
|
||||
reveal_type(MyUser.objects.values_list('name').get()) # N: Revealed type is 'Tuple[builtins.str]'
|
||||
reveal_type(MyUser.objects.values_list('id', 'name').get()) # N: Revealed type is 'Tuple[builtins.int, builtins.str]'
|
||||
|
||||
values_tuple = MyUser.objects.values_list('name', 'age').get()
|
||||
reveal_type(values_tuple[0]) # N: Revealed type is 'builtins.str'
|
||||
reveal_type(values_tuple[1]) # N: Revealed type is 'builtins.int'
|
||||
|
||||
# no fields specified return all fields
|
||||
all_values_tuple = MyUser.objects.values_list().get()
|
||||
reveal_type(all_values_tuple) # N: Revealed type is 'Tuple[builtins.int, builtins.str, builtins.int]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class MyUser(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
age = models.IntegerField()
|
||||
|
||||
- case: values_list_related_model_fields
|
||||
main: |
|
||||
from myapp.models import Post
|
||||
values_tuple = Post.objects.values_list('blog', 'blog__num_posts', 'blog__publisher', 'blog__publisher__name').get()
|
||||
reveal_type(values_tuple[0]) # N: Revealed type is 'myapp.models.Blog'
|
||||
reveal_type(values_tuple[1]) # N: Revealed type is 'builtins.int'
|
||||
reveal_type(values_tuple[2]) # N: Revealed type is 'myapp.models.Publisher'
|
||||
reveal_type(values_tuple[3]) # N: Revealed type is 'builtins.str'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Publisher(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
class Blog(models.Model):
|
||||
num_posts = models.IntegerField()
|
||||
publisher = models.ForeignKey(to=Publisher, on_delete=models.CASCADE)
|
||||
class Post(models.Model):
|
||||
blog = models.ForeignKey(to=Blog, on_delete=models.CASCADE)
|
||||
|
||||
- case: values_list_flat_true
|
||||
main: |
|
||||
from myapp.models import MyUser, MyUser2
|
||||
reveal_type(MyUser.objects.values_list('name', flat=True).get()) # N: Revealed type is 'builtins.str*'
|
||||
reveal_type(MyUser.objects.values_list('name', 'age', flat=True).get())
|
||||
|
||||
# flat=True without specified fields returns primary key values
|
||||
reveal_type(MyUser.objects.values_list(flat=True)[0]) # N: Revealed type is 'builtins.int*'
|
||||
reveal_type(MyUser2.objects.values_list(flat=True)[0]) # N: Revealed type is 'builtins.str*'
|
||||
out: |
|
||||
main:3: error: 'flat' is not valid when 'values_list' is called with more than one field
|
||||
main:3: note: Revealed type is 'Any'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class MyUser(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
age = models.IntegerField()
|
||||
class MyUser2(models.Model):
|
||||
name = models.CharField(max_length=100, primary_key=True)
|
||||
|
||||
- case: values_list_named_true
|
||||
main: |
|
||||
from myapp.models import MyUser
|
||||
values_named_tuple = MyUser.objects.values_list('name', 'age', named=True).get()
|
||||
reveal_type(values_named_tuple) # N: Revealed type is 'Tuple[builtins.str, builtins.int, fallback=main.Row]'
|
||||
reveal_type(values_named_tuple.name) # N: Revealed type is 'builtins.str'
|
||||
reveal_type(values_named_tuple.age) # N: Revealed type is 'builtins.int'
|
||||
|
||||
# no fields specified, returns all fields namedtuple
|
||||
all_values_named_tuple = MyUser.objects.values_list(named=True).get()
|
||||
reveal_type(all_values_named_tuple.id) # N: Revealed type is 'builtins.int'
|
||||
reveal_type(all_values_named_tuple.name) # N: Revealed type is 'builtins.str'
|
||||
reveal_type(all_values_named_tuple.age) # N: Revealed type is 'builtins.int'
|
||||
reveal_type(all_values_named_tuple.is_admin) # N: Revealed type is 'builtins.bool'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class MyUser(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
age = models.IntegerField()
|
||||
is_admin = models.BooleanField()
|
||||
|
||||
- case: values_list_flat_true_named_true_error
|
||||
main: |
|
||||
from myapp.models import MyUser
|
||||
reveal_type(MyUser.objects.values_list('name', flat=True, named=True).get())
|
||||
out: |
|
||||
main:2: error: 'flat' and 'named' can't be used together
|
||||
main:2: note: Revealed type is 'Any'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class MyUser(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
|
||||
- case: invalid_lookups
|
||||
main: |
|
||||
from myapp.models import Blog
|
||||
reveal_type(Blog.objects.values_list('unknown').get())
|
||||
reveal_type(Blog.objects.values_list('unknown', flat=True).get())
|
||||
reveal_type(Blog.objects.values_list('unknown', named=True).get())
|
||||
reveal_type(Blog.objects.values_list('publisher__unknown').get())
|
||||
out: |
|
||||
main:2: error: Cannot resolve keyword 'unknown' into field. Choices are: id, publisher, publisher_id
|
||||
main:2: note: Revealed type is 'Any'
|
||||
main:3: error: Cannot resolve keyword 'unknown' into field. Choices are: id, publisher, publisher_id
|
||||
main:3: note: Revealed type is 'Any'
|
||||
main:4: error: Cannot resolve keyword 'unknown' into field. Choices are: id, publisher, publisher_id
|
||||
main:4: note: Revealed type is 'Any'
|
||||
main:5: error: Lookups not supported yet
|
||||
main:5: note: Revealed type is 'Any'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Publisher(models.Model):
|
||||
pass
|
||||
class Blog(models.Model):
|
||||
publisher = models.ForeignKey(to=Publisher, on_delete=models.CASCADE)
|
||||
293
test-data/typecheck/managers/test_managers.yml
Normal file
293
test-data/typecheck/managers/test_managers.yml
Normal file
@@ -0,0 +1,293 @@
|
||||
- case: test_every_model_has_objects_queryset_available
|
||||
main: |
|
||||
from myapp.models import User
|
||||
reveal_type(User.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.User]'
|
||||
reveal_type(User.objects.get()) # N: Revealed type is 'myapp.models.User*'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
pass
|
||||
|
||||
- case: every_model_has_its_own_objects_queryset
|
||||
main: |
|
||||
from myapp.models import Parent, Child
|
||||
reveal_type(Parent.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.Parent]'
|
||||
reveal_type(Child.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.Child]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Parent(models.Model):
|
||||
pass
|
||||
class Child(Parent):
|
||||
pass
|
||||
|
||||
- case: if_manager_is_defined_on_model_do_not_add_objects
|
||||
main: |
|
||||
from myapp.models import MyModel
|
||||
reveal_type(MyModel.authors) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel]'
|
||||
MyModel.objects # E: "Type[MyModel]" has no attribute "objects"
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class MyModel(models.Model):
|
||||
authors = models.Manager['MyModel']()
|
||||
|
||||
- case: test_model_objects_attribute_present_in_case_of_model_cls_passed_as_generic_parameter
|
||||
main: |
|
||||
from myapp.models import Base, MyModel
|
||||
base_instance = Base(MyModel)
|
||||
reveal_type(base_instance.model_cls._default_manager) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from typing import TypeVar, Generic, Type
|
||||
from django.db import models
|
||||
|
||||
_T = TypeVar('_T', bound=models.Model)
|
||||
class Base(Generic[_T]):
|
||||
def __init__(self, model_cls: Type[_T]):
|
||||
self.model_cls = model_cls
|
||||
reveal_type(self.model_cls._default_manager) # N: Revealed type is 'django.db.models.manager.Manager[django.db.models.base.Model]'
|
||||
class MyModel(models.Model):
|
||||
pass
|
||||
class Child(Base[MyModel]):
|
||||
def method(self) -> None:
|
||||
reveal_type(self.model_cls._default_manager) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel]'
|
||||
|
||||
- case: if_custom_manager_defined_it_is_set_to_default_manager
|
||||
main: |
|
||||
from myapp.models import MyModel
|
||||
reveal_type(MyModel._default_manager) # N: Revealed type is 'myapp.models.CustomManager[myapp.models.MyModel]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from typing import TypeVar
|
||||
from django.db import models
|
||||
_T = TypeVar('_T', bound=models.Model)
|
||||
class CustomManager(models.Manager[_T]):
|
||||
pass
|
||||
class MyModel(models.Model):
|
||||
manager = CustomManager['MyModel']()
|
||||
|
||||
- case: if_default_manager_name_is_passed_set_default_manager_to_it
|
||||
main: |
|
||||
from myapp.models import MyModel
|
||||
reveal_type(MyModel._default_manager) # N: Revealed type is 'myapp.models.Manager2[myapp.models.MyModel]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from typing import TypeVar
|
||||
from django.db import models
|
||||
|
||||
_T = TypeVar('_T', bound=models.Model)
|
||||
class Manager1(models.Manager[_T]):
|
||||
pass
|
||||
class Manager2(models.Manager[_T]):
|
||||
pass
|
||||
class MyModel(models.Model):
|
||||
class Meta:
|
||||
default_manager_name = 'm2'
|
||||
m1 = Manager1['MyModel']()
|
||||
m2 = Manager2['MyModel']()
|
||||
|
||||
- case: test_leave_as_is_if_objects_is_set_and_fill_typevars_with_outer_class
|
||||
main: |
|
||||
from myapp.models import MyUser
|
||||
reveal_type(MyUser.objects) # N: Revealed type is 'myapp.models.UserManager[myapp.models.MyUser]'
|
||||
reveal_type(MyUser.objects.get()) # N: Revealed type is 'myapp.models.MyUser*'
|
||||
reveal_type(MyUser.objects.get_or_404()) # N: Revealed type is 'myapp.models.MyUser'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
|
||||
class UserManager(models.Manager['MyUser']):
|
||||
def get_or_404(self) -> 'MyUser':
|
||||
pass
|
||||
|
||||
class MyUser(models.Model):
|
||||
objects = UserManager()
|
||||
|
||||
- case: model_imported_from_different_file
|
||||
main: |
|
||||
from myapp.models import Inventory, Band
|
||||
reveal_type(Inventory.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.main.Inventory]'
|
||||
reveal_type(Band.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.Band]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models/__init__.py
|
||||
content: |
|
||||
from django.db import models
|
||||
from .main import Inventory
|
||||
class Band(models.Model):
|
||||
pass
|
||||
- path: myapp/models/main.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Inventory(models.Model):
|
||||
pass
|
||||
|
||||
- case: managers_that_defined_on_other_models_do_not_influence
|
||||
main: |
|
||||
from myapp.models import AbstractPerson, Book
|
||||
reveal_type(AbstractPerson.abstract_persons) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.AbstractPerson]'
|
||||
reveal_type(Book.published_objects) # N: Revealed type is 'myapp.models.PublishedBookManager[myapp.models.Book]'
|
||||
Book.published_objects.create(title='hello')
|
||||
reveal_type(Book.annotated_objects) # N: Revealed type is 'myapp.models.AnnotatedBookManager[myapp.models.Book]'
|
||||
Book.annotated_objects.create(title='hello')
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
|
||||
class AbstractPerson(models.Model):
|
||||
abstract_persons = models.Manager['AbstractPerson']()
|
||||
class PublishedBookManager(models.Manager['Book']):
|
||||
pass
|
||||
class AnnotatedBookManager(models.Manager['Book']):
|
||||
pass
|
||||
class Book(models.Model):
|
||||
title = models.CharField(max_length=50)
|
||||
published_objects = PublishedBookManager()
|
||||
annotated_objects = AnnotatedBookManager()
|
||||
|
||||
- case: managers_inherited_from_abstract_classes_multiple_inheritance
|
||||
main: |
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class CustomManager1(models.Manager['AbstractBase1']):
|
||||
pass
|
||||
class AbstractBase1(models.Model):
|
||||
class Meta:
|
||||
abstract = True
|
||||
name = models.CharField(max_length=50)
|
||||
manager1 = CustomManager1()
|
||||
class CustomManager2(models.Manager['AbstractBase2']):
|
||||
pass
|
||||
class AbstractBase2(models.Model):
|
||||
class Meta:
|
||||
abstract = True
|
||||
value = models.CharField(max_length=50)
|
||||
restricted = CustomManager2()
|
||||
|
||||
class Child(AbstractBase1, AbstractBase2):
|
||||
pass
|
||||
|
||||
- case: model_has_a_manager_of_the_same_type
|
||||
main: |
|
||||
from myapp.models import UnrelatedModel, MyModel
|
||||
reveal_type(UnrelatedModel.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.UnrelatedModel]'
|
||||
reveal_type(UnrelatedModel.objects.first()) # N: Revealed type is 'Union[myapp.models.UnrelatedModel*, None]'
|
||||
|
||||
reveal_type(MyModel.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel]'
|
||||
reveal_type(MyModel.objects.first()) # N: Revealed type is 'Union[myapp.models.MyModel*, None]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class UnrelatedModel(models.Model):
|
||||
objects = models.Manager['UnrelatedModel']()
|
||||
|
||||
class MyModel(models.Model):
|
||||
pass
|
||||
|
||||
- case: manager_without_annotation_of_the_model_gets_it_from_outer_one
|
||||
main: |
|
||||
from myapp.models import UnrelatedModel2, MyModel2
|
||||
reveal_type(UnrelatedModel2.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.UnrelatedModel2]'
|
||||
reveal_type(UnrelatedModel2.objects.first()) # N: Revealed type is 'Union[myapp.models.UnrelatedModel2*, None]'
|
||||
|
||||
reveal_type(MyModel2.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel2]'
|
||||
reveal_type(MyModel2.objects.first()) # N: Revealed type is 'Union[myapp.models.MyModel2*, None]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class UnrelatedModel2(models.Model):
|
||||
objects = models.Manager()
|
||||
|
||||
class MyModel2(models.Model):
|
||||
pass
|
||||
|
||||
- case: inherited_manager_has_the_proper_type_of_model
|
||||
main: |
|
||||
from myapp.models import ParentOfMyModel3, MyModel3
|
||||
reveal_type(ParentOfMyModel3.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.ParentOfMyModel3]'
|
||||
reveal_type(ParentOfMyModel3.objects.first()) # N: Revealed type is 'Union[myapp.models.ParentOfMyModel3*, None]'
|
||||
|
||||
reveal_type(MyModel3.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel3]'
|
||||
reveal_type(MyModel3.objects.first()) # N: Revealed type is 'Union[myapp.models.MyModel3*, None]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class ParentOfMyModel3(models.Model):
|
||||
objects = models.Manager()
|
||||
|
||||
class MyModel3(ParentOfMyModel3):
|
||||
pass
|
||||
|
||||
- case: inheritance_with_explicit_type_on_child_manager
|
||||
main: |
|
||||
from myapp.models import ParentOfMyModel4, MyModel4
|
||||
reveal_type(ParentOfMyModel4.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.ParentOfMyModel4]'
|
||||
reveal_type(ParentOfMyModel4.objects.first()) # N: Revealed type is 'Union[myapp.models.ParentOfMyModel4*, None]'
|
||||
|
||||
reveal_type(MyModel4.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel4]'
|
||||
reveal_type(MyModel4.objects.first()) # N: Revealed type is 'Union[myapp.models.MyModel4*, None]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class ParentOfMyModel4(models.Model):
|
||||
objects = models.Manager()
|
||||
|
||||
class MyModel4(ParentOfMyModel4):
|
||||
objects = models.Manager['MyModel4']()
|
||||
97
test-data/typecheck/models/test_create.yml
Normal file
97
test-data/typecheck/models/test_create.yml
Normal file
@@ -0,0 +1,97 @@
|
||||
- case: default_manager_create_is_typechecked
|
||||
main: |
|
||||
from myapp.models import User
|
||||
User.objects.create(name='Max', age=10)
|
||||
User.objects.create(age=[]) # E: Incompatible type for "age" of "User" (got "List[Any]", expected "Union[float, int, str, Combinable]")
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
|
||||
class User(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
age = models.IntegerField()
|
||||
|
||||
- case: model_recognises_parent_attributes
|
||||
main: |
|
||||
from myapp.models import Child
|
||||
Child.objects.create(name='Maxim', lastname='Maxim2')
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
|
||||
class Parent(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
class Child(Parent):
|
||||
lastname = models.CharField(max_length=100)
|
||||
|
||||
- case: deep_multiple_inheritance_with_create
|
||||
main: |
|
||||
from myapp.models import Child4
|
||||
Child4.objects.create(name1='n1', name2='n2', value=1, value4=4)
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
|
||||
class Parent1(models.Model):
|
||||
name1 = models.CharField(max_length=50)
|
||||
class Parent2(models.Model):
|
||||
id2 = models.AutoField(primary_key=True)
|
||||
name2 = models.CharField(max_length=50)
|
||||
|
||||
class Child1(Parent1, Parent2):
|
||||
value = models.IntegerField()
|
||||
class Child4(Child1):
|
||||
value4 = models.IntegerField()
|
||||
|
||||
- case: optional_id_fields_for_create_is_error
|
||||
main: |
|
||||
from myapp.models import Publisher, Book
|
||||
Book.objects.create(id=None) # E: Incompatible type for "id" of "Book" (got "None", expected "Union[Combinable, int, str]")
|
||||
Book.objects.create(publisher=None) # E: Incompatible type for "publisher" of "Book" (got "None", expected "Union[Publisher, Combinable]")
|
||||
Book.objects.create(publisher_id=None) # E: Incompatible type for "publisher_id" of "Book" (got "None", expected "Union[Combinable, int, str]")
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Publisher(models.Model):
|
||||
pass
|
||||
class Book(models.Model):
|
||||
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
|
||||
|
||||
- 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)
|
||||
|
||||
from myapp.models import MyModel2
|
||||
MyModel2(id=None)
|
||||
MyModel2.objects.create(id=None) # E: Incompatible type for "id" of "MyModel2" (got "None", expected "Union[float, int, str, Combinable]")
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
def return_int():
|
||||
return 0
|
||||
class MyModel(models.Model):
|
||||
id = models.IntegerField(primary_key=True, default=return_int)
|
||||
class MyModel2(models.Model):
|
||||
id = models.IntegerField(primary_key=True)
|
||||
70
test-data/typecheck/models/test_inheritance.yml
Normal file
70
test-data/typecheck/models/test_inheritance.yml
Normal file
@@ -0,0 +1,70 @@
|
||||
- case: test_meta_nested_class_allows_subclassing_in_multiple_inheritance
|
||||
main: |
|
||||
from typing import Any
|
||||
from django.db import models
|
||||
class Mixin1(models.Model):
|
||||
class Meta:
|
||||
abstract = True
|
||||
class Mixin2(models.Model):
|
||||
class Meta:
|
||||
abstract = True
|
||||
class User(Mixin1, Mixin2):
|
||||
pass
|
||||
|
||||
- case: test_inheritance_from_abstract_model_does_not_fail_if_field_with_id_exists
|
||||
main: |
|
||||
from django.db import models
|
||||
class Abstract(models.Model):
|
||||
class Meta:
|
||||
abstract = True
|
||||
class User(Abstract):
|
||||
id = models.AutoField(primary_key=True)
|
||||
|
||||
- case: test_typechecking_for_model_subclasses
|
||||
main: |
|
||||
from myapp.models import A, B, C
|
||||
def service(a: A) -> int:
|
||||
pass
|
||||
b_instance = B()
|
||||
service(b_instance) # E: Argument 1 to "service" has incompatible type "B"; expected "A"
|
||||
a_instance = A()
|
||||
c_instance = C()
|
||||
service(a_instance)
|
||||
service(c_instance)
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class A(models.Model):
|
||||
pass
|
||||
class B(models.Model):
|
||||
b_attr = 1
|
||||
pass
|
||||
class C(A):
|
||||
pass
|
||||
|
||||
- case: fail_if_no_such_attribute_on_model
|
||||
main: |
|
||||
from myapp.models import B
|
||||
b_instance = B()
|
||||
reveal_type(b_instance.b_attr) # N: Revealed type is 'builtins.int'
|
||||
|
||||
reveal_type(b_instance.non_existent_attribute)
|
||||
b_instance.non_existent_attribute = 2
|
||||
out: |
|
||||
main:5: note: Revealed type is 'Any'
|
||||
main:5: error: "B" has no attribute "non_existent_attribute"
|
||||
main:6: error: "B" has no attribute "non_existent_attribute"
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class B(models.Model):
|
||||
b_attr = 1
|
||||
pass
|
||||
235
test-data/typecheck/models/test_init.yml
Normal file
235
test-data/typecheck/models/test_init.yml
Normal file
@@ -0,0 +1,235 @@
|
||||
- case: arguments_to_init_unexpected_attributes
|
||||
main: |
|
||||
from myapp.models import MyUser
|
||||
user = MyUser(name=1, age=12)
|
||||
out: |
|
||||
main:2: error: Unexpected attribute "name" for model "MyUser"
|
||||
main:2: error: Unexpected attribute "age" for model "MyUser"
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
|
||||
class MyUser(models.Model):
|
||||
pass
|
||||
|
||||
- case: plain_function_which_returns_model
|
||||
main: |
|
||||
from myapp.models import MyUser
|
||||
def func(i: int) -> MyUser:
|
||||
pass
|
||||
func("hello") # E: Argument 1 to "func" has incompatible type "str"; expected "int"
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class MyUser(models.Model):
|
||||
pass
|
||||
|
||||
- case: arguments_to_init_from_class_incompatible_type
|
||||
main: |
|
||||
from myapp.models import MyUser
|
||||
user = MyUser(name='hello', age=[])
|
||||
out: |
|
||||
main:2: error: Incompatible type for "age" of "MyUser" (got "List[Any]", expected "Union[float, int, str, Combinable]")
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
|
||||
class MyUser(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
age = models.IntegerField()
|
||||
|
||||
- case: arguments_to_init_combined_from_base_classes
|
||||
main: |
|
||||
from myapp.models import BaseUser, ChildUser
|
||||
user = ChildUser(name='Max', age=12, lastname='Lastname')
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
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)
|
||||
|
||||
- case: fields_from_abstract_user_propagate_to_init
|
||||
main: |
|
||||
from myapp.models import MyUser
|
||||
user = MyUser(name='Maxim')
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class AbstractUser(models.Model):
|
||||
class Meta:
|
||||
abstract = True
|
||||
name = models.CharField(max_length=100)
|
||||
class MyUser(AbstractUser):
|
||||
pass
|
||||
|
||||
- case: pk_refers_to_primary_key_and_could_be_passed_to_init
|
||||
main: |
|
||||
from myapp.models import MyUser1, MyUser2
|
||||
user2 = MyUser1(pk='hello')
|
||||
user3 = MyUser2(pk=1, name='maxim')
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
|
||||
class MyUser1(models.Model):
|
||||
mypk = models.CharField(primary_key=True)
|
||||
class MyUser2(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
|
||||
- case: typechecking_of_pk
|
||||
main: |
|
||||
from myapp.models import MyUser1
|
||||
user = MyUser1(pk=[]) # E: Incompatible type for "pk" of "MyUser1" (got "List[Any]", expected "Union[float, int, str, Combinable, None]")
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
|
||||
class MyUser1(models.Model):
|
||||
mypk = models.IntegerField(primary_key=True)
|
||||
|
||||
- case: set_foreign_key_by_its_primary_key
|
||||
main: |
|
||||
from datetime import datetime
|
||||
now = datetime.now()
|
||||
|
||||
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, date, Combinable, None]")
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
|
||||
class Publisher(models.Model):
|
||||
pass
|
||||
class PublisherDatetime(models.Model):
|
||||
dt_pk = models.DateTimeField(primary_key=True)
|
||||
class Book(models.Model):
|
||||
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
|
||||
publisher_dt = models.ForeignKey(PublisherDatetime, on_delete=models.CASCADE)
|
||||
|
||||
- case: setting_value_to_an_array_of_ints
|
||||
main: |
|
||||
from typing import List, Tuple
|
||||
from myapp.models import MyModel
|
||||
array_val: Tuple[int, ...] = (1,)
|
||||
MyModel(array=array_val)
|
||||
array_val2: List[int] = [1]
|
||||
MyModel(array=array_val2)
|
||||
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]")
|
||||
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
|
||||
|
||||
class MyModel(models.Model):
|
||||
array = ArrayField(base_field=models.IntegerField())
|
||||
|
||||
- case: if_no_explicit_primary_key_id_can_be_passed
|
||||
main: |
|
||||
from myapp.models import MyModel
|
||||
MyModel(id=1, name='maxim')
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class MyModel(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
|
||||
- case: arguments_can_be_passed_as_positionals
|
||||
main: |
|
||||
from myapp.models import MyModel, MyModel2
|
||||
MyModel(1)
|
||||
MyModel2(1, 12)
|
||||
MyModel2(1, []) # E: Incompatible type for "name" of "MyModel2" (got "List[Any]", expected "Union[float, int, str, Combinable]")
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class MyModel(models.Model):
|
||||
pass
|
||||
class MyModel2(models.Model):
|
||||
name = models.IntegerField()
|
||||
|
||||
- case: charfield_with_integer_choices
|
||||
main: |
|
||||
from myapp.models import MyModel
|
||||
MyModel(day=1)
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class MyModel(models.Model):
|
||||
day = models.CharField(max_length=3, choices=((1, 'Fri'), (2, 'Sat')))
|
||||
|
||||
- case: optional_id_fields_allowed_in_init
|
||||
main: |
|
||||
from myapp.models import Book, Publisher
|
||||
Book(id=None)
|
||||
Book(publisher=None)
|
||||
Book(publisher_id=None)
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
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)
|
||||
43
test-data/typecheck/test_config.yml
Normal file
43
test-data/typecheck/test_config.yml
Normal file
@@ -0,0 +1,43 @@
|
||||
- case: pyproject_toml_config
|
||||
main: |
|
||||
from myapp.models import MyModel
|
||||
mymodel = MyModel(user_id=1)
|
||||
reveal_type(mymodel.id) # N: Revealed type is 'builtins.int*'
|
||||
reveal_type(mymodel.user) # N: Revealed type is 'django.contrib.auth.models.User*'
|
||||
reveal_type(mymodel.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel]'
|
||||
files:
|
||||
- path: pyproject.toml
|
||||
content: |
|
||||
[tool.django-stubs]
|
||||
django_settings_module = 'mysettings'
|
||||
- path: mysettings.py
|
||||
content: |
|
||||
SECRET_KEY = '1'
|
||||
INSTALLED_APPS = ('django.contrib.contenttypes', 'django.contrib.auth', 'myapp')
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from typing import TYPE_CHECKING
|
||||
from django.db import models
|
||||
class MyModel(models.Model):
|
||||
user = models.ForeignKey('auth.User', on_delete=models.CASCADE)
|
||||
if TYPE_CHECKING:
|
||||
reveal_type(MyModel.user) # N: Revealed type is 'django.contrib.auth.models.User*'
|
||||
|
||||
- case: generate_pyproject_toml_and_settings_file_from_installed_apps_key
|
||||
main: |
|
||||
from myapp.models import MyModel
|
||||
mymodel = MyModel(user_id=1)
|
||||
reveal_type(mymodel.id) # N: Revealed type is 'builtins.int*'
|
||||
installed_apps:
|
||||
- django.contrib.contenttypes
|
||||
- django.contrib.auth
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class MyModel(models.Model):
|
||||
user = models.ForeignKey('auth.User', on_delete=models.CASCADE)
|
||||
|
||||
58
test-data/typecheck/test_forms.yml
Normal file
58
test-data/typecheck/test_forms.yml
Normal file
@@ -0,0 +1,58 @@
|
||||
- case: no_incompatible_meta_nested_class_false_positive
|
||||
main: |
|
||||
from django import forms
|
||||
from myapp.models import Article, Category
|
||||
class ArticleForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Article
|
||||
fields = '__all__'
|
||||
class CategoryForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Category
|
||||
fields = '__all__'
|
||||
class CompositeForm(ArticleForm, CategoryForm):
|
||||
pass
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
from django import forms
|
||||
|
||||
class Article(models.Model):
|
||||
pass
|
||||
class Category(models.Model):
|
||||
pass
|
||||
|
||||
- case: formview_methods_on_forms_return_proper_types
|
||||
main: |
|
||||
from typing import Any
|
||||
from django import forms
|
||||
from django.views.generic.edit import FormView
|
||||
|
||||
class MyForm(forms.ModelForm):
|
||||
pass
|
||||
class MyForm2(forms.ModelForm):
|
||||
pass
|
||||
class MyView(FormView):
|
||||
form_class = MyForm
|
||||
def post(self, request, *args: Any, **kwds: Any):
|
||||
form_class = self.get_form_class()
|
||||
reveal_type(form_class) # N: Revealed type is 'Type[main.MyForm]'
|
||||
reveal_type(self.get_form(None)) # N: Revealed type is 'main.MyForm'
|
||||
reveal_type(self.get_form()) # N: Revealed type is 'main.MyForm'
|
||||
reveal_type(self.get_form(form_class)) # N: Revealed type is 'main.MyForm'
|
||||
reveal_type(self.get_form(MyForm2)) # N: Revealed type is 'main.MyForm2'
|
||||
|
||||
- case: successmessagemixin_compatible_with_formmixin
|
||||
main: |
|
||||
from django.views.generic.edit import FormMixin
|
||||
from django.contrib.messages.views import SuccessMessageMixin
|
||||
|
||||
class FormFirstView(FormMixin, SuccessMessageMixin):
|
||||
pass
|
||||
|
||||
class SuccessMessageFirstView(FormMixin, SuccessMessageMixin):
|
||||
pass
|
||||
42
test-data/typecheck/test_helpers.yml
Normal file
42
test-data/typecheck/test_helpers.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
- case: transaction_atomic_contextmanager
|
||||
main: |
|
||||
from django.db import transaction
|
||||
with transaction.atomic():
|
||||
pass
|
||||
with transaction.atomic(using="mydb"):
|
||||
pass
|
||||
with transaction.atomic(using="mydb", savepoint=False):
|
||||
pass
|
||||
|
||||
- case: transaction_atomic_decorator
|
||||
main: |
|
||||
from django.db import transaction
|
||||
|
||||
@transaction.atomic()
|
||||
def decorated_func(param1: str, param2: int) -> bool:
|
||||
pass
|
||||
# Ensure that the function's type is preserved
|
||||
reveal_type(decorated_func) # N: Revealed type is 'def (param1: builtins.str, param2: builtins.int) -> builtins.bool'
|
||||
|
||||
@transaction.atomic(using="mydb")
|
||||
def decorated_func_using(param1: str, param2: int) -> bool:
|
||||
pass
|
||||
# Ensure that the function's type is preserved
|
||||
reveal_type(decorated_func_using) # N: Revealed type is 'def (param1: builtins.str, param2: builtins.int) -> builtins.bool'
|
||||
|
||||
class ClassWithAtomicMethod:
|
||||
# Bare decorator
|
||||
@transaction.atomic
|
||||
def atomic_method1(self, abc: int) -> str:
|
||||
pass
|
||||
@transaction.atomic(savepoint=True)
|
||||
def atomic_method2(self):
|
||||
pass
|
||||
@transaction.atomic(using="db", savepoint=True)
|
||||
def atomic_method3(self, myparam: str) -> int:
|
||||
pass
|
||||
ClassWithAtomicMethod().atomic_method1("abc") # E: Argument 1 to "atomic_method1" of "ClassWithAtomicMethod" has incompatible type "str"; expected "int"
|
||||
# Ensure that the method's type is preserved
|
||||
reveal_type(ClassWithAtomicMethod().atomic_method1) # N: Revealed type is 'def (abc: builtins.int) -> builtins.str'
|
||||
# Ensure that the method's type is preserved
|
||||
reveal_type(ClassWithAtomicMethod().atomic_method3) # N: Revealed type is 'def (myparam: builtins.str) -> builtins.int'
|
||||
402
test-data/typecheck/test_import_all.yml
Normal file
402
test-data/typecheck/test_import_all.yml
Normal file
@@ -0,0 +1,402 @@
|
||||
- case: import_all_modules
|
||||
main: |
|
||||
import django.apps
|
||||
import django.apps.config
|
||||
import django.apps.registry
|
||||
import django.conf.global_settings
|
||||
import django.conf.urls
|
||||
import django.conf.urls.i18n
|
||||
import django.conf.urls.static
|
||||
import django.contrib.admin.actions
|
||||
import django.contrib.admin.apps
|
||||
import django.contrib.admin.checks
|
||||
import django.contrib.admin.decorators
|
||||
import django.contrib.admin.filters
|
||||
import django.contrib.admin.forms
|
||||
import django.contrib.admin.helpers
|
||||
import django.contrib.admin.models
|
||||
import django.contrib.admin.options
|
||||
import django.contrib.admin.sites
|
||||
import django.contrib.admin.templatetags
|
||||
import django.contrib.admin.templatetags.admin_list
|
||||
import django.contrib.admin.templatetags.admin_modify
|
||||
import django.contrib.admin.templatetags.admin_static
|
||||
import django.contrib.admin.templatetags.admin_urls
|
||||
import django.contrib.admin.templatetags.base
|
||||
import django.contrib.admin.templatetags.log
|
||||
import django.contrib.admin.utils
|
||||
import django.contrib.admin.views
|
||||
import django.contrib.admin.views.autocomplete
|
||||
import django.contrib.admin.views.decorators
|
||||
import django.contrib.admin.views.main
|
||||
import django.contrib.admin.widgets
|
||||
import django.contrib.admindocs
|
||||
import django.contrib.admindocs.middleware
|
||||
import django.contrib.admindocs.utils
|
||||
import django.contrib.admindocs.views
|
||||
import django.contrib.auth.admin
|
||||
import django.contrib.auth.apps
|
||||
import django.contrib.auth.backends
|
||||
import django.contrib.auth.base_user
|
||||
import django.contrib.auth.checks
|
||||
import django.contrib.auth.context_processors
|
||||
import django.contrib.auth.decorators
|
||||
import django.contrib.auth.forms
|
||||
import django.contrib.auth.handlers
|
||||
import django.contrib.auth.handlers.modwsgi
|
||||
import django.contrib.auth.hashers
|
||||
import django.contrib.auth.management.commands
|
||||
import django.contrib.auth.management.commands.changepassword
|
||||
import django.contrib.auth.management.commands.createsuperuser
|
||||
import django.contrib.auth.middleware
|
||||
import django.contrib.auth.mixins
|
||||
import django.contrib.auth.models
|
||||
import django.contrib.auth.password_validation
|
||||
import django.contrib.auth.signals
|
||||
import django.contrib.auth.tokens
|
||||
import django.contrib.auth.validators
|
||||
import django.contrib.auth.views
|
||||
import django.contrib.contenttypes.admin
|
||||
import django.contrib.contenttypes.apps
|
||||
import django.contrib.contenttypes.checks
|
||||
import django.contrib.contenttypes.fields
|
||||
import django.contrib.contenttypes.forms
|
||||
import django.contrib.contenttypes.management.commands
|
||||
import django.contrib.contenttypes.management.commands.remove_stale_contenttypes
|
||||
import django.contrib.contenttypes.models
|
||||
import django.contrib.contenttypes.views
|
||||
import django.contrib.flatpages.forms
|
||||
import django.contrib.flatpages.middleware
|
||||
import django.contrib.flatpages.models
|
||||
import django.contrib.flatpages.sitemaps
|
||||
import django.contrib.flatpages.templatetags
|
||||
import django.contrib.flatpages.templatetags.flatpages
|
||||
import django.contrib.flatpages.views
|
||||
import django.contrib.humanize.templatetags
|
||||
import django.contrib.humanize.templatetags.humanize
|
||||
import django.contrib.messages.api
|
||||
import django.contrib.messages.context_processors
|
||||
import django.contrib.messages.middleware
|
||||
import django.contrib.messages.storage
|
||||
import django.contrib.messages.storage.base
|
||||
import django.contrib.messages.storage.cookie
|
||||
import django.contrib.messages.storage.fallback
|
||||
import django.contrib.messages.storage.session
|
||||
import django.contrib.messages.utils
|
||||
import django.contrib.messages.views
|
||||
import django.contrib.postgres.fields
|
||||
import django.contrib.postgres.fields.array
|
||||
import django.contrib.postgres.fields.citext
|
||||
import django.contrib.postgres.fields.hstore
|
||||
import django.contrib.postgres.fields.jsonb
|
||||
import django.contrib.postgres.fields.mixins
|
||||
import django.contrib.postgres.fields.ranges
|
||||
import django.contrib.postgres.operations
|
||||
import django.contrib.redirects
|
||||
import django.contrib.redirects.middleware
|
||||
import django.contrib.redirects.models
|
||||
import django.contrib.sessions.backends
|
||||
import django.contrib.sessions.backends.base
|
||||
import django.contrib.sessions.backends.cache
|
||||
import django.contrib.sessions.backends.cached_db
|
||||
import django.contrib.sessions.backends.db
|
||||
import django.contrib.sessions.backends.file
|
||||
import django.contrib.sessions.backends.signed_cookies
|
||||
import django.contrib.sessions.base_session
|
||||
import django.contrib.sessions.management.commands
|
||||
import django.contrib.sessions.management.commands.clearsessions
|
||||
import django.contrib.sessions.middleware
|
||||
import django.contrib.sessions.models
|
||||
import django.contrib.sessions.serializers
|
||||
import django.contrib.sitemaps.management.commands
|
||||
import django.contrib.sitemaps.management.commands.ping_google
|
||||
import django.contrib.sitemaps.views
|
||||
import django.contrib.sites
|
||||
import django.contrib.sites.apps
|
||||
import django.contrib.sites.management
|
||||
import django.contrib.sites.managers
|
||||
import django.contrib.sites.middleware
|
||||
import django.contrib.sites.models
|
||||
import django.contrib.sites.requests
|
||||
import django.contrib.sites.shortcuts
|
||||
import django.contrib.staticfiles.apps
|
||||
import django.contrib.staticfiles.checks
|
||||
import django.contrib.staticfiles.finders
|
||||
import django.contrib.staticfiles.handlers
|
||||
import django.contrib.staticfiles.management.commands
|
||||
import django.contrib.staticfiles.management.commands.collectstatic
|
||||
import django.contrib.staticfiles.management.commands.findstatic
|
||||
import django.contrib.staticfiles.management.commands.runserver
|
||||
import django.contrib.staticfiles.storage
|
||||
import django.contrib.staticfiles.templatetags
|
||||
import django.contrib.staticfiles.templatetags.staticfiles
|
||||
import django.contrib.staticfiles.urls
|
||||
import django.contrib.staticfiles.utils
|
||||
import django.contrib.staticfiles.views
|
||||
import django.contrib.syndication
|
||||
import django.contrib.syndication.views
|
||||
import django.core.cache.backends
|
||||
import django.core.cache.backends.base
|
||||
import django.core.cache.backends.db
|
||||
import django.core.cache.backends.dummy
|
||||
import django.core.cache.backends.filebased
|
||||
import django.core.cache.backends.locmem
|
||||
import django.core.cache.utils
|
||||
import django.core.checks.caches
|
||||
import django.core.checks.database
|
||||
import django.core.checks.messages
|
||||
import django.core.checks.model_checks
|
||||
import django.core.checks.registry
|
||||
import django.core.checks.security
|
||||
import django.core.checks.security.base
|
||||
import django.core.checks.security.csrf
|
||||
import django.core.checks.security.sessions
|
||||
import django.core.checks.templates
|
||||
import django.core.checks.urls
|
||||
import django.core.exceptions
|
||||
import django.core.files
|
||||
import django.core.files.base
|
||||
import django.core.files.images
|
||||
import django.core.files.locks
|
||||
import django.core.files.move
|
||||
import django.core.files.storage
|
||||
import django.core.files.temp
|
||||
import django.core.files.uploadedfile
|
||||
import django.core.files.uploadhandler
|
||||
import django.core.files.utils
|
||||
import django.core.handlers
|
||||
import django.core.handlers.base
|
||||
import django.core.handlers.exception
|
||||
import django.core.handlers.wsgi
|
||||
import django.core.mail
|
||||
import django.core.mail.message
|
||||
import django.core.mail.utils
|
||||
import django.core.management
|
||||
import django.core.management.base
|
||||
import django.core.management.color
|
||||
import django.core.management.sql
|
||||
import django.core.management.templates
|
||||
import django.core.management.utils
|
||||
import django.core.paginator
|
||||
import django.core.serializers
|
||||
import django.core.serializers.base
|
||||
import django.core.serializers.json
|
||||
import django.core.serializers.python
|
||||
import django.core.servers
|
||||
import django.core.servers.basehttp
|
||||
import django.core.signals
|
||||
import django.core.signing
|
||||
import django.core.validators
|
||||
import django.core.wsgi
|
||||
import django.db.backends.base
|
||||
import django.db.backends.base.base
|
||||
import django.db.backends.base.client
|
||||
import django.db.backends.base.creation
|
||||
import django.db.backends.base.features
|
||||
import django.db.backends.base.introspection
|
||||
import django.db.backends.base.operations
|
||||
import django.db.backends.base.schema
|
||||
import django.db.backends.base.validation
|
||||
import django.db.backends.ddl_references
|
||||
import django.db.backends.dummy
|
||||
import django.db.backends.dummy.base
|
||||
import django.db.backends.mysql
|
||||
import django.db.backends.mysql.client
|
||||
import django.db.backends.postgresql
|
||||
import django.db.backends.postgresql.client
|
||||
import django.db.backends.sqlite3
|
||||
import django.db.backends.sqlite3.base
|
||||
import django.db.backends.sqlite3.creation
|
||||
import django.db.backends.sqlite3.features
|
||||
import django.db.backends.sqlite3.introspection
|
||||
import django.db.backends.sqlite3.operations
|
||||
import django.db.backends.sqlite3.schema
|
||||
import django.db.backends.utils
|
||||
import django.db.migrations.autodetector
|
||||
import django.db.migrations.exceptions
|
||||
import django.db.migrations.executor
|
||||
import django.db.migrations.graph
|
||||
import django.db.migrations.loader
|
||||
import django.db.migrations.migration
|
||||
import django.db.migrations.operations
|
||||
import django.db.migrations.operations.base
|
||||
import django.db.migrations.operations.fields
|
||||
import django.db.migrations.operations.models
|
||||
import django.db.migrations.operations.special
|
||||
import django.db.migrations.operations.utils
|
||||
import django.db.migrations.optimizer
|
||||
import django.db.migrations.questioner
|
||||
import django.db.migrations.recorder
|
||||
import django.db.migrations.serializer
|
||||
import django.db.migrations.state
|
||||
import django.db.migrations.topological_sort
|
||||
import django.db.migrations.utils
|
||||
import django.db.migrations.writer
|
||||
import django.db.models.aggregates
|
||||
import django.db.models.base
|
||||
import django.db.models.deletion
|
||||
import django.db.models.expressions
|
||||
import django.db.models.fields
|
||||
import django.db.models.fields.files
|
||||
import django.db.models.fields.mixins
|
||||
import django.db.models.fields.proxy
|
||||
import django.db.models.fields.related
|
||||
import django.db.models.fields.related_descriptors
|
||||
import django.db.models.fields.related_lookups
|
||||
import django.db.models.fields.reverse_related
|
||||
import django.db.models.functions
|
||||
import django.db.models.functions.comparison
|
||||
import django.db.models.functions.datetime
|
||||
import django.db.models.functions.text
|
||||
import django.db.models.functions.window
|
||||
import django.db.models.indexes
|
||||
import django.db.models.lookups
|
||||
import django.db.models.manager
|
||||
import django.db.models.options
|
||||
import django.db.models.query
|
||||
import django.db.models.query_utils
|
||||
import django.db.models.signals
|
||||
import django.db.models.sql
|
||||
import django.db.models.sql.compiler
|
||||
import django.db.models.sql.constants
|
||||
import django.db.models.sql.datastructures
|
||||
import django.db.models.sql.query
|
||||
import django.db.models.sql.subqueries
|
||||
import django.db.models.sql.where
|
||||
import django.db.models.utils
|
||||
import django.db.transaction
|
||||
import django.db.utils
|
||||
import django.dispatch
|
||||
import django.dispatch.dispatcher
|
||||
import django.forms
|
||||
import django.forms.boundfield
|
||||
import django.forms.fields
|
||||
import django.forms.forms
|
||||
import django.forms.formsets
|
||||
import django.forms.models
|
||||
import django.forms.renderers
|
||||
import django.forms.utils
|
||||
import django.forms.widgets
|
||||
import django.http
|
||||
import django.http.cookie
|
||||
import django.http.multipartparser
|
||||
import django.http.request
|
||||
import django.http.response
|
||||
import django.middleware
|
||||
import django.middleware.cache
|
||||
import django.middleware.clickjacking
|
||||
import django.middleware.common
|
||||
import django.middleware.csrf
|
||||
import django.middleware.gzip
|
||||
import django.middleware.http
|
||||
import django.middleware.locale
|
||||
import django.middleware.security
|
||||
import django.shortcuts
|
||||
import django.template.backends
|
||||
import django.template.backends.base
|
||||
import django.template.backends.django
|
||||
import django.template.backends.dummy
|
||||
import django.template.backends.jinja2
|
||||
import django.template.backends.utils
|
||||
import django.template.base
|
||||
import django.template.context
|
||||
import django.template.context_processors
|
||||
import django.template.defaultfilters
|
||||
import django.template.defaulttags
|
||||
import django.template.engine
|
||||
import django.template.exceptions
|
||||
import django.template.library
|
||||
import django.template.loader
|
||||
import django.template.loader_tags
|
||||
import django.template.loaders
|
||||
import django.template.loaders.app_directories
|
||||
import django.template.loaders.base
|
||||
import django.template.loaders.cached
|
||||
import django.template.loaders.filesystem
|
||||
import django.template.loaders.locmem
|
||||
import django.template.response
|
||||
import django.template.smartif
|
||||
import django.template.utils
|
||||
import django.templatetags
|
||||
import django.templatetags.cache
|
||||
import django.templatetags.i18n
|
||||
import django.templatetags.l10n
|
||||
import django.templatetags.static
|
||||
import django.templatetags.tz
|
||||
import django.test
|
||||
import django.test.client
|
||||
import django.test.html
|
||||
import django.test.runner
|
||||
import django.test.selenium
|
||||
import django.test.signals
|
||||
import django.test.testcases
|
||||
import django.test.utils
|
||||
import django.urls
|
||||
import django.urls.base
|
||||
import django.urls.conf
|
||||
import django.urls.converters
|
||||
import django.urls.exceptions
|
||||
import django.urls.resolvers
|
||||
import django.urls.utils
|
||||
import django.utils._os
|
||||
import django.utils.archive
|
||||
import django.utils.autoreload
|
||||
import django.utils.baseconv
|
||||
import django.utils.cache
|
||||
import django.utils.crypto
|
||||
import django.utils.datastructures
|
||||
import django.utils.dateformat
|
||||
import django.utils.dateparse
|
||||
import django.utils.dates
|
||||
import django.utils.datetime_safe
|
||||
import django.utils.deconstruct
|
||||
import django.utils.decorators
|
||||
import django.utils.deprecation
|
||||
import django.utils.duration
|
||||
import django.utils.encoding
|
||||
import django.utils.feedgenerator
|
||||
import django.utils.formats
|
||||
import django.utils.functional
|
||||
import django.utils.html
|
||||
import django.utils.http
|
||||
import django.utils.inspect
|
||||
import django.utils.ipv6
|
||||
import django.utils.itercompat
|
||||
import django.utils.jslex
|
||||
import django.utils.log
|
||||
import django.utils.lorem_ipsum
|
||||
import django.utils.module_loading
|
||||
import django.utils.numberformat
|
||||
import django.utils.regex_helper
|
||||
import django.utils.safestring
|
||||
import django.utils.six
|
||||
import django.utils.termcolors
|
||||
import django.utils.text
|
||||
import django.utils.timesince
|
||||
import django.utils.timezone
|
||||
import django.utils.translation
|
||||
import django.utils.translation.template
|
||||
import django.utils.translation.trans_null
|
||||
import django.utils.translation.trans_real
|
||||
import django.utils.tree
|
||||
import django.utils.version
|
||||
import django.utils.xmlutils
|
||||
import django.views.csrf
|
||||
import django.views.debug
|
||||
import django.views.decorators
|
||||
import django.views.decorators.cache
|
||||
import django.views.decorators.clickjacking
|
||||
import django.views.decorators.csrf
|
||||
import django.views.decorators.debug
|
||||
import django.views.decorators.gzip
|
||||
import django.views.decorators.http
|
||||
import django.views.decorators.vary
|
||||
import django.views.defaults
|
||||
import django.views.generic
|
||||
import django.views.generic.base
|
||||
import django.views.generic.dates
|
||||
import django.views.generic.detail
|
||||
import django.views.generic.edit
|
||||
import django.views.generic.list
|
||||
import django.views.i18n
|
||||
import django.views.static
|
||||
41
test-data/typecheck/test_settings.yml
Normal file
41
test-data/typecheck/test_settings.yml
Normal file
@@ -0,0 +1,41 @@
|
||||
- case: settings_loaded_from_different_files
|
||||
disable_cache: true
|
||||
main: |
|
||||
from django.conf import settings
|
||||
# standard settings
|
||||
reveal_type(settings.AUTH_USER_MODEL) # N: Revealed type is 'builtins.str'
|
||||
reveal_type(settings.ROOT_DIR) # N: Revealed type is 'builtins.str'
|
||||
reveal_type(settings.APPS_DIR) # N: Revealed type is 'pathlib.Path'
|
||||
reveal_type(settings.NUMBERS) # N: Revealed type is 'builtins.list[builtins.str*]'
|
||||
reveal_type(settings.DICT) # N: Revealed type is 'builtins.dict[Any, Any]'
|
||||
files:
|
||||
- path: pyproject.toml
|
||||
content: |
|
||||
[tool.django-stubs]
|
||||
django_settings_module = 'mysettings'
|
||||
- path: mysettings.py
|
||||
content: |
|
||||
from base import *
|
||||
SECRET_KEY = 112233
|
||||
NUMBERS = ['one', 'two']
|
||||
DICT = {} # type: ignore
|
||||
- path: base.py
|
||||
content: |
|
||||
from pathlib import Path
|
||||
ROOT_DIR = '/etc'
|
||||
APPS_DIR = Path(ROOT_DIR)
|
||||
|
||||
- case: global_settings_are_always_loaded
|
||||
main: |
|
||||
from django.conf import settings
|
||||
reveal_type(settings.AUTH_USER_MODEL) # N: Revealed type is 'builtins.str'
|
||||
reveal_type(settings.AUTHENTICATION_BACKENDS) # N: Revealed type is 'typing.Sequence[builtins.str]'
|
||||
installed_apps: []
|
||||
|
||||
- case: fail_if_there_is_no_setting
|
||||
main: |
|
||||
from django.conf import settings
|
||||
reveal_type(settings.NOT_EXISTING)
|
||||
out: |
|
||||
main:2: note: Revealed type is 'Any'
|
||||
main:2: error: 'Settings' object has no attribute 'NOT_EXISTING'
|
||||
39
test-data/typecheck/test_shortcuts.yml
Normal file
39
test-data/typecheck/test_shortcuts.yml
Normal file
@@ -0,0 +1,39 @@
|
||||
- case: get_object_or_404_returns_proper_types
|
||||
main: |
|
||||
from django.shortcuts import get_object_or_404, get_list_or_404
|
||||
from myapp.models import MyModel
|
||||
|
||||
reveal_type(get_object_or_404(MyModel)) # N: Revealed type is 'myapp.models.MyModel*'
|
||||
reveal_type(get_object_or_404(MyModel.objects)) # N: Revealed type is 'myapp.models.MyModel*'
|
||||
reveal_type(get_object_or_404(MyModel.objects.get_queryset())) # N: Revealed type is 'myapp.models.MyModel*'
|
||||
|
||||
reveal_type(get_list_or_404(MyModel)) # N: Revealed type is 'builtins.list[myapp.models.MyModel*]'
|
||||
reveal_type(get_list_or_404(MyModel.objects)) # N: Revealed type is 'builtins.list[myapp.models.MyModel*]'
|
||||
reveal_type(get_list_or_404(MyModel.objects.get_queryset())) # N: Revealed type is 'builtins.list[myapp.models.MyModel*]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class MyModel(models.Model):
|
||||
pass
|
||||
|
||||
- case: get_user_model_returns_proper_class
|
||||
disable_cache: true
|
||||
main: |
|
||||
from django.contrib.auth import get_user_model
|
||||
UserModel = get_user_model()
|
||||
reveal_type(UserModel.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyUser]'
|
||||
additional_settings:
|
||||
- AUTH_USER_MODEL='myapp.MyUser'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class MyUser(models.Model):
|
||||
pass
|
||||
Reference in New Issue
Block a user