Skip to content

Commit 279066f

Browse files
committed
move meta to new API
1 parent c6e68ce commit 279066f

File tree

5 files changed

+55
-64
lines changed

5 files changed

+55
-64
lines changed

mypy_django_plugin/lib/helpers.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,13 @@ def lookup_typeinfo(self, fullname: str) -> Optional[TypeInfo]:
185185

186186
class GetMethodCallback(TypeCheckerPluginCallback):
187187
ctx: MethodContext
188+
callee_type: Instance
188189
default_return_type: MypyType
189190

190191
def __call__(self, ctx: MethodContext) -> MypyType:
191192
self.type_checker = cast(TypeChecker, ctx.api)
192193
self.ctx = ctx
194+
self.callee_type = cast(Instance, ctx.type)
193195
self.default_return_type = self.ctx.default_return_type
194196
return self.get_method_return_type()
195197

mypy_django_plugin/main.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@
1414
import mypy_django_plugin.transformers.orm_lookups
1515
from mypy_django_plugin.django.context import DjangoContext
1616
from mypy_django_plugin.lib import fullnames, helpers
17-
from mypy_django_plugin.transformers import init_create, meta, querysets
17+
from mypy_django_plugin.transformers import init_create, querysets
1818
from mypy_django_plugin.transformers2.fields import FieldContructorCallback
1919
from mypy_django_plugin.transformers2.forms import (
2020
FormCallback, GetFormCallback, GetFormClassCallback,
2121
)
22+
from mypy_django_plugin.transformers2.meta import MetaGetFieldCallback
2223
from mypy_django_plugin.transformers2.models import ModelCallback
2324
from mypy_django_plugin.transformers2.related_managers import (
2425
GetRelatedManagerCallback,
@@ -198,7 +199,7 @@ def get_method_hook(self, fullname: str
198199
if method_name == 'get_field':
199200
info = self._get_typeinfo_or_none(class_fullname)
200201
if info and info.has_base(fullnames.OPTIONS_CLASS_FULLNAME):
201-
return partial(meta.return_proper_field_type_from_get_field, django_context=self.django_context)
202+
return MetaGetFieldCallback(self)
202203

203204
manager_classes = self._get_current_manager_bases()
204205
if class_fullname in manager_classes and method_name == 'create':

mypy_django_plugin/transformers/meta.py

Lines changed: 0 additions & 52 deletions
This file was deleted.

mypy_django_plugin/transformers2/forms.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,18 @@ def modify_class_defn(self) -> None:
1616

1717

1818
class FormMethodCallback(helpers.GetMethodCallback):
19-
def get_specified_form_class(self, object_type: Instance) -> Optional[TypeType]:
20-
form_class_sym = object_type.type.get('form_class')
19+
def get_specified_form_class(self) -> Optional[TypeType]:
20+
form_class_sym = self.callee_type.type.get('form_class')
2121
if form_class_sym and isinstance(form_class_sym.type, CallableType):
2222
return TypeType(form_class_sym.type.ret_type)
2323
return None
2424

2525

2626
class GetFormCallback(FormMethodCallback):
2727
def get_method_return_type(self) -> MypyType:
28-
object_type = self.ctx.type
29-
assert isinstance(object_type, Instance)
30-
3128
form_class_type = chk_helpers.get_call_argument_type_by_name(self.ctx, 'form_class')
3229
if form_class_type is None or isinstance(form_class_type, NoneTyp):
33-
form_class_type = self.get_specified_form_class(object_type)
30+
form_class_type = self.get_specified_form_class()
3431

3532
if isinstance(form_class_type, TypeType) and isinstance(form_class_type.item, Instance):
3633
return form_class_type.item
@@ -43,10 +40,7 @@ def get_method_return_type(self) -> MypyType:
4340

4441
class GetFormClassCallback(FormMethodCallback):
4542
def get_method_return_type(self) -> MypyType:
46-
object_type = self.ctx.type
47-
assert isinstance(object_type, Instance)
48-
49-
form_class_type = self.get_specified_form_class(object_type)
43+
form_class_type = self.get_specified_form_class()
5044
if form_class_type is None:
5145
return self.default_return_type
5246

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from django.core.exceptions import FieldDoesNotExist
2+
from mypy.types import AnyType, Instance
3+
from mypy.types import Type as MypyType
4+
from mypy.types import TypeOfAny
5+
6+
from mypy_django_plugin.lib import chk_helpers, helpers
7+
8+
9+
class MetaGetFieldCallback(helpers.GetMethodCallback):
10+
def _get_field_instance(self, field_fullname: str) -> MypyType:
11+
field_info = helpers.lookup_fully_qualified_typeinfo(self.type_checker, field_fullname)
12+
if field_info is None:
13+
return AnyType(TypeOfAny.unannotated)
14+
return Instance(field_info, [AnyType(TypeOfAny.explicit), AnyType(TypeOfAny.explicit)])
15+
16+
def get_method_return_type(self) -> MypyType:
17+
# bail if list of generic params is empty
18+
if len(self.callee_type.args) == 0:
19+
return self.default_return_type
20+
21+
model_type = self.callee_type.args[0]
22+
if not isinstance(model_type, Instance):
23+
return self.default_return_type
24+
25+
model_cls = self.django_context.get_model_class_by_fullname(model_type.type.fullname)
26+
if model_cls is None:
27+
return self.default_return_type
28+
29+
field_name_expr = chk_helpers.get_call_argument_by_name(self.ctx, 'field_name')
30+
if field_name_expr is None:
31+
return self.default_return_type
32+
33+
field_name = helpers.resolve_string_attribute_value(field_name_expr, self.django_context)
34+
if field_name is None:
35+
return self.default_return_type
36+
37+
try:
38+
field = model_cls._meta.get_field(field_name)
39+
except FieldDoesNotExist as exc:
40+
# if model is abstract, do not raise exception, skip false positives
41+
if not model_cls._meta.abstract:
42+
self.ctx.api.fail(exc.args[0], self.ctx.context)
43+
return AnyType(TypeOfAny.from_error)
44+
45+
field_fullname = helpers.get_class_fullname(field.__class__)
46+
return self._get_field_instance(field_fullname)

0 commit comments

Comments
 (0)