Skip to content

Commit b8f2902

Browse files
authored
Suppress IncompleteDefnException on final_iteration and continue with the loop (#260)
* suppress IncompleteDefnException on final_iteration * lint
1 parent eba3f6c commit b8f2902

File tree

2 files changed

+50
-16
lines changed

2 files changed

+50
-16
lines changed

mypy_django_plugin/lib/fullnames.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
QUERYSET_CLASS_FULLNAME = 'django.db.models.query.QuerySet'
1414
BASE_MANAGER_CLASS_FULLNAME = 'django.db.models.manager.BaseManager'
1515
MANAGER_CLASS_FULLNAME = 'django.db.models.manager.Manager'
16-
RELATED_MANAGER_CLASS_FULLNAME = 'django.db.models.manager.RelatedManager'
16+
RELATED_MANAGER_CLASS = 'django.db.models.manager.RelatedManager'
1717

1818
BASEFORM_CLASS_FULLNAME = 'django.forms.forms.BaseForm'
1919
FORM_CLASS_FULLNAME = 'django.forms.forms.Form'
@@ -23,7 +23,7 @@
2323

2424
MANAGER_CLASSES = {
2525
MANAGER_CLASS_FULLNAME,
26-
RELATED_MANAGER_CLASS_FULLNAME,
26+
RELATED_MANAGER_CLASS,
2727
BASE_MANAGER_CLASS_FULLNAME,
2828
# QUERYSET_CLASS_FULLNAME
2929
}

mypy_django_plugin/transformers/models.py

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
ManyToManyRel, ManyToOneRel, OneToOneRel,
99
)
1010
from mypy.nodes import ARG_STAR2, Argument, Context, FuncDef, TypeInfo, Var
11-
from mypy.plugin import ClassDefContext
11+
from mypy.plugin import ClassDefContext, SemanticAnalyzerPluginInterface
1212
from mypy.plugins import common
1313
from mypy.plugins.common import add_method
1414
from mypy.types import AnyType, CallableType, Instance
@@ -22,6 +22,8 @@
2222

2323

2424
class ModelClassInitializer:
25+
api: SemanticAnalyzerPluginInterface
26+
2527
def __init__(self, ctx: ClassDefContext, django_context: DjangoContext):
2628
self.api = ctx.api
2729
self.model_classdef = ctx.cls
@@ -118,7 +120,14 @@ def run_with_model_cls(self, model_cls: Type[Model]) -> None:
118120
continue
119121

120122
rel_primary_key_field = self.django_context.get_primary_key_field(related_model_cls)
121-
field_info = self.lookup_class_typeinfo_or_incomplete_defn_error(rel_primary_key_field.__class__)
123+
try:
124+
field_info = self.lookup_class_typeinfo_or_incomplete_defn_error(rel_primary_key_field.__class__)
125+
except helpers.IncompleteDefnException as exc:
126+
if not self.api.final_iteration:
127+
raise exc
128+
else:
129+
continue
130+
122131
is_nullable = self.django_context.get_field_nullability(field, None)
123132
set_type, get_type = get_field_descriptor_types(field_info, is_nullable)
124133
self.add_new_node_to_model_class(field.attname,
@@ -132,7 +141,13 @@ def _is_manager_any(self, typ: Instance) -> bool:
132141
def run_with_model_cls(self, model_cls: Type[Model]) -> None:
133142
for manager_name, manager in model_cls._meta.managers_map.items():
134143
manager_fullname = helpers.get_class_fullname(manager.__class__)
135-
manager_info = self.lookup_typeinfo_or_incomplete_defn_error(manager_fullname)
144+
try:
145+
manager_info = self.lookup_typeinfo_or_incomplete_defn_error(manager_fullname)
146+
except helpers.IncompleteDefnException as exc:
147+
if not self.api.final_iteration:
148+
raise exc
149+
else:
150+
continue
136151

137152
if manager_name not in self.model_classdef.info.names:
138153
manager_type = Instance(manager_info, [Instance(self.model_classdef.info, [])])
@@ -143,15 +158,21 @@ def run_with_model_cls(self, model_cls: Type[Model]) -> None:
143158
if has_manager_any_base:
144159
custom_model_manager_name = manager.model.__name__ + '_' + manager.__class__.__name__
145160

146-
bases = []
147-
for original_base in manager_info.bases:
148-
if self._is_manager_any(original_base):
149-
if original_base.type is None:
150-
raise helpers.IncompleteDefnException()
151-
152-
original_base = helpers.reparametrize_instance(original_base,
153-
[Instance(self.model_classdef.info, [])])
154-
bases.append(original_base)
161+
try:
162+
bases = []
163+
for original_base in manager_info.bases:
164+
if self._is_manager_any(original_base):
165+
if original_base.type is None:
166+
raise helpers.IncompleteDefnException()
167+
168+
original_base = helpers.reparametrize_instance(original_base,
169+
[Instance(self.model_classdef.info, [])])
170+
bases.append(original_base)
171+
except helpers.IncompleteDefnException as exc:
172+
if not self.api.final_iteration:
173+
raise exc
174+
else:
175+
continue
155176

156177
current_module = self.api.modules[self.model_classdef.info.module_name]
157178
custom_manager_info = helpers.add_new_class_for_module(current_module,
@@ -223,13 +244,26 @@ def run_with_model_cls(self, model_cls: Type[Model]) -> None:
223244
if related_model_cls is None:
224245
continue
225246

226-
related_model_info = self.lookup_class_typeinfo_or_incomplete_defn_error(related_model_cls)
247+
try:
248+
related_model_info = self.lookup_class_typeinfo_or_incomplete_defn_error(related_model_cls)
249+
except helpers.IncompleteDefnException as exc:
250+
if not self.api.final_iteration:
251+
raise exc
252+
else:
253+
continue
254+
227255
if isinstance(relation, OneToOneRel):
228256
self.add_new_node_to_model_class(attname, Instance(related_model_info, []))
229257
continue
230258

231259
if isinstance(relation, (ManyToOneRel, ManyToManyRel)):
232-
manager_info = self.lookup_typeinfo_or_incomplete_defn_error(fullnames.RELATED_MANAGER_CLASS_FULLNAME)
260+
try:
261+
manager_info = self.lookup_typeinfo_or_incomplete_defn_error(fullnames.RELATED_MANAGER_CLASS)
262+
except helpers.IncompleteDefnException as exc:
263+
if not self.api.final_iteration:
264+
raise exc
265+
else:
266+
continue
233267
self.add_new_node_to_model_class(attname,
234268
Instance(manager_info, [Instance(related_model_info, [])]))
235269
continue

0 commit comments

Comments
 (0)