-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[red-knot] Report classes inheriting from bases with incompatible `__…
…slots__`
- Loading branch information
1 parent
5bc9d6d
commit 0171985
Showing
4 changed files
with
356 additions
and
37 deletions.
There are no files selected for viewing
174 changes: 174 additions & 0 deletions
174
crates/red_knot_python_semantic/resources/mdtest/slots.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
# `__slots__` | ||
|
||
## Not specified and empty | ||
|
||
```py | ||
class A: ... | ||
|
||
class B: | ||
__slots__ = () | ||
|
||
class C: | ||
__slots__ = ("lorem", "ipsum") | ||
|
||
class AB(A, B): ... # fine | ||
class AC(A, C): ... # fine | ||
class BC(B, C): ... # fine | ||
|
||
class ABC(A, B, C): ... # fine | ||
``` | ||
|
||
## Incompatible tuples | ||
|
||
```py | ||
class A: | ||
__slots__ = ("a", "b") | ||
|
||
class B: | ||
__slots__ = ("c", "d") | ||
|
||
class C( | ||
A, # error: [incompatible-slots] | ||
B, # error: [incompatible-slots] | ||
): ... | ||
``` | ||
|
||
## Same value | ||
|
||
```py | ||
class A: | ||
__slots__ = ("a", "b") | ||
|
||
class B: | ||
__slots__ = ("a", "b") | ||
|
||
class C( | ||
A, # error: [incompatible-slots] | ||
B, # error: [incompatible-slots] | ||
): ... | ||
``` | ||
|
||
## Strings | ||
|
||
```py | ||
class A: | ||
__slots__ = "abc" | ||
|
||
class B: | ||
__slots__ = ("abc") | ||
|
||
class AB( | ||
A, # error: [incompatible-slots] | ||
B, # error: [incompatible-slots] | ||
): ... | ||
``` | ||
|
||
## Invalid | ||
|
||
TODO: Emit diagnostics | ||
|
||
```py | ||
class NonString1: | ||
__slots__ = 42 | ||
|
||
class NonString2: | ||
__slots__ = b"ar" | ||
|
||
class NonIdentifier1: | ||
__slots__ = "42" | ||
|
||
class NonIdentifier2: | ||
__slots__ = ("lorem", "42") | ||
|
||
class NonIdentifier3: | ||
__slots__ = (e for e in ("lorem", "42")) | ||
``` | ||
|
||
## Inheritance | ||
|
||
```py | ||
class A: | ||
__slots__ = ("a", "b") | ||
|
||
class B(A): ... | ||
|
||
class C: | ||
__slots__ = ("c", "d") | ||
|
||
class D(C): ... | ||
|
||
class E( | ||
B, # error: [incompatible-slots] | ||
D, # error: [incompatible-slots] | ||
): ... | ||
``` | ||
|
||
## False negatives | ||
|
||
### Possibly unbound | ||
|
||
```py | ||
def _(flag: bool): | ||
class A: | ||
if flag: | ||
__slots__ = ("a", "b") | ||
|
||
class B: | ||
__slots__ = ("c", "d") | ||
|
||
# Might or might not be fine at runtime | ||
class C(A, B): ... | ||
``` | ||
|
||
### Bound but with different types | ||
|
||
```py | ||
def _(flag: bool): | ||
class A: | ||
if flag: | ||
__slots__ = ("a", "b") | ||
else: | ||
__slots__ = () | ||
|
||
class B: | ||
__slots__ = ("c", "d") | ||
|
||
# Might or might not be fine at runtime | ||
class C(A, B): ... | ||
``` | ||
|
||
### Non-tuples | ||
|
||
```py | ||
class A: | ||
__slots__ = ["a", "b"] # This is treated as "dynamic" | ||
|
||
class B: | ||
__slots__ = ("c", "d") | ||
|
||
# False negative: [incompatible-slots] | ||
class C(A, B): ... | ||
``` | ||
|
||
### Post-hoc modifications | ||
|
||
```py | ||
class A: | ||
__slots__ = () | ||
__slots__ += ("a", "b") | ||
|
||
reveal_type(A.__slots__) # revealed: @Todo(Support for more binary expressions) | ||
|
||
class B: | ||
__slots__ = ("c", "d") | ||
|
||
# False negative: [incompatible-slots] | ||
class C(A, B): ... | ||
``` | ||
|
||
### Built-ins with implicit layouts | ||
|
||
```py | ||
# False negative: [incompatible-slots] | ||
class A(int, str): ... | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.