File: test_abstract.yml

package info (click to toggle)
python-django-stubs 5.2.9-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,832 kB
  • sloc: python: 5,185; makefile: 15; sh: 8
file content (219 lines) | stat: -rw-r--r-- 7,962 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
- case: test_filter_on_abstract_user_pk
  main: |
    from typing_extensions import reveal_type
    from django.contrib.auth.models import AbstractUser
    AbstractUser.objects.get(pk=1)
    AbstractUser.objects.get(pk__in=[1])

    au: AbstractUser
    reveal_type(au.pk)  # N: Revealed type is "Any"
  installed_apps:
    - django.contrib.auth
    - django.contrib.contenttypes


- case: test_filter_on_abstract_user_pk_wrong_name
  main: |
    from django.contrib.auth.models import AbstractUser
    AbstractUser.objects.get(pkey=1)  # ER: Cannot resolve keyword 'pkey' into field..*
  installed_apps:
    - django.contrib.auth
    - django.contrib.contenttypes


- case: test_fetch_pk_with_custom_manager_on_abstract_model
  main: |
    from myapp.models import MyModel
  installed_apps:
    - myapp
  files:
    -   path: myapp/__init__.py
    -   path: myapp/models.py
        content: |
            from typing_extensions import reveal_type
            from django.db import models

            class BaseManager(models.Manager):
                pass

            class BaseModel(models.Model):
                objects = BaseManager()

                class Meta:
                    abstract = True

                def lock(self) -> None:
                    reveal_type(type(self).objects.values_list("pk"))  # N: Revealed type is "django.db.models.query.QuerySet[myapp.models.BaseModel, tuple[Any]]"

            class MyModel(BaseModel):
                field = models.IntegerField()

- case: test_can_instantiate_with_recursive_relation_on_abstract_model
  main: |
    from myapp.models import Concrete, Recursive
    first = Concrete.objects.create(parent=None)
    Concrete.objects.create(parent=first)
    Recursive.objects.create(parent=None)
    Recursive(parent=Recursive(parent=None))
    Concrete(parent=Concrete(parent=None))
  out: |
    main:4: error: "type[Recursive]" has no attribute "objects"  [attr-defined]
    main:5: error: Cannot instantiate abstract class "Recursive" with abstract attributes "DoesNotExist" and "MultipleObjectsReturned"  [abstract]
    main:5: error: Unexpected attribute "parent" for model "Recursive"  [misc]
  installed_apps:
    - myapp
  files:
    -   path: myapp/__init__.py
    -   path: myapp/models.py
        content: |
            from django.db import models

            class Recursive(models.Model):
                parent = models.ForeignKey("self", null=True, on_delete=models.CASCADE)

                class Meta:
                    abstract = True

            class Concrete(Recursive):
                ...


- case: test_abstract_model_type_cannot_be_used_as_runtime_arg
  main: |
      from myapp.models import Abstract, Concrete, LiteralAbstract
      from typing import Generic, TypeVar, overload

      Abstract()  # E: Cannot instantiate abstract class "Abstract" with abstract attributes "DoesNotExist" and "MultipleObjectsReturned"  [abstract]
      LiteralAbstract()  # E: Cannot instantiate abstract class "LiteralAbstract" with abstract attributes "DoesNotExist" and "MultipleObjectsReturned"  [abstract]

      def f(klass: type[Abstract]) -> None:
          return None

      f(Abstract)  # E: Only concrete class can be given where "type[Abstract]" is expected  [type-abstract]
      f(Concrete)

      def second_arg(arg: str, klass: type[Abstract]) -> None:
          return None

      second_arg("abc", Abstract)  # E: Only concrete class can be given where "type[Abstract]" is expected  [type-abstract]
      second_arg(Abstract, Concrete)  # E: Argument 1 to "second_arg" has incompatible type "type[Abstract]"; expected "str"  [arg-type]

      T = TypeVar("T", bound=Abstract)

      def g(klass: type[T]) -> None:
          return None

      g(Abstract)  # E: Only concrete class can be given where "type[Abstract]" is expected  [type-abstract]
      g(Concrete)

      @overload
      def o(klass: type[T], arg: str) -> None: ...
      @overload
      def o(klass: type[T], arg: int) -> None: ...
      def o(klass: type[T], arg: str | int) -> None:
          return None

      o(Abstract, "a")  # E: Only concrete class can be given where "type[Abstract]" is expected  [type-abstract]
      o(Abstract, 1)  # E: Only concrete class can be given where "type[Abstract]" is expected  [type-abstract]
      o(Concrete, 1)

      class M:
          def method(self, klass: type[Abstract]) -> None:
              return None

          @overload
          def overloaded(self, arg: int, klass: type[Abstract]) -> None:
              ...

          @overload
          def overloaded(self, arg: str, klass: type[Abstract]) -> None:
              ...

          def overloaded(self, arg: str | int, klass: type[Abstract]) -> None:
              return None

      M().method(Abstract)  # E: Only concrete class can be given where "type[Abstract]" is expected  [type-abstract]
      M().overloaded(1, Abstract)  # E: Only concrete class can be given where "type[Abstract]" is expected  [type-abstract]
      M().overloaded("1", Abstract)  # E: Only concrete class can be given where "type[Abstract]" is expected  [type-abstract]

      class G(Generic[T]):
          def method(self, klass: type[T]) -> None:
              return None

      G[Abstract]().method(Abstract)  # E: Only concrete class can be given where "type[Abstract]" is expected  [type-abstract]
      # Additional plugin coverage
      unknown(Abstract)  # E: Name "unknown" is not defined  [name-defined]
      M().unknown(Abstract)  # E: "M" has no attribute "unknown"  [attr-defined]
  installed_apps:
    - myapp
  files:
    -   path: myapp/__init__.py
    -   path: myapp/models.py
        content: |
            from django.db import models
            from typing import Literal, ClassVar

            class Abstract(models.Model):
                field = models.CharField()

                class Meta:
                    abstract = True

            class Concrete(Abstract):
                ...

            class LiteralAbstract(models.Model):
                class Meta:
                    abstract: ClassVar[Literal[True]]


- case: test_use_abstract_model
  main: |
    from myapp.models import create_animal, create_animal_generic, Cat, Animal, ExplicitConcrete
    create_animal(Cat, "Garfield")
    create_animal(Animal, "Animal")  # E: Only concrete class can be given where "type[Animal]" is expected  [type-abstract]
    create_animal_generic(Cat, "Grumpy")
    create_animal_generic(Animal, "Animal")  # E: Only concrete class can be given where "type[Animal]" is expected  [type-abstract]

    Animal()  # E: Cannot instantiate abstract class "Animal" with abstract attributes "DoesNotExist" and "MultipleObjectsReturned"  [abstract]
    ExplicitConcrete()
  installed_apps:
    - myapp
  files:
    -   path: myapp/__init__.py
    -   path: myapp/models.py
        content: |
            from typing import Protocol, TypeVar
            from typing_extensions import reveal_type
            from django.db import models
            from django_stubs_ext.db.models import TypedModelMeta

            class Animal(models.Model):
                name = models.CharField(max_length=100)

                class Meta(TypedModelMeta):
                    abstract = True

            class Cat(Animal):  # Concrete model
                pass


            class ExplicitConcrete(Animal):
                class Meta:
                    abstract = False

            def f() -> None:
                x: type[Animal]
                x()
                return None

            def create_animal(klass: type[Animal], name: str) -> Animal:
                obj = klass(name=name)
                obj.save()
                return obj

            T = TypeVar("T", bound=Animal)

            def create_animal_generic(klass: type[T], name: str) -> T:
                reveal_type(klass)  # N: Revealed type is "type[T`-1]"
                return klass._default_manager.create(name=name)