43
43
traverse the entire AST.
44
44
"""
45
45
46
- import sys
47
46
from typing import (
48
- List , Dict , Set , Tuple , cast , Any , overload , TypeVar , Union , Optional , Callable
47
+ List , Dict , Set , Tuple , cast , Any , TypeVar , Union , Optional , Callable
49
48
)
50
49
51
50
from mypy .nodes import (
65
64
SetComprehension , DictionaryComprehension , TYPE_ALIAS , TypeAliasExpr ,
66
65
YieldExpr , ExecStmt , Argument , BackquoteExpr , ImportBase , AwaitExpr ,
67
66
IntExpr , FloatExpr , UnicodeExpr ,
67
+ Expression , EllipsisExpr , namedtuple_type_info ,
68
68
COVARIANT , CONTRAVARIANT , INVARIANT , UNBOUND_IMPORTED , LITERAL_YES ,
69
69
)
70
70
from mypy .visitor import NodeVisitor
71
71
from mypy .traverser import TraverserVisitor
72
72
from mypy .errors import Errors , report_internal_error
73
73
from mypy .types import (
74
74
NoneTyp , CallableType , Overloaded , Instance , Type , TypeVarType , AnyType ,
75
- FunctionLike , UnboundType , TypeList , ErrorType , TypeVarDef , Void ,
76
- replace_leading_arg_type , TupleType , UnionType , StarType , EllipsisType
77
- )
75
+ FunctionLike , UnboundType , TypeList , TypeVarDef ,
76
+ replace_leading_arg_type , TupleType , UnionType , StarType , EllipsisType , TypeType )
78
77
from mypy .nodes import function_type , implicit_module_attrs
79
78
from mypy .typeanal import TypeAnalyser , TypeAnalyserPass3 , analyze_type_alias
80
79
from mypy .exprtotype import expr_to_unanalyzed_type , TypeTranslationError
81
- from mypy .lex import lex
82
- from mypy .parsetype import parse_type
83
80
from mypy .sametypes import is_same_type
84
81
from mypy .erasetype import erase_typevars
85
- from mypy import defaults
86
82
from mypy .options import Options
87
83
88
84
@@ -319,9 +315,8 @@ def visit_func_def(self, defn: FuncDef) -> None:
319
315
# A coroutine defined as `async def foo(...) -> T: ...`
320
316
# has external return type `Awaitable[T]`.
321
317
defn .type = defn .type .copy_modified (
322
- ret_type = Instance (
323
- self .named_type_or_none ('typing.Awaitable' ).type ,
324
- [defn .type .ret_type ]))
318
+ ret_type = self .named_type_or_none ('typing.Awaitable' ,
319
+ [defn .type .ret_type ]))
325
320
self .errors .pop_function ()
326
321
327
322
def prepare_method_signature (self , func : FuncDef ) -> None :
@@ -751,38 +746,40 @@ def analyze_base_classes(self, defn: ClassDef) -> None:
751
746
"""
752
747
753
748
base_types = [] # type: List[Instance]
749
+ info = defn .info
754
750
for base_expr in defn .base_type_exprs :
755
751
try :
756
752
base = self .expr_to_analyzed_type (base_expr )
757
753
except TypeTranslationError :
758
754
self .fail ('Invalid base class' , base_expr )
759
- defn . info .fallback_to_any = True
755
+ info .fallback_to_any = True
760
756
continue
761
757
762
758
if isinstance (base , TupleType ):
763
- if defn . info .tuple_type :
759
+ if info .tuple_type :
764
760
self .fail ("Class has two incompatible bases derived from tuple" , defn )
761
+ defn .has_incompatible_baseclass = True
765
762
if (not self .is_stub_file
766
- and not defn . info .is_named_tuple
763
+ and not info .is_named_tuple
767
764
and base .fallback .type .fullname () == 'builtins.tuple' ):
768
765
self .fail ("Tuple[...] not supported as a base class outside a stub file" , defn )
769
- defn . info .tuple_type = base
766
+ info .tuple_type = base
770
767
base_types .append (base .fallback )
771
768
elif isinstance (base , Instance ):
772
769
if base .type .is_newtype :
773
770
self .fail ("Cannot subclass NewType" , defn )
774
771
base_types .append (base )
775
772
elif isinstance (base , AnyType ):
776
- defn . info .fallback_to_any = True
773
+ info .fallback_to_any = True
777
774
else :
778
775
self .fail ('Invalid base class' , base_expr )
779
- defn . info .fallback_to_any = True
776
+ info .fallback_to_any = True
780
777
781
778
# Add 'object' as implicit base if there is no other base class.
782
779
if (not base_types and defn .fullname != 'builtins.object' ):
783
780
base_types .append (self .object_type ())
784
781
785
- defn . info .bases = base_types
782
+ info .bases = base_types
786
783
787
784
# Calculate the MRO. It might be incomplete at this point if
788
785
# the bases of defn include classes imported from other
@@ -794,8 +791,8 @@ def analyze_base_classes(self, defn: ClassDef) -> None:
794
791
calculate_class_mro (defn , self .fail_blocker )
795
792
# If there are cyclic imports, we may be missing 'object' in
796
793
# the MRO. Fix MRO if needed.
797
- if defn . info .mro and defn . info .mro [- 1 ].fullname () != 'builtins.object' :
798
- defn . info .mro .append (self .object_type ().type )
794
+ if info .mro and info .mro [- 1 ].fullname () != 'builtins.object' :
795
+ info .mro .append (self .object_type ().type )
799
796
800
797
def expr_to_analyzed_type (self , expr : Node ) -> Type :
801
798
if isinstance (expr , CallExpr ):
@@ -866,11 +863,11 @@ def named_type(self, qualified_name: str, args: List[Type] = None) -> Instance:
866
863
sym = self .lookup_qualified (qualified_name , None )
867
864
return Instance (cast (TypeInfo , sym .node ), args or [])
868
865
869
- def named_type_or_none (self , qualified_name : str ) -> Instance :
866
+ def named_type_or_none (self , qualified_name : str , args : List [ Type ] = None ) -> Instance :
870
867
sym = self .lookup_fully_qualified_or_none (qualified_name )
871
868
if not sym :
872
869
return None
873
- return Instance (cast (TypeInfo , sym .node ), [])
870
+ return Instance (cast (TypeInfo , sym .node ), args or [])
874
871
875
872
def is_instance_type (self , t : Type ) -> bool :
876
873
return isinstance (t , Instance )
@@ -1627,6 +1624,7 @@ def parse_namedtuple_args(self, call: CallExpr,
1627
1624
if len (args ) < 2 :
1628
1625
return self .fail_namedtuple_arg ("Too few arguments for namedtuple()" , call )
1629
1626
if len (args ) > 2 :
1627
+ # FIX incorrect. There are two additional parameters
1630
1628
return self .fail_namedtuple_arg ("Too many arguments for namedtuple()" , call )
1631
1629
if call .arg_kinds != [ARG_POS , ARG_POS ]:
1632
1630
return self .fail_namedtuple_arg ("Unexpected arguments to namedtuple()" , call )
@@ -1639,7 +1637,7 @@ def parse_namedtuple_args(self, call: CallExpr,
1639
1637
if (fullname == 'collections.namedtuple'
1640
1638
and isinstance (args [1 ], (StrExpr , BytesExpr , UnicodeExpr ))):
1641
1639
str_expr = cast (StrExpr , args [1 ])
1642
- items = str_expr .value .split ()
1640
+ items = str_expr .value .replace ( ',' , ' ' ). split ()
1643
1641
else :
1644
1642
return self .fail_namedtuple_arg (
1645
1643
"List literal expected as the second argument to namedtuple()" , call )
@@ -1689,48 +1687,74 @@ def fail_namedtuple_arg(self, message: str,
1689
1687
1690
1688
def build_namedtuple_typeinfo (self , name : str , items : List [str ],
1691
1689
types : List [Type ]) -> TypeInfo :
1690
+ strtype = self .named_type ('__builtins__.str' ) # type: Type
1691
+ basetuple_type = self .named_type ('__builtins__.tuple' , [AnyType ()])
1692
+ dictype = (self .named_type_or_none ('builtins.dict' , [strtype , AnyType ()])
1693
+ or self .object_type ())
1694
+ # Actual signature should return OrderedDict[str, Union[types]]
1695
+ ordereddictype = (self .named_type_or_none ('builtins.dict' , [strtype , AnyType ()])
1696
+ or self .object_type ())
1697
+ fallback = self .named_type ('__builtins__.tuple' , types )
1698
+ # Note: actual signature should accept an invariant version of Iterable[UnionType[types]].
1699
+ # but it can't be expressed. 'new' and 'len' should be callable types.
1700
+ iterable_type = self .named_type_or_none ('typing.Iterable' , [AnyType ()])
1701
+ function_type = self .named_type ('__builtins__.function' )
1702
+ fullname = self .qualified_name (name )
1703
+
1692
1704
symbols = SymbolTable ()
1693
1705
class_def = ClassDef (name , Block ([]))
1694
- class_def .fullname = self .qualified_name (name )
1695
- info = TypeInfo (symbols , class_def )
1696
- # Add named tuple items as attributes.
1697
- # TODO: Make them read-only.
1698
- for item , typ in zip (items , types ):
1699
- var = Var (item )
1706
+ class_def .fullname = fullname
1707
+ info = namedtuple_type_info (TupleType (types , fallback ), symbols , class_def )
1708
+
1709
+ def add_field (var : Var , is_initialized_in_class : bool = False ,
1710
+ is_property : bool = False ) -> None :
1700
1711
var .info = info
1701
- var .type = typ
1702
- symbols [item ] = SymbolTableNode (MDEF , var )
1703
- # Add a __init__ method.
1704
- init = self .make_namedtuple_init (info , items , types )
1705
- symbols ['__init__' ] = SymbolTableNode (MDEF , init )
1706
- info .tuple_type = TupleType (types , self .named_type ('__builtins__.tuple' , [AnyType ()]))
1707
- info .is_named_tuple = True
1708
- info .mro = [info ] + info .tuple_type .fallback .type .mro
1709
- info .bases = [info .tuple_type .fallback ]
1712
+ var .is_initialized_in_class = is_initialized_in_class
1713
+ var .is_property = is_property
1714
+ symbols [var .name ()] = SymbolTableNode (MDEF , var )
1715
+
1716
+ vars = [Var (item , typ ) for item , typ in zip (items , types )]
1717
+ for var in vars :
1718
+ add_field (var , is_property = True )
1719
+
1720
+ tuple_of_strings = TupleType ([strtype for _ in items ], basetuple_type )
1721
+ add_field (Var ('_fields' , tuple_of_strings ), is_initialized_in_class = True )
1722
+ add_field (Var ('_field_types' , dictype ), is_initialized_in_class = True )
1723
+ add_field (Var ('_source' , strtype ), is_initialized_in_class = True )
1724
+
1725
+ # TODO: SelfType should be bind to actual 'self'
1726
+ this_type = self_type (info )
1727
+
1728
+ def add_method (funcname : str , ret : Type , args : List [Argument ], name = None ,
1729
+ is_classmethod = False ) -> None :
1730
+ if not is_classmethod :
1731
+ args = [Argument (Var ('self' ), this_type , None , ARG_POS )] + args
1732
+ types = [arg .type_annotation for arg in args ]
1733
+ items = [arg .variable .name () for arg in args ]
1734
+ arg_kinds = [arg .kind for arg in args ]
1735
+ signature = CallableType (types , arg_kinds , items , ret , function_type ,
1736
+ name = name or info .name () + '.' + funcname )
1737
+ signature .is_classmethod_class = is_classmethod
1738
+ func = FuncDef (funcname , args , Block ([]), typ = signature )
1739
+ func .info = info
1740
+ func .is_class = is_classmethod
1741
+ symbols [funcname ] = SymbolTableNode (MDEF , func )
1742
+
1743
+ add_method ('_replace' , ret = this_type ,
1744
+ args = [Argument (var , var .type , EllipsisExpr (), ARG_NAMED ) for var in vars ])
1745
+ add_method ('__init__' , ret = NoneTyp (), name = info .name (),
1746
+ args = [Argument (var , var .type , None , ARG_POS ) for var in vars ])
1747
+ add_method ('_asdict' , args = [], ret = ordereddictype )
1748
+ # FIX: make it actual class method
1749
+ add_method ('_make' , ret = this_type , is_classmethod = True ,
1750
+ args = [Argument (Var ('iterable' , iterable_type ), iterable_type , None , ARG_POS ),
1751
+ Argument (Var ('new' ), AnyType (), EllipsisExpr (), ARG_NAMED ),
1752
+ Argument (Var ('len' ), AnyType (), EllipsisExpr (), ARG_NAMED )])
1710
1753
return info
1711
1754
1712
1755
def make_argument (self , name : str , type : Type ) -> Argument :
1713
1756
return Argument (Var (name ), type , None , ARG_POS )
1714
1757
1715
- def make_namedtuple_init (self , info : TypeInfo , items : List [str ],
1716
- types : List [Type ]) -> FuncDef :
1717
- args = [self .make_argument (item , type ) for item , type in zip (items , types )]
1718
- # TODO: Make sure that the self argument name is not visible?
1719
- args = [Argument (Var ('__self' ), NoneTyp (), None , ARG_POS )] + args
1720
- arg_kinds = [arg .kind for arg in args ]
1721
- signature = CallableType ([cast (Type , None )] + types ,
1722
- arg_kinds ,
1723
- ['__self' ] + items ,
1724
- NoneTyp (),
1725
- self .named_type ('__builtins__.function' ),
1726
- name = info .name ())
1727
- func = FuncDef ('__init__' ,
1728
- args ,
1729
- Block ([]),
1730
- typ = signature )
1731
- func .info = info
1732
- return func
1733
-
1734
1758
def analyze_types (self , items : List [Node ]) -> List [Type ]:
1735
1759
result = [] # type: List[Type]
1736
1760
for node in items :
@@ -2477,6 +2501,8 @@ def fail(self, msg: str, ctx: Context, serious: bool = False, *,
2477
2501
self .function_stack and
2478
2502
self .function_stack [- 1 ].is_dynamic ()):
2479
2503
return
2504
+ # In case it's a bug and we don't really have context
2505
+ assert ctx is not None , msg
2480
2506
self .errors .report (ctx .get_line (), msg , blocker = blocker )
2481
2507
2482
2508
def fail_blocker (self , msg : str , ctx : Context ) -> None :
@@ -2832,8 +2858,7 @@ def self_type(typ: TypeInfo) -> Union[Instance, TupleType]:
2832
2858
inst = Instance (typ , tv )
2833
2859
if typ .tuple_type is None :
2834
2860
return inst
2835
- else :
2836
- return TupleType (typ .tuple_type .items , inst )
2861
+ return typ .tuple_type .copy_modified (fallback = inst )
2837
2862
2838
2863
2839
2864
def replace_implicit_first_type (sig : FunctionLike , new : Type ) -> FunctionLike :
0 commit comments