88 ManyToManyRel , ManyToOneRel , OneToOneRel ,
99)
1010from mypy .nodes import (
11- ARG_STAR2 , MDEF , Argument , SymbolTableNode , TypeInfo , Var ,
11+ ARG_STAR2 , MDEF , Argument , Context , SymbolTableNode , TypeInfo , Var ,
1212)
1313from mypy .plugin import ClassDefContext
1414from mypy .plugins import common
15- from mypy .types import AnyType , Instance , TypeOfAny
15+ from mypy .types import AnyType , Instance
16+ from mypy .types import Type as MypyType
17+ from mypy .types import TypeOfAny
1618
1719from mypy_django_plugin .django .context import DjangoContext
1820from mypy_django_plugin .lib import fullnames , helpers
@@ -38,7 +40,7 @@ def lookup_class_typeinfo_or_incomplete_defn_error(self, klass: type) -> TypeInf
3840 field_info = self .lookup_typeinfo_or_incomplete_defn_error (fullname )
3941 return field_info
4042
41- def create_new_var (self , name : str , typ : Instance ) -> Var :
43+ def create_new_var (self , name : str , typ : MypyType ) -> Var :
4244 # type=: type of the variable itself
4345 var = Var (name = name , type = typ )
4446 # var.info: type of the object variable is bound to
@@ -48,7 +50,7 @@ def create_new_var(self, name: str, typ: Instance) -> Var:
4850 var .is_inferred = True
4951 return var
5052
51- def add_new_node_to_model_class (self , name : str , typ : Instance ) -> None :
53+ def add_new_node_to_model_class (self , name : str , typ : MypyType ) -> None :
5254 var = self .create_new_var (name , typ )
5355 self .model_classdef .info .names [name ] = SymbolTableNode (MDEF , var , plugin_generated = True )
5456
@@ -100,6 +102,18 @@ def run_with_model_cls(self, model_cls: Type[Model]) -> None:
100102 for field in model_cls ._meta .get_fields ():
101103 if isinstance (field , ForeignKey ):
102104 related_model_cls = self .django_context .get_field_related_model_cls (field )
105+ if related_model_cls is None :
106+ error_context : Context = self .ctx .cls
107+ field_sym = self .ctx .cls .info .get (field .name )
108+ if field_sym is not None and field_sym .node is not None :
109+ error_context = field_sym .node
110+ self .api .fail (f'Cannot find model { field .related_model !r} '
111+ f'referenced in field { field .name !r} ' ,
112+ ctx = error_context )
113+ self .add_new_node_to_model_class (field .attname ,
114+ AnyType (TypeOfAny .explicit ))
115+ continue
116+
103117 rel_primary_key_field = self .django_context .get_primary_key_field (related_model_cls )
104118 field_info = self .lookup_class_typeinfo_or_incomplete_defn_error (rel_primary_key_field .__class__ )
105119 is_nullable = self .django_context .get_field_nullability (field , None )
@@ -163,8 +177,10 @@ def run_with_model_cls(self, model_cls: Type[Model]) -> None:
163177 continue
164178
165179 related_model_cls = self .django_context .get_field_related_model_cls (relation )
166- related_model_info = self .lookup_class_typeinfo_or_incomplete_defn_error (related_model_cls )
180+ if related_model_cls is None :
181+ continue
167182
183+ related_model_info = self .lookup_class_typeinfo_or_incomplete_defn_error (related_model_cls )
168184 if isinstance (relation , OneToOneRel ):
169185 self .add_new_node_to_model_class (attname , Instance (related_model_info , []))
170186 continue
0 commit comments