1515 StrExpr ,
1616 SymbolTableNode ,
1717 TypeInfo ,
18- Var ,
1918)
20- from mypy .plugin import AttributeContext , ClassDefContext , DynamicClassDefContext
19+ from mypy .plugin import AttributeContext , ClassDefContext , DynamicClassDefContext , MethodContext
2120from mypy .semanal import SemanticAnalyzer
2221from mypy .semanal_shared import has_placeholder
2322from mypy .subtypes import find_member
@@ -552,23 +551,9 @@ def create_new_manager_class_from_as_manager_method(ctx: DynamicClassDefContext)
552551 manager_name = manager_class_name ,
553552 manager_base = manager_base ,
554553 )
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
555556
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
572557 # Add the new manager to the current module
573558 added = semanal_api .add_symbol_table_node (
574559 # We'll use `new_manager_info.name` instead of `manager_class_name` here
@@ -580,6 +565,26 @@ def create_new_manager_class_from_as_manager_method(ctx: DynamicClassDefContext)
580565 assert added
581566
582567
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+ # Whenever `<QuerySet>.as_manager()` isn't called at class level, we want to ensure
581+ # that the variable is an instance of our generated manager. Instead of the return
582+ # value of `.as_manager()`. Though model argument is populated as `Any`.
583+ # `transformers.models.AddManagers` will populate a model's manager(s), when it
584+ # finds it on class level.
585+ return Instance (manager_node .node , [AnyType (TypeOfAny .from_omitted_generics )])
586+
587+
583588def reparametrize_any_manager_hook (ctx : ClassDefContext ) -> None :
584589 """
585590 Add implicit generics to manager classes that are defined without generic.
0 commit comments