diff --git a/mypy/semanal.py b/mypy/semanal.py index 610b038a0458..5975eada653a 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -71,7 +71,7 @@ from mypy.errors import Errors, report_internal_error from mypy.types import ( NoneTyp, CallableType, Overloaded, Instance, Type, TypeVarType, AnyType, - FunctionLike, UnboundType, TypeList, TypeVarDef, TypeType, + FunctionLike, UnboundType, TypeList, TypeVarDef, TupleType, UnionType, StarType, EllipsisType, function_type) from mypy.nodes import implicit_module_attrs from mypy.typeanal import TypeAnalyser, TypeAnalyserPass3, analyze_type_alias @@ -1803,41 +1803,31 @@ def add_field(var: Var, is_initialized_in_class: bool = False, add_field(Var('_field_types', dictype), is_initialized_in_class=True) add_field(Var('_source', strtype), is_initialized_in_class=True) - tvd = TypeVarDef('NT', 1, [], fill_typevars(info)) - selftype = TypeVarType(tvd) + # TODO: SelfType should be bind to actual 'self' + this_type = fill_typevars(info) def add_method(funcname: str, ret: Type, args: List[Argument], name=None, is_classmethod=False) -> None: - if is_classmethod: - first = [Argument(Var('cls'), TypeType(selftype), None, ARG_POS)] - else: - first = [Argument(Var('self'), selftype, None, ARG_POS)] - args = first + args - + if not is_classmethod: + args = [Argument(Var('self'), this_type, None, ARG_POS)] + args types = [arg.type_annotation for arg in args] items = [arg.variable.name() for arg in args] arg_kinds = [arg.kind for arg in args] signature = CallableType(types, arg_kinds, items, ret, function_type, name=name or info.name() + '.' + funcname) - signature.variables = [tvd] + signature.is_classmethod_class = is_classmethod func = FuncDef(funcname, args, Block([]), typ=signature) func.info = info func.is_class = is_classmethod - if is_classmethod: - v = Var(funcname, signature) - v.is_classmethod = True - v.info = info - dec = Decorator(func, [NameExpr('classmethod')], v) - info.names[funcname] = SymbolTableNode(MDEF, dec) - else: - info.names[funcname] = SymbolTableNode(MDEF, func) + info.names[funcname] = SymbolTableNode(MDEF, func) - add_method('_replace', ret=selftype, + add_method('_replace', ret=this_type, args=[Argument(var, var.type, EllipsisExpr(), ARG_NAMED) for var in vars]) add_method('__init__', ret=NoneTyp(), name=info.name(), args=[Argument(var, var.type, None, ARG_POS) for var in vars]) add_method('_asdict', args=[], ret=ordereddictype) - add_method('_make', ret=selftype, is_classmethod=True, + # FIX: make it actual class method + add_method('_make', ret=this_type, is_classmethod=True, args=[Argument(Var('iterable', iterable_type), iterable_type, None, ARG_POS), Argument(Var('new'), AnyType(), EllipsisExpr(), ARG_NAMED), Argument(Var('len'), AnyType(), EllipsisExpr(), ARG_NAMED)]) diff --git a/test-data/unit/check-class-namedtuple.test b/test-data/unit/check-class-namedtuple.test index de109ab248d5..d5575fcb8649 100644 --- a/test-data/unit/check-class-namedtuple.test +++ b/test-data/unit/check-class-namedtuple.test @@ -283,7 +283,7 @@ class X(NamedTuple): y: str x: X -reveal_type(x._replace()) # E: Revealed type is '__main__.X*' +reveal_type(x._replace()) # E: Revealed type is 'Tuple[builtins.int, builtins.str, fallback=__main__.X]' x._replace(x=5) x._replace(y=5) # E: Argument 1 to X._replace has incompatible type "int"; expected "str" diff --git a/test-data/unit/check-namedtuple.test b/test-data/unit/check-namedtuple.test index c18f360a94ea..c41cc5a916fd 100644 --- a/test-data/unit/check-namedtuple.test +++ b/test-data/unit/check-namedtuple.test @@ -258,7 +258,7 @@ from collections import namedtuple X = namedtuple('X', ['x', 'y']) x = None # type: X -reveal_type(x._replace()) # E: Revealed type is '__main__.X*' +reveal_type(x._replace()) # E: Revealed type is 'Tuple[Any, Any, fallback=__main__.X]' x._replace(y=5) x._replace(x=3) x._replace(x=3, y=5) @@ -279,18 +279,19 @@ from typing import NamedTuple X = NamedTuple('X', [('x', int), ('y', str)]) x = None # type: X -reveal_type(x._replace()) # E: Revealed type is '__main__.X*' +reveal_type(x._replace()) # E: Revealed type is 'Tuple[builtins.int, builtins.str, fallback=__main__.X]' x._replace(x=5) x._replace(y=5) # E: Argument 1 to X._replace has incompatible type "int"; expected "str" + [case testNamedTupleMake] from typing import NamedTuple X = NamedTuple('X', [('x', int), ('y', str)]) -reveal_type(X._make([5, 'a'])) # E: Revealed type is '__main__.X*' +reveal_type(X._make([5, 'a'])) # E: Revealed type is 'Tuple[builtins.int, builtins.str, fallback=__main__.X]' X._make('a b') # E: Argument 1 to X._make has incompatible type "str"; expected Iterable[Any] --- # FIX: not a proper class method +-- # FIX: not a proper class method -- x = None # type: X -- reveal_type(x._make([5, 'a'])) # E: Revealed type is 'Tuple[builtins.int, builtins.str, fallback=__main__.X]' -- x._make('a b') # E: Argument 1 to X._make has incompatible type "str"; expected Iterable[Any]