Skip to content

Commit

Permalink
[red-knot] Add MRO resolution for classes (#14027)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexWaygood authored Nov 4, 2024
1 parent 88d9bb1 commit df45a0e
Show file tree
Hide file tree
Showing 13 changed files with 1,171 additions and 120 deletions.
7 changes: 4 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ hashbrown = { version = "0.15.0", default-features = false, features = [
ignore = { version = "0.4.22" }
imara-diff = { version = "0.1.5" }
imperative = { version = "1.0.4" }
indexmap = {version = "2.6.0" }
indicatif = { version = "0.17.8" }
indoc = { version = "2.0.4" }
insta = { version = "1.35.1" }
Expand Down
6 changes: 3 additions & 3 deletions crates/red_knot_python_semantic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ bitflags = { workspace = true }
camino = { workspace = true }
compact_str = { workspace = true }
countme = { workspace = true }
itertools = { workspace = true}
indexmap = { workspace = true }
itertools = { workspace = true }
ordermap = { workspace = true }
salsa = { workspace = true }
thiserror = { workspace = true }
Expand All @@ -43,10 +44,9 @@ red_knot_test = { workspace = true }
red_knot_vendored = { workspace = true }

anyhow = { workspace = true }
dir-test = {workspace = true}
dir-test = { workspace = true }
insta = { workspace = true }
tempfile = { workspace = true }

[lints]
workspace = true

Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ f = Foo()
# that `Foo.__iadd__` may be unbound as additional context.
f += "Hello, world!"

reveal_type(f) # revealed: int | @Todo
reveal_type(f) # revealed: int | Unknown
```

## Partially bound with `__add__`
Expand Down
35 changes: 35 additions & 0 deletions crates/red_knot_python_semantic/resources/mdtest/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,38 @@ else:

reveal_type(C.x) # revealed: Literal[1, 2]
```

## 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]
```
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,7 @@ reveal_type(A() + B()) # revealed: MyString
# N.B. Still a subtype of `A`, even though `A` does not appear directly in the class's `__bases__`
class C(B): ...

# TODO: we currently only understand direct subclasses as subtypes of the superclass.
# We need to iterate through the full MRO rather than just the class's bases;
# if we do, we'll understand `C` as a subtype of `A`, and correctly understand this as being
# `MyString` rather than `str`
reveal_type(A() + C()) # revealed: str
reveal_type(A() + C()) # revealed: MyString
```

## Reflected precedence 2
Expand Down
Loading

0 comments on commit df45a0e

Please sign in to comment.