mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:16 +00:00
[ty] fix binary expression inference between boolean literals and bool
instances (#18663)
This commit is contained in:
parent
87f0feb21a
commit
932f941d15
2 changed files with 80 additions and 16 deletions
|
@ -103,3 +103,65 @@ def _(a: bool):
|
||||||
reveal_type(x / y) # revealed: int | float
|
reveal_type(x / y) # revealed: int | float
|
||||||
reveal_type(x % y) # revealed: int
|
reveal_type(x % y) # revealed: int
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Bitwise operations with a variable
|
||||||
|
|
||||||
|
```py
|
||||||
|
import random
|
||||||
|
|
||||||
|
def _(a: bool):
|
||||||
|
def lhs_is_int(x: int):
|
||||||
|
reveal_type(x | a) # revealed: int
|
||||||
|
reveal_type(x & a) # revealed: int
|
||||||
|
reveal_type(x ^ a) # revealed: int
|
||||||
|
|
||||||
|
def rhs_is_int(x: int):
|
||||||
|
reveal_type(a | x) # revealed: int
|
||||||
|
reveal_type(a & x) # revealed: int
|
||||||
|
reveal_type(a ^ x) # revealed: int
|
||||||
|
|
||||||
|
def lhs_is_int_literal():
|
||||||
|
reveal_type(0 | a) # revealed: int
|
||||||
|
reveal_type(0 & a) # revealed: int
|
||||||
|
reveal_type(0 ^ a) # revealed: int
|
||||||
|
|
||||||
|
reveal_type(1 | a) # revealed: int
|
||||||
|
reveal_type(1 & a) # revealed: int
|
||||||
|
reveal_type(1 ^ a) # revealed: int
|
||||||
|
|
||||||
|
def lhs_is_true():
|
||||||
|
reveal_type(True | a) # revealed: bool
|
||||||
|
reveal_type(True & a) # revealed: bool
|
||||||
|
reveal_type(True ^ a) # revealed: bool
|
||||||
|
|
||||||
|
def rhs_is_true():
|
||||||
|
reveal_type(a | True) # revealed: bool
|
||||||
|
reveal_type(a & True) # revealed: bool
|
||||||
|
reveal_type(a ^ True) # revealed: bool
|
||||||
|
|
||||||
|
def lhs_is_false():
|
||||||
|
reveal_type(False | a) # revealed: bool
|
||||||
|
reveal_type(False & a) # revealed: bool
|
||||||
|
reveal_type(False ^ a) # revealed: bool
|
||||||
|
|
||||||
|
def rhs_is_false():
|
||||||
|
reveal_type(a | False) # revealed: bool
|
||||||
|
reveal_type(a & False) # revealed: bool
|
||||||
|
reveal_type(a ^ False) # revealed: bool
|
||||||
|
|
||||||
|
def both_are_bool(x: bool, y: bool):
|
||||||
|
reveal_type(x | y) # revealed: bool
|
||||||
|
reveal_type(x & y) # revealed: bool
|
||||||
|
reveal_type(x ^ y) # revealed: bool
|
||||||
|
|
||||||
|
def lhs_is_int_literal_rhs_is_bool_literal():
|
||||||
|
reveal_type(0 & True) # revealed: Literal[0]
|
||||||
|
reveal_type(0 | True) # revealed: Literal[1]
|
||||||
|
reveal_type(3 & True) # revealed: Literal[1]
|
||||||
|
reveal_type(3 | True) # revealed: Literal[3]
|
||||||
|
|
||||||
|
reveal_type(0 & False) # revealed: Literal[0]
|
||||||
|
reveal_type(0 | False) # revealed: Literal[0]
|
||||||
|
reveal_type(3 & False) # revealed: Literal[0]
|
||||||
|
reveal_type(3 | False) # revealed: Literal[3]
|
||||||
|
```
|
||||||
|
|
|
@ -6893,22 +6893,22 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||||
(Type::BooleanLiteral(b1), Type::BooleanLiteral(b2), ast::Operator::BitXor) => {
|
(Type::BooleanLiteral(b1), Type::BooleanLiteral(b2), ast::Operator::BitXor) => {
|
||||||
Some(Type::BooleanLiteral(b1 ^ b2))
|
Some(Type::BooleanLiteral(b1 ^ b2))
|
||||||
}
|
}
|
||||||
|
(Type::BooleanLiteral(b1), Type::BooleanLiteral(_) | Type::IntLiteral(_), op) => self
|
||||||
(Type::BooleanLiteral(bool_value), right, op) => self.infer_binary_expression_type(
|
.infer_binary_expression_type(
|
||||||
node,
|
node,
|
||||||
emitted_division_by_zero_diagnostic,
|
emitted_division_by_zero_diagnostic,
|
||||||
Type::IntLiteral(i64::from(bool_value)),
|
Type::IntLiteral(i64::from(b1)),
|
||||||
right,
|
right_ty,
|
||||||
op,
|
op,
|
||||||
),
|
),
|
||||||
(left, Type::BooleanLiteral(bool_value), op) => self.infer_binary_expression_type(
|
(Type::IntLiteral(_), Type::BooleanLiteral(b2), op) => self
|
||||||
|
.infer_binary_expression_type(
|
||||||
node,
|
node,
|
||||||
emitted_division_by_zero_diagnostic,
|
emitted_division_by_zero_diagnostic,
|
||||||
left,
|
left_ty,
|
||||||
Type::IntLiteral(i64::from(bool_value)),
|
Type::IntLiteral(i64::from(b2)),
|
||||||
op,
|
op,
|
||||||
),
|
),
|
||||||
|
|
||||||
(Type::Tuple(lhs), Type::Tuple(rhs), ast::Operator::Add) => {
|
(Type::Tuple(lhs), Type::Tuple(rhs), ast::Operator::Add) => {
|
||||||
// Note: this only works on heterogeneous tuples.
|
// Note: this only works on heterogeneous tuples.
|
||||||
let lhs_elements = lhs.elements(self.db());
|
let lhs_elements = lhs.elements(self.db());
|
||||||
|
@ -6927,6 +6927,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||||
// fall back on looking for dunder methods on one of the operand types.
|
// fall back on looking for dunder methods on one of the operand types.
|
||||||
(
|
(
|
||||||
Type::FunctionLiteral(_)
|
Type::FunctionLiteral(_)
|
||||||
|
| Type::BooleanLiteral(_)
|
||||||
| Type::Callable(..)
|
| Type::Callable(..)
|
||||||
| Type::BoundMethod(_)
|
| Type::BoundMethod(_)
|
||||||
| Type::WrapperDescriptor(_)
|
| Type::WrapperDescriptor(_)
|
||||||
|
@ -6954,6 +6955,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||||
| Type::TypeVar(_)
|
| Type::TypeVar(_)
|
||||||
| Type::TypeIs(_),
|
| Type::TypeIs(_),
|
||||||
Type::FunctionLiteral(_)
|
Type::FunctionLiteral(_)
|
||||||
|
| Type::BooleanLiteral(_)
|
||||||
| Type::Callable(..)
|
| Type::Callable(..)
|
||||||
| Type::BoundMethod(_)
|
| Type::BoundMethod(_)
|
||||||
| Type::WrapperDescriptor(_)
|
| Type::WrapperDescriptor(_)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue