mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 05:14:52 +00:00
[ty] Remove incorrect type narrowing for if type(x) is C[int]
(#19926)
This commit is contained in:
parent
f344dda82c
commit
9ced219ffc
2 changed files with 52 additions and 6 deletions
|
@ -70,6 +70,56 @@ def _(x: A | B, y: A | C):
|
|||
reveal_type(y) # revealed: A
|
||||
```
|
||||
|
||||
## No narrowing for `type(x) is C[int]`
|
||||
|
||||
At runtime, `type(x)` will never return a generic alias object (only ever a class-literal object),
|
||||
so no narrowing can occur if `type(x)` is compared with a generic alias object.
|
||||
|
||||
```toml
|
||||
[environment]
|
||||
python-version = "3.12"
|
||||
```
|
||||
|
||||
```py
|
||||
class A[T]: ...
|
||||
class B: ...
|
||||
|
||||
def f(x: A[int] | B):
|
||||
if type(x) is A[int]:
|
||||
# this branch is actually unreachable -- we *could* reveal `Never` here!
|
||||
reveal_type(x) # revealed: A[int] | B
|
||||
else:
|
||||
reveal_type(x) # revealed: A[int] | B
|
||||
|
||||
if type(x) is A:
|
||||
# TODO: this should be `A[int]`, but `A[int] | B` would be better than `Never`
|
||||
reveal_type(x) # revealed: Never
|
||||
else:
|
||||
reveal_type(x) # revealed: A[int] | B
|
||||
|
||||
if type(x) is B:
|
||||
reveal_type(x) # revealed: B
|
||||
else:
|
||||
reveal_type(x) # revealed: A[int] | B
|
||||
|
||||
if type(x) is not A[int]:
|
||||
reveal_type(x) # revealed: A[int] | B
|
||||
else:
|
||||
# this branch is actually unreachable -- we *could* reveal `Never` here!
|
||||
reveal_type(x) # revealed: A[int] | B
|
||||
|
||||
if type(x) is not A:
|
||||
reveal_type(x) # revealed: A[int] | B
|
||||
else:
|
||||
# TODO: this should be `A[int]`, but `A[int] | B` would be better than `Never`
|
||||
reveal_type(x) # revealed: Never
|
||||
|
||||
if type(x) is not B:
|
||||
reveal_type(x) # revealed: A[int] | B
|
||||
else:
|
||||
reveal_type(x) # revealed: B
|
||||
```
|
||||
|
||||
## `type(x) == C`, `type(x) != C`
|
||||
|
||||
No narrowing can occur for equality comparisons, since there might be a custom `__eq__`
|
||||
|
|
|
@ -756,12 +756,8 @@ impl<'db, 'ast> NarrowingConstraintsBuilder<'db, 'ast> {
|
|||
node_index: _,
|
||||
},
|
||||
}) if keywords.is_empty() => {
|
||||
let rhs_class = match rhs_ty {
|
||||
Type::ClassLiteral(class) => class,
|
||||
Type::GenericAlias(alias) => alias.origin(self.db),
|
||||
_ => {
|
||||
continue;
|
||||
}
|
||||
let Type::ClassLiteral(rhs_class) = rhs_ty else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let target = match &**args {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue