mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-07 04:34:29 +08:00
remove some asserts that could be validly triggered
This commit is contained in:
3
mypy.ini
3
mypy.ini
@@ -1,4 +1 @@
|
|||||||
[mypy]
|
[mypy]
|
||||||
|
|
||||||
[mypy-mypy_django_plugin.monkeypatch.*]
|
|
||||||
ignore_errors = True
|
|
||||||
@@ -1,20 +1,21 @@
|
|||||||
import os
|
import os
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from typing import Dict, Iterator, List, Optional, TYPE_CHECKING, Tuple, Type
|
from typing import TYPE_CHECKING, Dict, Iterator, List, Optional, Tuple, Type
|
||||||
|
|
||||||
|
from django.contrib.postgres.fields import ArrayField
|
||||||
from django.core.exceptions import FieldError
|
from django.core.exceptions import FieldError
|
||||||
from django.db.models.base import Model
|
from django.db.models.base import Model
|
||||||
|
from django.db.models.fields import AutoField, CharField, Field
|
||||||
from django.db.models.fields.related import ForeignKey, RelatedField
|
from django.db.models.fields.related import ForeignKey, RelatedField
|
||||||
from django.db.models.fields.reverse_related import ForeignObjectRel
|
from django.db.models.fields.reverse_related import ForeignObjectRel
|
||||||
from django.db.models.sql.query import Query
|
from django.db.models.sql.query import Query
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from mypy.checker import TypeChecker
|
from mypy.checker import TypeChecker
|
||||||
from mypy.nodes import TypeInfo
|
from mypy.types import AnyType, Instance
|
||||||
from mypy.types import AnyType, Instance, Type as MypyType, TypeOfAny
|
from mypy.types import Type as MypyType
|
||||||
|
from mypy.types import TypeOfAny
|
||||||
|
|
||||||
from django.contrib.postgres.fields import ArrayField
|
|
||||||
from django.db.models.fields import AutoField, CharField, Field
|
|
||||||
from mypy_django_plugin.lib import helpers
|
from mypy_django_plugin.lib import helpers
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@@ -104,7 +105,8 @@ class DjangoFieldsContext:
|
|||||||
def get_field_get_type(self, api: TypeChecker, field: Field, *, method: str) -> MypyType:
|
def get_field_get_type(self, api: TypeChecker, field: Field, *, method: str) -> MypyType:
|
||||||
""" Get a type of __get__ for this specific Django field. """
|
""" Get a type of __get__ for this specific Django field. """
|
||||||
field_info = helpers.lookup_class_typeinfo(api, field.__class__)
|
field_info = helpers.lookup_class_typeinfo(api, field.__class__)
|
||||||
assert isinstance(field_info, TypeInfo)
|
if field_info is None:
|
||||||
|
return AnyType(TypeOfAny.unannotated)
|
||||||
|
|
||||||
is_nullable = self.get_field_nullability(field, method)
|
is_nullable = self.get_field_nullability(field, method)
|
||||||
if isinstance(field, RelatedField):
|
if isinstance(field, RelatedField):
|
||||||
@@ -113,7 +115,8 @@ class DjangoFieldsContext:
|
|||||||
return self.get_field_get_type(api, primary_key_field, method=method)
|
return self.get_field_get_type(api, primary_key_field, method=method)
|
||||||
|
|
||||||
model_info = helpers.lookup_class_typeinfo(api, field.related_model)
|
model_info = helpers.lookup_class_typeinfo(api, field.related_model)
|
||||||
assert isinstance(model_info, TypeInfo)
|
if model_info is None:
|
||||||
|
return AnyType(TypeOfAny.unannotated)
|
||||||
|
|
||||||
return Instance(model_info, [])
|
return Instance(model_info, [])
|
||||||
else:
|
else:
|
||||||
@@ -215,14 +218,19 @@ class DjangoContext:
|
|||||||
if isinstance(field, ForeignKey):
|
if isinstance(field, ForeignKey):
|
||||||
field_name = field.name
|
field_name = field.name
|
||||||
foreign_key_info = helpers.lookup_class_typeinfo(api, field.__class__)
|
foreign_key_info = helpers.lookup_class_typeinfo(api, field.__class__)
|
||||||
assert isinstance(foreign_key_info, TypeInfo)
|
if foreign_key_info is None:
|
||||||
|
# maybe there's no type annotation for the field
|
||||||
|
expected_types[field_name] = AnyType(TypeOfAny.unannotated)
|
||||||
|
continue
|
||||||
|
|
||||||
related_model = field.related_model
|
related_model = field.related_model
|
||||||
if related_model._meta.proxy_for_model:
|
if related_model._meta.proxy_for_model:
|
||||||
related_model = field.related_model._meta.proxy_for_model
|
related_model = field.related_model._meta.proxy_for_model
|
||||||
|
|
||||||
related_model_info = helpers.lookup_class_typeinfo(api, related_model)
|
related_model_info = helpers.lookup_class_typeinfo(api, related_model)
|
||||||
assert isinstance(related_model_info, TypeInfo)
|
if related_model_info is None:
|
||||||
|
expected_types[field_name] = AnyType(TypeOfAny.unannotated)
|
||||||
|
continue
|
||||||
|
|
||||||
is_nullable = self.fields_context.get_field_nullability(field, method)
|
is_nullable = self.fields_context.get_field_nullability(field, method)
|
||||||
foreign_key_set_type = helpers.get_private_descriptor_type(foreign_key_info,
|
foreign_key_set_type = helpers.get_private_descriptor_type(foreign_key_info,
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from typing import Any, Dict, List, Optional, Set, TYPE_CHECKING, Union, cast
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Union, cast
|
||||||
|
|
||||||
from mypy import checker
|
from mypy import checker
|
||||||
from mypy.checker import TypeChecker
|
from mypy.checker import TypeChecker
|
||||||
from mypy.mro import calculate_mro
|
from mypy.mro import calculate_mro
|
||||||
from mypy.nodes import (Block, ClassDef, Expression, GDEF, MDEF, MemberExpr, MypyFile, NameExpr, StrExpr, SymbolNode,
|
from mypy.nodes import (
|
||||||
SymbolTable, SymbolTableNode, TypeInfo, Var)
|
GDEF, MDEF, Block, ClassDef, Expression, MemberExpr, MypyFile, NameExpr, StrExpr, SymbolNode, SymbolTable,
|
||||||
from mypy.plugin import AttributeContext, CheckerPluginInterface, FunctionContext, MethodContext
|
SymbolTableNode, TypeInfo, Var,
|
||||||
from mypy.types import AnyType, Instance, NoneTyp, TupleType, Type as MypyType, TypeOfAny, TypedDictType, UnionType
|
)
|
||||||
|
from mypy.plugin import (
|
||||||
|
AttributeContext, CheckerPluginInterface, FunctionContext, MethodContext,
|
||||||
|
)
|
||||||
|
from mypy.types import AnyType, Instance, NoneTyp, TupleType
|
||||||
|
from mypy.types import Type as MypyType
|
||||||
|
from mypy.types import TypedDictType, TypeOfAny, UnionType
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from mypy_django_plugin.django.context import DjangoContext
|
from mypy_django_plugin.django.context import DjangoContext
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ from django.db.models.fields.related import RelatedField
|
|||||||
from mypy.errors import Errors
|
from mypy.errors import Errors
|
||||||
from mypy.nodes import MypyFile, TypeInfo
|
from mypy.nodes import MypyFile, TypeInfo
|
||||||
from mypy.options import Options
|
from mypy.options import Options
|
||||||
from mypy.plugin import AnalyzeTypeContext, AttributeContext, ClassDefContext, FunctionContext, MethodContext, Plugin
|
from mypy.plugin import (
|
||||||
|
AnalyzeTypeContext, AttributeContext, ClassDefContext, FunctionContext, MethodContext, Plugin,
|
||||||
|
)
|
||||||
from mypy.types import Type as MypyType
|
from mypy.types import Type as MypyType
|
||||||
|
|
||||||
from mypy_django_plugin.django.context import DjangoContext
|
from mypy_django_plugin.django.context import DjangoContext
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from typing import Optional, Tuple, cast
|
|||||||
|
|
||||||
from django.db.models.fields import Field
|
from django.db.models.fields import Field
|
||||||
from django.db.models.fields.related import RelatedField
|
from django.db.models.fields.related import RelatedField
|
||||||
from mypy.nodes import AssignmentStmt, TypeInfo, NameExpr
|
from mypy.nodes import AssignmentStmt, NameExpr, TypeInfo
|
||||||
from mypy.plugin import FunctionContext
|
from mypy.plugin import FunctionContext
|
||||||
from mypy.types import AnyType, Instance
|
from mypy.types import AnyType, Instance
|
||||||
from mypy.types import Type as MypyType
|
from mypy.types import Type as MypyType
|
||||||
@@ -22,7 +22,8 @@ def _get_current_field_from_assignment(ctx: FunctionContext, django_context: Dja
|
|||||||
for stmt in outer_model_info.defn.defs.body:
|
for stmt in outer_model_info.defn.defs.body:
|
||||||
if isinstance(stmt, AssignmentStmt):
|
if isinstance(stmt, AssignmentStmt):
|
||||||
if stmt.rvalue == ctx.context:
|
if stmt.rvalue == ctx.context:
|
||||||
assert isinstance(stmt.lvalues[0], NameExpr)
|
if not isinstance(stmt.lvalues[0], NameExpr):
|
||||||
|
return None
|
||||||
field_name = stmt.lvalues[0].name
|
field_name = stmt.lvalues[0].name
|
||||||
break
|
break
|
||||||
if field_name is None:
|
if field_name is None:
|
||||||
@@ -50,16 +51,24 @@ def fill_descriptor_types_for_related_field(ctx: FunctionContext, django_context
|
|||||||
typechecker_api = helpers.get_typechecker_api(ctx)
|
typechecker_api = helpers.get_typechecker_api(ctx)
|
||||||
|
|
||||||
related_model_info = helpers.lookup_class_typeinfo(typechecker_api, related_model)
|
related_model_info = helpers.lookup_class_typeinfo(typechecker_api, related_model)
|
||||||
assert isinstance(related_model_info, TypeInfo)
|
if related_model_info is None:
|
||||||
|
# maybe no type stub
|
||||||
|
related_model_type = AnyType(TypeOfAny.unannotated)
|
||||||
|
else:
|
||||||
|
related_model_type = Instance(related_model_info, []) # type: ignore
|
||||||
|
|
||||||
related_model_to_set_info = helpers.lookup_class_typeinfo(typechecker_api, related_model_to_set)
|
related_model_to_set_info = helpers.lookup_class_typeinfo(typechecker_api, related_model_to_set)
|
||||||
assert isinstance(related_model_to_set_info, TypeInfo)
|
if related_model_to_set_info is None:
|
||||||
|
# maybe no type stub
|
||||||
|
related_model_to_set_type = AnyType(TypeOfAny.unannotated)
|
||||||
|
else:
|
||||||
|
related_model_to_set_type = Instance(related_model_to_set_info, []) # type: ignore
|
||||||
|
|
||||||
default_related_field_type = set_descriptor_types_for_field(ctx)
|
default_related_field_type = set_descriptor_types_for_field(ctx)
|
||||||
# replace Any with referred_to_type
|
# replace Any with referred_to_type
|
||||||
args = [
|
args = [
|
||||||
helpers.convert_any_to_type(default_related_field_type.args[0], Instance(related_model_to_set_info, [])),
|
helpers.convert_any_to_type(default_related_field_type.args[0], related_model_to_set_type),
|
||||||
helpers.convert_any_to_type(default_related_field_type.args[1], Instance(related_model_info, [])),
|
helpers.convert_any_to_type(default_related_field_type.args[1], related_model_type),
|
||||||
]
|
]
|
||||||
return helpers.reparametrize_instance(default_related_field_type, new_args=args)
|
return helpers.reparametrize_instance(default_related_field_type, new_args=args)
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ from typing import List, Tuple, Type, Union
|
|||||||
|
|
||||||
from django.db.models.base import Model
|
from django.db.models.base import Model
|
||||||
from mypy.plugin import FunctionContext, MethodContext
|
from mypy.plugin import FunctionContext, MethodContext
|
||||||
from mypy.types import Instance, Type as MypyType
|
from mypy.types import Instance
|
||||||
|
from mypy.types import Type as MypyType
|
||||||
|
|
||||||
from mypy_django_plugin.django.context import DjangoContext
|
from mypy_django_plugin.django.context import DjangoContext
|
||||||
from mypy_django_plugin.lib import helpers
|
from mypy_django_plugin.lib import helpers
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
from django.core.exceptions import FieldDoesNotExist
|
from django.core.exceptions import FieldDoesNotExist
|
||||||
from mypy.nodes import TypeInfo
|
|
||||||
from mypy.plugin import MethodContext
|
from mypy.plugin import MethodContext
|
||||||
from mypy.types import AnyType, Instance
|
from mypy.types import AnyType, Instance
|
||||||
from mypy.types import Type as MypyType
|
from mypy.types import Type as MypyType
|
||||||
@@ -12,7 +11,8 @@ from mypy_django_plugin.lib import fullnames, helpers
|
|||||||
def _get_field_instance(ctx: MethodContext, field_fullname: str) -> MypyType:
|
def _get_field_instance(ctx: MethodContext, field_fullname: str) -> MypyType:
|
||||||
field_info = helpers.lookup_fully_qualified_typeinfo(helpers.get_typechecker_api(ctx),
|
field_info = helpers.lookup_fully_qualified_typeinfo(helpers.get_typechecker_api(ctx),
|
||||||
field_fullname)
|
field_fullname)
|
||||||
assert isinstance(field_info, TypeInfo)
|
if field_info is None:
|
||||||
|
return AnyType(TypeOfAny.unannotated)
|
||||||
return Instance(field_info, [AnyType(TypeOfAny.explicit), AnyType(TypeOfAny.explicit)])
|
return Instance(field_info, [AnyType(TypeOfAny.explicit), AnyType(TypeOfAny.explicit)])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ from django.core.exceptions import FieldError
|
|||||||
from django.db.models.base import Model
|
from django.db.models.base import Model
|
||||||
from mypy.newsemanal.typeanal import TypeAnalyser
|
from mypy.newsemanal.typeanal import TypeAnalyser
|
||||||
from mypy.nodes import Expression, NameExpr, TypeInfo
|
from mypy.nodes import Expression, NameExpr, TypeInfo
|
||||||
from mypy.plugin import FunctionContext, MethodContext, AnalyzeTypeContext
|
from mypy.plugin import AnalyzeTypeContext, FunctionContext, MethodContext
|
||||||
from mypy.types import AnyType, Instance, Type as MypyType, TypeOfAny
|
from mypy.types import AnyType, Instance
|
||||||
|
from mypy.types import Type as MypyType
|
||||||
|
from mypy.types import TypeOfAny
|
||||||
|
|
||||||
from mypy_django_plugin.django.context import DjangoContext
|
from mypy_django_plugin.django.context import DjangoContext
|
||||||
from mypy_django_plugin.lib import fullnames, helpers
|
from mypy_django_plugin.lib import fullnames, helpers
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from mypy.nodes import MemberExpr, TypeInfo
|
from mypy.nodes import MemberExpr
|
||||||
from mypy.plugin import AttributeContext, FunctionContext
|
from mypy.plugin import AttributeContext, FunctionContext
|
||||||
from mypy.types import Instance, Type as MypyType, TypeType
|
from mypy.types import AnyType, Instance
|
||||||
|
from mypy.types import Type as MypyType
|
||||||
|
from mypy.types import TypeOfAny, TypeType
|
||||||
|
|
||||||
from mypy_django_plugin.django.context import DjangoContext
|
from mypy_django_plugin.django.context import DjangoContext
|
||||||
from mypy_django_plugin.lib import helpers
|
from mypy_django_plugin.lib import helpers
|
||||||
@@ -11,9 +13,10 @@ def get_user_model_hook(ctx: FunctionContext, django_context: DjangoContext) ->
|
|||||||
model_cls = django_context.apps_registry.get_model(auth_user_model)
|
model_cls = django_context.apps_registry.get_model(auth_user_model)
|
||||||
model_cls_fullname = helpers.get_class_fullname(model_cls)
|
model_cls_fullname = helpers.get_class_fullname(model_cls)
|
||||||
|
|
||||||
model_info = helpers.lookup_fully_qualified_generic(model_cls_fullname,
|
model_info = helpers.lookup_fully_qualified_typeinfo(helpers.get_typechecker_api(ctx),
|
||||||
helpers.get_typechecker_api(ctx).modules)
|
model_cls_fullname)
|
||||||
assert isinstance(model_info, TypeInfo)
|
if model_info is None:
|
||||||
|
return AnyType(TypeOfAny.unannotated)
|
||||||
|
|
||||||
return TypeType(Instance(model_info, []))
|
return TypeType(Instance(model_info, []))
|
||||||
|
|
||||||
|
|||||||
@@ -34,3 +34,17 @@
|
|||||||
out: |
|
out: |
|
||||||
main:2: note: Revealed type is 'Any'
|
main:2: note: Revealed type is 'Any'
|
||||||
main:2: error: 'Settings' object has no attribute 'NOT_EXISTING'
|
main:2: error: 'Settings' object has no attribute 'NOT_EXISTING'
|
||||||
|
|
||||||
|
- case: override_default_setting_with_different_type_in_the_different_module
|
||||||
|
custom_settings: |
|
||||||
|
from settings.basic_settings import *
|
||||||
|
main: |
|
||||||
|
from django.conf import settings
|
||||||
|
reveal_type(settings.MEDIA_ROOT) # N: Revealed type is 'pathlib.Path'
|
||||||
|
reveal_type(settings.MEDIA_ROOT / 'part') # N: Revealed type is 'pathlib.Path*'
|
||||||
|
files:
|
||||||
|
- path: settings/__init__.py
|
||||||
|
- path: settings/basic_settings.py
|
||||||
|
content: |
|
||||||
|
from pathlib import Path
|
||||||
|
MEDIA_ROOT = Path()
|
||||||
|
|||||||
Reference in New Issue
Block a user