15
15
StrExpr ,
16
16
SymbolTableNode ,
17
17
TypeInfo ,
18
- Var ,
19
18
)
20
- from mypy .plugin import AttributeContext , ClassDefContext , DynamicClassDefContext
19
+ from mypy .plugin import AttributeContext , ClassDefContext , DynamicClassDefContext , MethodContext
21
20
from mypy .semanal import SemanticAnalyzer
22
21
from mypy .semanal_shared import has_placeholder
23
22
from mypy .subtypes import find_member
@@ -552,23 +551,9 @@ def create_new_manager_class_from_as_manager_method(ctx: DynamicClassDefContext)
552
551
manager_name = manager_class_name ,
553
552
manager_base = manager_base ,
554
553
)
554
+ queryset_info .metadata .setdefault ("django_as_manager_names" , {})
555
+ queryset_info .metadata ["django_as_manager_names" ][semanal_api .cur_mod_id ] = new_manager_info .name
555
556
556
- # Whenever `<QuerySet>.as_manager()` isn't called at class level, we want to ensure
557
- # that the variable is an instance of our generated manager. Instead of the return
558
- # value of `.as_manager()`. Though model argument is populated as `Any`.
559
- # `transformers.models.AddManagers` will populate a model's manager(s), when it
560
- # finds it on class level.
561
- var = Var (name = ctx .name , type = Instance (new_manager_info , [AnyType (TypeOfAny .from_omitted_generics )]))
562
- var .info = new_manager_info
563
- var ._fullname = f"{ current_module .fullname } .{ ctx .name } "
564
- var .is_inferred = True
565
- # Note: Order of `add_symbol_table_node` calls matters. Depending on what level
566
- # we've found the `.as_manager()` call. Point here being that we want to replace the
567
- # `.as_manager` return value with our newly created manager.
568
- added = semanal_api .add_symbol_table_node (
569
- ctx .name , SymbolTableNode (semanal_api .current_symbol_kind (), var , plugin_generated = True )
570
- )
571
- assert added
572
557
# Add the new manager to the current module
573
558
added = semanal_api .add_symbol_table_node (
574
559
# We'll use `new_manager_info.name` instead of `manager_class_name` here
@@ -580,6 +565,27 @@ def create_new_manager_class_from_as_manager_method(ctx: DynamicClassDefContext)
580
565
assert added
581
566
582
567
568
+ def construct_as_manager_instance (ctx : MethodContext , * , info : TypeInfo ) -> MypyType :
569
+ api = helpers .get_typechecker_api (ctx )
570
+ module = helpers .get_current_module (api )
571
+ try :
572
+ manager_name = info .metadata ["django_as_manager_names" ][module .fullname ]
573
+ except KeyError :
574
+ return ctx .default_return_type
575
+
576
+ manager_node = api .lookup (manager_name )
577
+ if not isinstance (manager_node .node , TypeInfo ):
578
+ return ctx .default_return_type
579
+
580
+ outer_model_info = helpers .get_typechecker_api (ctx ).scope .active_class ()
581
+ if outer_model_info is not None and outer_model_info .self_type is not None :
582
+ model_tp : MypyType = outer_model_info .self_type
583
+ else :
584
+ model_tp = AnyType (TypeOfAny .from_omitted_generics )
585
+
586
+ return Instance (manager_node .node , [model_tp ])
587
+
588
+
583
589
def reparametrize_any_manager_hook (ctx : ClassDefContext ) -> None :
584
590
"""
585
591
Add implicit generics to manager classes that are defined without generic.
0 commit comments