@@ -1876,6 +1876,10 @@ class is generic then it will be a type constructor of higher kind.
1876
1876
# Method Resolution Order: the order of looking up attributes. The first
1877
1877
# value always to refers to this class.
1878
1878
mro = None # type: List[TypeInfo]
1879
+
1880
+ declared_metaclass = None # type: Optional[mypy.types.Instance]
1881
+ metaclass_type = None # type: mypy.types.Instance
1882
+
1879
1883
subtypes = None # type: Set[TypeInfo] # Direct subclasses encountered so far
1880
1884
names = None # type: SymbolTable # Names defined directly in this type
1881
1885
is_abstract = False # Does the class have any abstract attributes?
@@ -2005,6 +2009,21 @@ def calculate_mro(self) -> None:
2005
2009
self .mro = mro
2006
2010
self .is_enum = self ._calculate_is_enum ()
2007
2011
2012
+ def calculate_metaclass_type (self ) -> 'Optional[mypy.types.Instance]' :
2013
+ declared = self .declared_metaclass
2014
+ if declared is not None and not declared .type .has_base ('builtins.type' ):
2015
+ return declared
2016
+ if self ._fullname == 'builtins.type' :
2017
+ return mypy .types .Instance (self , [])
2018
+ candidates = [s .declared_metaclass for s in self .mro if s .declared_metaclass is not None ]
2019
+ for c in candidates :
2020
+ if all (other .type in c .type .mro for other in candidates ):
2021
+ return c
2022
+ return None
2023
+
2024
+ def is_metaclass (self ) -> bool :
2025
+ return self .has_base ('builtins.type' )
2026
+
2008
2027
def _calculate_is_enum (self ) -> bool :
2009
2028
"""
2010
2029
If this is "enum.Enum" itself, then yes, it's an enum.
@@ -2060,6 +2079,8 @@ def serialize(self) -> JsonDict:
2060
2079
'type_vars' : self .type_vars ,
2061
2080
'bases' : [b .serialize () for b in self .bases ],
2062
2081
'_promote' : None if self ._promote is None else self ._promote .serialize (),
2082
+ 'declared_metaclass' : (None if self .declared_metaclass is None
2083
+ else self .declared_metaclass .serialize ()),
2063
2084
'tuple_type' : None if self .tuple_type is None else self .tuple_type .serialize (),
2064
2085
'typeddict_type' :
2065
2086
None if self .typeddict_type is None else self .typeddict_type .serialize (),
@@ -2081,6 +2102,9 @@ def deserialize(cls, data: JsonDict) -> 'TypeInfo':
2081
2102
ti .bases = [mypy .types .Instance .deserialize (b ) for b in data ['bases' ]]
2082
2103
ti ._promote = (None if data ['_promote' ] is None
2083
2104
else mypy .types .Type .deserialize (data ['_promote' ]))
2105
+ ti .declared_metaclass = (None if data ['declared_metaclass' ] is None
2106
+ else mypy .types .Instance .deserialize (data ['declared_metaclass' ]))
2107
+ # NOTE: ti.metaclass_type and ti.mro will be set in the fixup phase.
2084
2108
ti .tuple_type = (None if data ['tuple_type' ] is None
2085
2109
else mypy .types .TupleType .deserialize (data ['tuple_type' ]))
2086
2110
ti .typeddict_type = (None if data ['typeddict_type' ] is None
0 commit comments