@@ -758,7 +758,14 @@ def is_dynamic(self) -> bool:
758758 return self .type is None
759759
760760
761- FUNCDEF_FLAGS : Final = FUNCITEM_FLAGS + ["is_decorated" , "is_conditional" , "is_abstract" ]
761+ FUNCDEF_FLAGS : Final = FUNCITEM_FLAGS + ["is_decorated" , "is_conditional" ]
762+
763+ # Abstract status of a function
764+ NOT_ABSTRACT : Final = 0
765+ # Explicitly abstract (with @abstractmethod or overload without implementation)
766+ IS_ABSTRACT : Final = 1
767+ # Implicitly abstract: used for functions with trivial bodies defined in Protocols
768+ IMPLICITLY_ABSTRACT : Final = 2
762769
763770
764771class FuncDef (FuncItem , SymbolNode , Statement ):
@@ -771,7 +778,7 @@ class FuncDef(FuncItem, SymbolNode, Statement):
771778 "_name" ,
772779 "is_decorated" ,
773780 "is_conditional" ,
774- "is_abstract " ,
781+ "abstract_status " ,
775782 "original_def" ,
776783 "deco_line" ,
777784 )
@@ -788,7 +795,7 @@ def __init__(
788795 self ._name = name
789796 self .is_decorated = False
790797 self .is_conditional = False # Defined conditionally (within block)?
791- self .is_abstract = False
798+ self .abstract_status = NOT_ABSTRACT
792799 self .is_final = False
793800 # Original conditional definition
794801 self .original_def : Union [None , FuncDef , Var , Decorator ] = None
@@ -817,6 +824,7 @@ def serialize(self) -> JsonDict:
817824 "arg_kinds" : [int (x .value ) for x in self .arg_kinds ],
818825 "type" : None if self .type is None else self .type .serialize (),
819826 "flags" : get_flags (self , FUNCDEF_FLAGS ),
827+ "abstract_status" : self .abstract_status ,
820828 # TODO: Do we need expanded, original_def?
821829 }
822830
@@ -839,6 +847,7 @@ def deserialize(cls, data: JsonDict) -> "FuncDef":
839847 # NOTE: ret.info is set in the fixup phase.
840848 ret .arg_names = data ["arg_names" ]
841849 ret .arg_kinds = [ArgKind (x ) for x in data ["arg_kinds" ]]
850+ ret .abstract_status = data ["abstract_status" ]
842851 # Leave these uninitialized so that future uses will trigger an error
843852 del ret .arguments
844853 del ret .max_pos
@@ -2674,7 +2683,9 @@ class is generic then it will be a type constructor of higher kind.
26742683 is_abstract : bool # Does the class have any abstract attributes?
26752684 is_protocol : bool # Is this a protocol class?
26762685 runtime_protocol : bool # Does this protocol support isinstance checks?
2677- abstract_attributes : List [str ]
2686+ # List of names of abstract attributes together with their abstract status.
2687+ # The abstract status must be one of `NOT_ABSTRACT`, `IS_ABSTRACT`, `IMPLICITLY_ABSTRACT`.
2688+ abstract_attributes : List [Tuple [str , int ]]
26782689 deletable_attributes : List [str ] # Used by mypyc only
26792690 # Does this type have concrete `__slots__` defined?
26802691 # If class does not have `__slots__` defined then it is `None`,
@@ -3034,7 +3045,7 @@ def deserialize(cls, data: JsonDict) -> "TypeInfo":
30343045 ti = TypeInfo (names , defn , module_name )
30353046 ti ._fullname = data ["fullname" ]
30363047 # TODO: Is there a reason to reconstruct ti.subtypes?
3037- ti .abstract_attributes = data ["abstract_attributes" ]
3048+ ti .abstract_attributes = [( attr [ 0 ], attr [ 1 ]) for attr in data ["abstract_attributes" ] ]
30383049 ti .type_vars = data ["type_vars" ]
30393050 ti .has_param_spec_type = data ["has_param_spec_type" ]
30403051 ti .bases = [mypy .types .Instance .deserialize (b ) for b in data ["bases" ]]
0 commit comments