Fix crash if model from same app referenced in RelatedField cannot be resolved (#199)

* do not crash if model from same app refd in ForeignKey cannot be resolved

* bump to 1.2.0
This commit is contained in:
Maxim Kurnikov
2019-10-05 20:00:51 +03:00
committed by GitHub
parent 717be5940f
commit db9ff6aaf6
7 changed files with 69 additions and 11 deletions

View File

@@ -45,6 +45,8 @@ def fill_descriptor_types_for_related_field(ctx: FunctionContext, django_context
assert isinstance(current_field, RelatedField)
related_model_cls = django_context.get_field_related_model_cls(current_field)
if related_model_cls is None:
return AnyType(TypeOfAny.from_error)
related_model = related_model_cls
related_model_to_set = related_model_cls

View File

@@ -8,11 +8,13 @@ from django.db.models.fields.reverse_related import (
ManyToManyRel, ManyToOneRel, OneToOneRel,
)
from mypy.nodes import (
ARG_STAR2, MDEF, Argument, SymbolTableNode, TypeInfo, Var,
ARG_STAR2, MDEF, Argument, Context, SymbolTableNode, TypeInfo, Var,
)
from mypy.plugin import ClassDefContext
from mypy.plugins import common
from mypy.types import AnyType, Instance, 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.lib import fullnames, helpers
@@ -38,7 +40,7 @@ class ModelClassInitializer:
field_info = self.lookup_typeinfo_or_incomplete_defn_error(fullname)
return field_info
def create_new_var(self, name: str, typ: Instance) -> Var:
def create_new_var(self, name: str, typ: MypyType) -> Var:
# type=: type of the variable itself
var = Var(name=name, type=typ)
# var.info: type of the object variable is bound to
@@ -48,7 +50,7 @@ class ModelClassInitializer:
var.is_inferred = True
return var
def add_new_node_to_model_class(self, name: str, typ: Instance) -> None:
def add_new_node_to_model_class(self, name: str, typ: MypyType) -> None:
var = self.create_new_var(name, typ)
self.model_classdef.info.names[name] = SymbolTableNode(MDEF, var, plugin_generated=True)
@@ -100,6 +102,18 @@ class AddRelatedModelsId(ModelClassInitializer):
for field in model_cls._meta.get_fields():
if isinstance(field, ForeignKey):
related_model_cls = self.django_context.get_field_related_model_cls(field)
if related_model_cls is None:
error_context: Context = self.ctx.cls
field_sym = self.ctx.cls.info.get(field.name)
if field_sym is not None and field_sym.node is not None:
error_context = field_sym.node
self.api.fail(f'Cannot find model {field.related_model!r} '
f'referenced in field {field.name!r} ',
ctx=error_context)
self.add_new_node_to_model_class(field.attname,
AnyType(TypeOfAny.explicit))
continue
rel_primary_key_field = self.django_context.get_primary_key_field(related_model_cls)
field_info = self.lookup_class_typeinfo_or_incomplete_defn_error(rel_primary_key_field.__class__)
is_nullable = self.django_context.get_field_nullability(field, None)
@@ -163,8 +177,10 @@ class AddRelatedManagers(ModelClassInitializer):
continue
related_model_cls = self.django_context.get_field_related_model_cls(relation)
related_model_info = self.lookup_class_typeinfo_or_incomplete_defn_error(related_model_cls)
if related_model_cls is None:
continue
related_model_info = self.lookup_class_typeinfo_or_incomplete_defn_error(related_model_cls)
if isinstance(relation, OneToOneRel):
self.add_new_node_to_model_class(attname, Instance(related_model_info, []))
continue

View File

@@ -49,6 +49,8 @@ def get_field_type_from_lookup(ctx: MethodContext, django_context: DjangoContext
if isinstance(lookup_field, RelatedField) and lookup_field.column == lookup:
related_model_cls = django_context.get_field_related_model_cls(lookup_field)
if related_model_cls is None:
return AnyType(TypeOfAny.from_error)
lookup_field = django_context.get_primary_key_field(related_model_cls)
field_get_type = django_context.get_field_get_type(helpers.get_typechecker_api(ctx),