mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:37 +00:00
[red-knot] don't emit divide-by-zero error if we can't be sure (#13799)
If the LHS is just `int` or `float` type, that type includes custom subclasses which can arbitrarily override division behavior, so we shouldn't emit a divide-by-zero error in those cases. Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
parent
5e6de4e0c6
commit
5c537b6dbb
2 changed files with 13 additions and 5 deletions
|
@ -21,12 +21,23 @@ reveal_type(f) # revealed: Literal[2]
|
||||||
## Division by Zero
|
## Division by Zero
|
||||||
|
|
||||||
```py
|
```py
|
||||||
|
class MyInt(int):
|
||||||
|
def __truediv__(self, other):
|
||||||
|
return 100
|
||||||
|
|
||||||
|
def returns_int() -> int:
|
||||||
|
return MyInt(3)
|
||||||
|
|
||||||
# TODO: `a` should be `int` and `e` should be `float` once we support inference.
|
# TODO: `a` should be `int` and `e` should be `float` once we support inference.
|
||||||
a = 1 / 0 # error: "Cannot divide object of type `Literal[1]` by zero"
|
a = 1 / 0 # error: "Cannot divide object of type `Literal[1]` by zero"
|
||||||
b = 2 // 0 # error: "Cannot floor divide object of type `Literal[2]` by zero"
|
b = 2 // 0 # error: "Cannot floor divide object of type `Literal[2]` by zero"
|
||||||
c = 3 % 0 # error: "Cannot reduce object of type `Literal[3]` modulo zero"
|
c = 3 % 0 # error: "Cannot reduce object of type `Literal[3]` modulo zero"
|
||||||
d = int() / 0 # error: "Cannot divide object of type `int` by zero"
|
# even `int` type could be a subclass of `int` with custom behavior; no error
|
||||||
e = 1.0 / 0 # error: "Cannot divide object of type `float` by zero"
|
d = returns_int() / 0
|
||||||
|
# this could be flagged as an error, if we had an ExactFloat or ExactInstance
|
||||||
|
# type, but given only a `float` type we can't issue an error for the same
|
||||||
|
# reason: could be a custom float subclass
|
||||||
|
e = 1.0 / 0
|
||||||
|
|
||||||
reveal_type(a) # revealed: float
|
reveal_type(a) # revealed: float
|
||||||
reveal_type(b) # revealed: int
|
reveal_type(b) # revealed: int
|
||||||
|
|
|
@ -540,9 +540,6 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||||
fn check_division_by_zero(&mut self, expr: &ast::ExprBinOp, left: Type<'db>) {
|
fn check_division_by_zero(&mut self, expr: &ast::ExprBinOp, left: Type<'db>) {
|
||||||
match left {
|
match left {
|
||||||
Type::IntLiteral(_) => {}
|
Type::IntLiteral(_) => {}
|
||||||
Type::Instance(cls)
|
|
||||||
if cls.is_known(self.db, KnownClass::Float)
|
|
||||||
|| cls.is_known(self.db, KnownClass::Int) => {}
|
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue