8000 Make it an error to use a class-attribute type var outside a type (#3… · python/mypy@61cdbf3 · GitHub
[go: up one dir, main page]

Skip to content

Commit 61cdbf3

Browse files
sixoletJukkaL
authored andcommitted
Make it an error to use a class-attribute type var outside a type (#3105)
Previously, e9d28a0 fixed a crash when you tried to access a class-attribute type variable. The test in that commit involved assigning a variable the value of the typevar. It resulted in no crash, but rather treating the variable as being an instance of the type the typevar bound to, later, which is incorrect. Instead, this PR treats such an assignment as an error, and gives you the same message as when you try to alias a typevar directly. Also test a *correct* alias with the typevar access method in question -- it works.
1 parent 3dd0210 commit 61cdbf3

File tree

3 files changed

+17
-4
lines changed

3 files changed

+17
-4
lines changed

mypy/checkmember.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,9 @@ def analyze_class_attribute_access(itype: Instance,
406406
return AnyType()
407407

408408
if isinstance(node.node, TypeVarExpr):
409-
return TypeVarType(node.tvar_def, node.tvar_def.line, node.tvar_def.column)
409+
msg.fail('Type variable "{}.{}" cannot be used as an expression'.format(
410+
itype.type.name(), name), context)
411+
return AnyType()
410412

411413
if isinstance(node.node, TypeInfo):
412414
return type_object_type(node.node, builtin_type)

mypy/typeanal.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ def analyze_type_alias(node: Expression,
4343
# that we don't support straight string literals as type aliases
4444
# (only string literals within index expressions).
4545
if isinstance(node, RefExpr):
46+
# Note that this misses the case where someone tried to use a
47+
# class-referenced type variable as a type alias. It's easier to catch
48+
# that one in checkmember.py
4649
if node.kind == UNBOUND_TVAR or node.kind == BOUND_TVAR:
4750
fail_func('Type variable "{}" is invalid as target for type alias'.format(
4851
node.fullname), node)

test-data/unit/check-typevar-values.test

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -496,12 +496,20 @@ def outer(x: T) -> T:
496496
[out]
497497

498498
[case testClassMemberTypeVarInFunctionBody]
499-
from typing import TypeVar
499+
from typing import TypeVar, List
500500
class C:
501501
T = TypeVar('T', bound=int)
502502
def f(self, x: T) -> T:
503-
A = C.T
504-
return x
503+
L = List[C.T] # a valid type alias
504+
l: L = []
505+
reveal_type(l) # E: Revealed type is 'builtins.list[T`-1]'
506+
y: C.T = x
507+
l.append(x)
508+
C.T # E: Type variable "C.T" cannot be used as an expression
509+
A = C.T # E: Type variable "C.T" cannot be used as an expression
510+
return l[0]
511+
512+
[builtins fixtures/list.pyi]
505513

506514
[case testParameterLessGenericAsRestriction]
507515
from typing import Sequence, Iterable, TypeVar

0 commit comments

Comments
 (0)
0