Skip to content

Commit fff6c41

Browse files
committed
self type
1 parent 193e605 commit fff6c41

File tree

3 files changed

+22
-15
lines changed

3 files changed

+22
-15
lines changed

mypy/checkmember.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,26 +1081,17 @@ def analyze_class_attribute_access(
10811081
# x: T
10821082
# C.x # Error, ambiguous access
10831083
# C[int].x # Also an error, since C[int] is same as C at runtime
1084-
# Exception is Self type wrapped in ClassVar, that is safe.
1084+
# Exception is Self type, which is always allowed
10851085
def_vars = set(node.node.info.defn.type_vars)
1086-
if not node.node.is_classvar and node.node.info.self_type:
1087-
def_vars.add(node.node.info.self_type)
1088-
1086+
if node.node.info.self_type:
1087+
def_vars.discard(node.node.info.self_type)
10891088
typ_vars = set(get_type_vars(t))
1090-
for tv in def_vars & typ_vars:
1091-
if (
1092-
# Forgive access to variables generic over Self
1093-
isinstance(tv.upper_bound, Instance)
1094-
and super_info
1095-
and tv.upper_bound.type.fullname == super_info.fullname
1096-
):
1097-
continue
1089+
if def_vars & typ_vars:
10981090
if node.node.is_classvar:
10991091
message = message_registry.GENERIC_CLASS_VAR_ACCESS
11001092
else:
11011093
message = message_registry.GENERIC_INSTANCE_VAR_CLASS_ACCESS
11021094
mx.msg.fail(message, mx.context)
1103-
break
11041095

11051096
t = expand_self_type_if_needed(t, mx, node.node, itype, is_class=True)
11061097
# Erase non-mapped variables, but keep mapped ones, even if there is an error.

test-data/unit/check-generics.test

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2234,7 +2234,7 @@ reveal_type(xi) # N: Revealed type is "builtins.int"
22342234
[builtins fixtures/classmethod.pyi]
22352235

22362236
[case testGenericClassAttrSelfType]
2237-
from typing import TypeVar, Generic, Self, Type, Mapping
2237+
from typing import TypeVar, Generic, Self, Type, Mapping, ClassVar
22382238

22392239
class A:
22402240
d: Mapping[str, Self]
@@ -2253,6 +2253,22 @@ def check_B(B_t: Type[B]) -> None:
22532253
reveal_type(B.d) # N: Revealed type is "typing.Mapping[builtins.str, __main__.B]"
22542254
reveal_type(B_t.d) # N: Revealed type is "typing.Mapping[builtins.str, __main__.B]"
22552255

2256+
class AA:
2257+
d: ClassVar[Mapping[str, Self]]
2258+
2259+
@classmethod
2260+
def make(cls) -> Self:
2261+
return cls.d["asdf"]
2262+
2263+
class BB(AA): ...
2264+
2265+
def check_AA(AA_t: Type[AA]) -> None:
2266+
reveal_type(AA.d) # N: Revealed type is "typing.Mapping[builtins.str, __main__.AA]"
2267+
reveal_type(AA_t.d) # N: Revealed type is "typing.Mapping[builtins.str, __main__.AA]"
2268+
2269+
def check_BB(BB_t: Type[BB]) -> None:
2270+
reveal_type(BB.d) # N: Revealed type is "typing.Mapping[builtins.str, __main__.BB]"
2271+
reveal_type(BB_t.d) # N: Revealed type is "typing.Mapping[builtins.str, __main__.BB]"
22562272
[builtins fixtures/classmethod.pyi]
22572273

22582274
[case testGenericClassAttrUnboundOnSubClass]

test-data/unit/check-selftype.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2120,7 +2120,7 @@ c: C
21202120
reveal_type(c.x) # N: Revealed type is "Tuple[builtins.int, builtins.str, fallback=__main__.C]"
21212121
reveal_type(c.y) # N: Revealed type is "Tuple[builtins.int, builtins.str, fallback=__main__.C]"
21222122
reveal_type(C.y) # N: Revealed type is "Tuple[builtins.int, builtins.str, fallback=__main__.C]"
2123-
C.x # E: Access to generic instance variables via class is ambiguous
2123+
C.x
21242124
[builtins fixtures/classmethod.pyi]
21252125

21262126
[case testAccessingTypingSelfUnion]

0 commit comments

Comments
 (0)