@@ -808,7 +808,7 @@ def _(flag1: bool, flag2: bool):
808808 reveal_type(C5.attr1) # revealed: Unknown | Literal["metaclass value", "class value"]
809809```
810810
811- ## Union of attributes
811+ ## Unions of attributes
812812
813813If the (meta)class is a union type or if the attribute on the (meta) class has a union type, we
814814infer those union types accordingly:
@@ -854,43 +854,6 @@ def _(flag: bool):
854854 reveal_type(C4.x) # revealed: Unknown | Literal[7, 8]
855855```
856856
857- ## Inherited class attributes
858-
859- ### Basic
860-
861- ``` py
862- class A :
863- X = " foo"
864-
865- class B (A ): ...
866- class C (B ): ...
867-
868- reveal_type(C.X) # revealed: Unknown | Literal["foo"]
869- ```
870-
871- ### Multiple inheritance
872-
873- ``` py
874- class O : ...
875-
876- class F (O ):
877- X = 56
878-
879- class E (O ):
880- X = 42
881-
882- class D (O ): ...
883- class C (D , F ): ...
884- class B (E , D ): ...
885- class A (B , C ): ...
886-
887- # revealed: tuple[Literal[A], Literal[B], Literal[E], Literal[C], Literal[D], Literal[F], Literal[O], Literal[object]]
888- reveal_type(A.__mro__ )
889-
890- # `E` is earlier in the MRO than `F`, so we should use the type of `E.X`
891- reveal_type(A.X) # revealed: Unknown | Literal[42]
892- ```
893-
894857## Unions with possibly unbound paths
895858
896859### Definite boundness within a class
@@ -1028,7 +991,58 @@ def _(flag: bool):
1028991 reveal_type(Foo().x) # revealed: Unknown | Literal[1]
1029992```
1030993
1031- ### Attribute access on ` Any `
994+ ### Unions with all paths unbound
995+
996+ If the symbol is unbound in all elements of the union, we detect that:
997+
998+ ``` py
999+ def _ (flag : bool ):
1000+ class C1 : ...
1001+ class C2 : ...
1002+ C = C1 if flag else C2
1003+
1004+ # error: [unresolved-attribute] "Type `Literal[C1, C2]` has no attribute `x`"
1005+ reveal_type(C.x) # revealed: Unknown
1006+ ```
1007+
1008+ ## Inherited class attributes
1009+
1010+ ### Basic
1011+
1012+ ``` py
1013+ class A :
1014+ X = " foo"
1015+
1016+ class B (A ): ...
1017+ class C (B ): ...
1018+
1019+ reveal_type(C.X) # revealed: Unknown | Literal["foo"]
1020+ ```
1021+
1022+ ### Multiple inheritance
1023+
1024+ ``` py
1025+ class O : ...
1026+
1027+ class F (O ):
1028+ X = 56
1029+
1030+ class E (O ):
1031+ X = 42
1032+
1033+ class D (O ): ...
1034+ class C (D , F ): ...
1035+ class B (E , D ): ...
1036+ class A (B , C ): ...
1037+
1038+ # revealed: tuple[Literal[A], Literal[B], Literal[E], Literal[C], Literal[D], Literal[F], Literal[O], Literal[object]]
1039+ reveal_type(A.__mro__ )
1040+
1041+ # `E` is earlier in the MRO than `F`, so we should use the type of `E.X`
1042+ reveal_type(A.X) # revealed: Unknown | Literal[42]
1043+ ```
1044+
1045+ ## Attribute access on ` Any `
10321046
10331047The union of the set of types that ` Any ` could materialise to is equivalent to ` object ` . It follows
10341048from this that attribute access on ` Any ` resolves to ` Any ` if the attribute does not exist on
@@ -1059,20 +1073,6 @@ reveal_type(C.__mro__) # revealed: tuple[Literal[C], Literal[B], Any, Literal[A
10591073reveal_type(C.x) # revealed: Literal[1] & Any
10601074```
10611075
1062- ### Unions with all paths unbound
1063-
1064- If the symbol is unbound in all elements of the union, we detect that:
1065-
1066- ``` py
1067- def _ (flag : bool ):
1068- class C1 : ...
1069- class C2 : ...
1070- C = C1 if flag else C2
1071-
1072- # error: [unresolved-attribute] "Type `Literal[C1, C2]` has no attribute `x`"
1073- reveal_type(C.x) # revealed: Unknown
1074- ```
1075-
10761076## Objects of all types have a ` __class__ ` method
10771077
10781078The type of ` x.__class__ ` is the same as ` x ` 's meta-type. ` x.__class__ ` is always the same value as
@@ -1125,6 +1125,8 @@ reveal_type(Foo.__class__) # revealed: Literal[type]
11251125
11261126## Module attributes
11271127
1128+ ### Basic
1129+
11281130` mod.py ` :
11291131
11301132``` py
@@ -1159,7 +1161,7 @@ for mod.global_symbol in IntIterable():
11591161 pass
11601162```
11611163
1162- ## Nested attributes
1164+ ### Nested module attributes
11631165
11641166` outer/__init__.py ` :
11651167
0 commit comments