# Class attributes

## Union of attributes

```py
def bool_instance() -> bool:
    return True

flag = bool_instance()

if flag:
    class C1:
        x = 1

else:
    class C1:
        x = 2

class C2:
    if flag:
        x = 3
    else:
        x = 4

reveal_type(C1.x)  # revealed: Literal[1, 2]
reveal_type(C2.x)  # revealed: Literal[3, 4]
```

## Inherited attributes

```py
class A:
    X = "foo"

class B(A): ...
class C(B): ...

reveal_type(C.X)  # revealed: Literal["foo"]
```

## Inherited attributes (multiple inheritance)

```py
class O: ...

class F(O):
    X = 56

class E(O):
    X = 42

class D(O): ...
class C(D, F): ...
class B(E, D): ...
class A(B, C): ...

# revealed: tuple[Literal[A], Literal[B], Literal[E], Literal[C], Literal[D], Literal[F], Literal[O], Literal[object]]
reveal_type(A.__mro__)

# `E` is earlier in the MRO than `F`, so we should use the type of `E.X`
reveal_type(A.X)  # revealed: Literal[42]
```

## Unions with possibly unbound paths

### Definite boundness within a class

In this example, the `x` attribute is not defined in the `C2` element of the union:

```py
def bool_instance() -> bool:
    return True

class C1:
    x = 1

class C2: ...

class C3:
    x = 3

flag1 = bool_instance()
flag2 = bool_instance()

C = C1 if flag1 else C2 if flag2 else C3

# error: [possibly-unbound-attribute] "Attribute `x` on type `Literal[C1, C2, C3]` is possibly unbound"
reveal_type(C.x)  # revealed: Literal[1, 3]
```

### Possibly-unbound within a class

We raise the same diagnostic if the attribute is possibly-unbound in at least one element of the
union:

```py
def bool_instance() -> bool:
    return True

class C1:
    x = 1

class C2:
    if bool_instance():
        x = 2

class C3:
    x = 3

flag1 = bool_instance()
flag2 = bool_instance()

C = C1 if flag1 else C2 if flag2 else C3

# error: [possibly-unbound-attribute] "Attribute `x` on type `Literal[C1, C2, C3]` is possibly unbound"
reveal_type(C.x)  # revealed: Literal[1, 2, 3]
```

## Unions with all paths unbound

If the symbol is unbound in all elements of the union, we detect that:

```py
def bool_instance() -> bool:
    return True

class C1: ...
class C2: ...

flag = bool_instance()

C = C1 if flag else C2

# error: [unresolved-attribute] "Type `Literal[C1, C2]` has no attribute `x`"
reveal_type(C.x)  # revealed: Unknown
```
