mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 18:58:04 +00:00
[red-knot] Document limitations of diagnostics-silencing in unreachable code (#17387)
## Summary Document the limitations of our current approach to silencing only a subset of diagnostics in unreachable sections.
This commit is contained in:
parent
dfd8eaeb32
commit
850360a0b4
1 changed files with 76 additions and 0 deletions
|
@ -474,3 +474,79 @@ def f():
|
|||
|
||||
1 / 0 # error: [division-by-zero]
|
||||
```
|
||||
|
||||
## Limitations of the current approach
|
||||
|
||||
The current approach of silencing only a subset of diagnostics in unreachable code leads to some
|
||||
problems, and we may want to re-evaluate this decision in the future. To illustrate, consider the
|
||||
following example:
|
||||
|
||||
```py
|
||||
if False:
|
||||
x: int = 1
|
||||
else:
|
||||
x: str = "a"
|
||||
|
||||
if False:
|
||||
# TODO We currently emit a false positive here:
|
||||
# error: [invalid-assignment] "Object of type `Literal["a"]` is not assignable to `int`"
|
||||
other: int = x
|
||||
else:
|
||||
other: str = x
|
||||
```
|
||||
|
||||
The problem here originates from the fact that the type of `x` in the `False` branch conflicts with
|
||||
the visible type of `x` in the `True` branch. When we type-check the lower `False` branch, we only
|
||||
see the visible definition of `x`, which has a type of `str`.
|
||||
|
||||
In principle, this means that all diagnostics that depend on type information from "outside" the
|
||||
unreachable section should be silenced. Similar problems to the one above can occur for other rule
|
||||
types as well:
|
||||
|
||||
```py
|
||||
from typing import Literal
|
||||
|
||||
if False:
|
||||
def f(x: int): ...
|
||||
def g(*, a: int, b: int): ...
|
||||
|
||||
class C:
|
||||
x: int = 1
|
||||
|
||||
class D:
|
||||
def __call__(self):
|
||||
pass
|
||||
|
||||
number: Literal[1] = 1
|
||||
else:
|
||||
def f(x: str): ...
|
||||
def g(*, a: int): ...
|
||||
|
||||
class C:
|
||||
x: str = "a"
|
||||
|
||||
class D: ...
|
||||
number: Literal[0] = 0
|
||||
|
||||
if False:
|
||||
# TODO
|
||||
# error: [invalid-argument-type]
|
||||
f(2)
|
||||
|
||||
# TODO
|
||||
# error: [unknown-argument]
|
||||
g(a=2, b=3)
|
||||
|
||||
# TODO
|
||||
# error: [invalid-assignment]
|
||||
C.x = 2
|
||||
|
||||
d: D = D()
|
||||
# TODO
|
||||
# error: [call-non-callable]
|
||||
d()
|
||||
|
||||
# TODO
|
||||
# error: [division-by-zero]
|
||||
1 / number
|
||||
```
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue