Skip to content

Commit 4f7dbfc

Browse files
authored
Revert "selftype in namedtuple methods" (#2414)
Reverts #2408 This appears to have a bug; see my comment to the PR for an explanation.
1 parent bf9cb22 commit 4f7dbfc

File tree

3 files changed

+16
-25
lines changed

3 files changed

+16
-25
lines changed

mypy/semanal.py

+10-20
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
from mypy.errors import Errors, report_internal_error
7272
from mypy.types import (
7373
NoneTyp, CallableType, Overloaded, Instance, Type, TypeVarType, AnyType,
74-
FunctionLike, UnboundType, TypeList, TypeVarDef, TypeType,
74+
FunctionLike, UnboundType, TypeList, TypeVarDef,
7575
TupleType, UnionType, StarType, EllipsisType, function_type)
7676
from mypy.nodes import implicit_module_attrs
7777
from mypy.typeanal import TypeAnalyser, TypeAnalyserPass3, analyze_type_alias
@@ -1803,41 +1803,31 @@ def add_field(var: Var, is_initialized_in_class: bool = False,
18031803
add_field(Var('_field_types', dictype), is_initialized_in_class=True)
18041804
add_field(Var('_source', strtype), is_initialized_in_class=True)
18051805

1806-
tvd = TypeVarDef('NT', 1, [], fill_typevars(info))
1807-
selftype = TypeVarType(tvd)
1806+
# TODO: SelfType should be bind to actual 'self'
1807+
this_type = fill_typevars(info)
18081808

18091809
def add_method(funcname: str, ret: Type, args: List[Argument], name=None,
18101810
is_classmethod=False) -> None:
1811-
if is_classmethod:
1812-
first = [Argument(Var('cls'), TypeType(selftype), None, ARG_POS)]
1813-
else:
1814-
first = [Argument(Var('self'), selftype, None, ARG_POS)]
1815-
args = first + args
1816-
1811+
if not is_classmethod:
1812+
args = [Argument(Var('self'), this_type, None, ARG_POS)] + args
18171813
types = [arg.type_annotation for arg in args]
18181814
items = [arg.variable.name() for arg in args]
18191815
arg_kinds = [arg.kind for arg in args]
18201816
signature = CallableType(types, arg_kinds, items, ret, function_type,
18211817
name=name or info.name() + '.' + funcname)
1822-
signature.variables = [tvd]
1818+
signature.is_classmethod_class = is_classmethod
18231819
func = FuncDef(funcname, args, Block([]), typ=signature)
18241820
func.info = info
18251821
func.is_class = is_classmethod
1826-
if is_classmethod:
1827-
v = Var(funcname, signature)
1828-
v.is_classmethod = True
1829-
v.info = info
1830-
dec = Decorator(func, [NameExpr('classmethod')], v)
1831-
info.names[funcname] = SymbolTableNode(MDEF, dec)
1832-
else:
1833-
info.names[funcname] = SymbolTableNode(MDEF, func)
1822+
info.names[funcname] = SymbolTableNode(MDEF, func)
18341823

1835-
add_method('_replace', ret=selftype,
1824+
add_method('_replace', ret=this_type,
18361825
args=[Argument(var, var.type, EllipsisExpr(), ARG_NAMED) for var in vars])
18371826
add_method('__init__', ret=NoneTyp(), name=info.name(),
18381827
args=[Argument(var, var.type, None, ARG_POS) for var in vars])
18391828
add_method('_asdict', args=[], ret=ordereddictype)
1840-
add_method('_make', ret=selftype, is_classmethod=True,
1829+
# FIX: make it actual class method
1830+
add_method('_make', ret=this_type, is_classmethod=True,
18411831
args=[Argument(Var('iterable', iterable_type), iterable_type, None, ARG_POS),
18421832
Argument(Var('new'), AnyType(), EllipsisExpr(), ARG_NAMED),
18431833
Argument(Var('len'), AnyType(), EllipsisExpr(), ARG_NAMED)])

test-data/unit/check-class-namedtuple.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ class X(NamedTuple):
283283
y: str
284284

285285
x: X
286-
reveal_type(x._replace()) # E: Revealed type is '__main__.X*'
286+
reveal_type(x._replace()) # E: Revealed type is 'Tuple[builtins.int, builtins.str, fallback=__main__.X]'
287287
x._replace(x=5)
288288
x._replace(y=5) # E: Argument 1 to X._replace has incompatible type "int"; expected "str"
289289

test-data/unit/check-namedtuple.test

+5-4
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ from collections import namedtuple
258258

259259
X = namedtuple('X', ['x', 'y'])
260260
x = None # type: X
261-
reveal_type(x._replace()) # E: Revealed type is '__main__.X*'
261+
reveal_type(x._replace()) # E: Revealed type is 'Tuple[Any, Any, fallback=__main__.X]'
262262
x._replace(y=5)
263263
x._replace(x=3)
264264
x._replace(x=3, y=5)
@@ -279,18 +279,19 @@ from typing import NamedTuple
279279

280280
X = NamedTuple('X', [('x', int), ('y', str)])
281281
x = None # type: X
282-
reveal_type(x._replace()) # E: Revealed type is '__main__.X*'
282+
reveal_type(x._replace()) # E: Revealed type is 'Tuple[builtins.int, builtins.str, fallback=__main__.X]'
283283
x._replace(x=5)
284284
x._replace(y=5) # E: Argument 1 to X._replace has incompatible type "int"; expected "str"
285285

286+
286287
[case testNamedTupleMake]
287288
from typing import NamedTuple
288289

289290
X = NamedTuple('X', [('x', int), ('y', str)])
290-
reveal_type(X._make([5, 'a'])) # E: Revealed type is '__main__.X*'
291+
reveal_type(X._make([5, 'a'])) # E: Revealed type is 'Tuple[builtins.int, builtins.str, fallback=__main__.X]'
291292
X._make('a b') # E: Argument 1 to X._make has incompatible type "str"; expected Iterable[Any]
292293

293-
-- # FIX: not a proper class method
294+
-- # FIX: not a proper class method
294295
-- x = None # type: X
295296
-- reveal_type(x._make([5, 'a'])) # E: Revealed type is 'Tuple[builtins.int, builtins.str, fallback=__main__.X]'
296297
-- x._make('a b') # E: Argument 1 to X._make has incompatible type "str"; expected Iterable[Any]

0 commit comments

Comments
 (0)