1313from mypy import experiments
1414from mypy .nodes import (
1515 INVARIANT , SymbolNode , ARG_POS , ARG_OPT , ARG_STAR , ARG_STAR2 , ARG_NAMED , ARG_NAMED_OPT ,
16+ FuncDef
1617)
1718from mypy .sharedparse import argument_elide_name
1819from mypy .util import IdMapper
@@ -676,6 +677,8 @@ class CallableType(FunctionLike):
676677 # instantiation?
677678 'bound_args' , # Bound type args, mostly unused but may be useful for
678679 # tools that consume mypy ASTs
680+ 'def_extras' , # Information about original definition we want to serialize.
681+ # This is used for more detailed error messages.
679682 )
680683
681684 def __init__ (self ,
@@ -695,6 +698,7 @@ def __init__(self,
695698 special_sig : Optional [str ] = None ,
696699 from_type_type : bool = False ,
697700 bound_args : Sequence [Optional [Type ]] = (),
701+ def_extras : Optional [Dict [str , Any ]] = None ,
698702 ) -> None :
699703 super ().__init__ (line , column )
700704 assert len (arg_types ) == len (arg_kinds ) == len (arg_names )
@@ -721,6 +725,18 @@ def __init__(self,
721725 if not bound_args :
722726 bound_args = ()
723727 self .bound_args = bound_args
728+ if def_extras :
729+ self .def_extras = def_extras
730+ elif isinstance (definition , FuncDef ):
731+ # This information would be lost if we don't have definition
732+ # after serialization, but it is useful in error messages.
733+ # TODO: decide how to add more info here (file, line, column)
734+ # without changing interface hash.
735+ self .def_extras = {'first_arg' : definition .arg_names [0 ]
736+ if definition .arg_names and definition .info and
737+ not definition .is_static else None }
738+ else :
739+ self .def_extras = {}
724740
725741 def copy_modified (self ,
726742 arg_types : List [Type ] = _dummy ,
@@ -736,7 +752,8 @@ def copy_modified(self,
736752 is_ellipsis_args : bool = _dummy ,
737753 special_sig : Optional [str ] = _dummy ,
738754 from_type_type : bool = _dummy ,
739- bound_args : List [Optional [Type ]] = _dummy ) -> 'CallableType' :
755+ bound_args : List [Optional [Type ]] = _dummy ,
756+ def_extras : Dict [str , Any ] = _dummy ) -> 'CallableType' :
740757 return CallableType (
741758 arg_types = arg_types if arg_types is not _dummy else self .arg_types ,
742759 arg_kinds = arg_kinds if arg_kinds is not _dummy else self .arg_kinds ,
@@ -755,6 +772,7 @@ def copy_modified(self,
755772 special_sig = special_sig if special_sig is not _dummy else self .special_sig ,
756773 from_type_type = from_type_type if from_type_type is not _dummy else self .from_type_type ,
757774 bound_args = bound_args if bound_args is not _dummy else self .bound_args ,
775+ def_extras = def_extras if def_extras is not _dummy else dict (self .def_extras ),
758776 )
759777
760778 def is_type_obj (self ) -> bool :
@@ -907,6 +925,7 @@ def serialize(self) -> JsonDict:
907925 'is_classmethod_class' : self .is_classmethod_class ,
908926 'bound_args' : [(None if t is None else t .serialize ())
909927 for t in self .bound_args ],
928+ 'def_extras' : dict (self .def_extras ),
910929 }
911930
912931 @classmethod
@@ -925,6 +944,7 @@ def deserialize(cls, data: JsonDict) -> 'CallableType':
925944 is_classmethod_class = data ['is_classmethod_class' ],
926945 bound_args = [(None if t is None else deserialize_type (t ))
927946 for t in data ['bound_args' ]],
947+ def_extras = data ['def_extras' ]
928948 )
929949
930950
0 commit comments