diff --git a/mypy/checker.py b/mypy/checker.py index cd0e338eab40..dad9ab7d9714 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -5689,7 +5689,7 @@ def _format_expr_type(self, t: Type, expr: Expression) -> str: else: return f"Expression has type {typ}" - def check_for_truthy_type(self, t: Type, expr: Expression) -> None: + def _check_for_truthy_type(self, t: Type, expr: Expression) -> None: """ Check if a type can have a truthy value. @@ -5731,7 +5731,7 @@ def get_expr_name() -> str: else: self.fail(message_registry.TYPE_ALWAYS_TRUE.format(format_expr_type()), expr) - def check_for_optional_non_truthy_type(self, t: Type, expr: Expression) -> None: + def _check_for_optional_non_truthy_type(self, t: Type, expr: Expression) -> None: """Check if a type involves both None and types that aren't always true, catching suspicious cases of falsy values being lumped together with None. @@ -5766,6 +5766,21 @@ def check_for_optional_non_truthy_type(self, t: Type, expr: Expression) -> None: expr, ) + def check_for_appropriate_truthiness_in_boolean_context( + self, t: Type, expr: Expression + ) -> None: + """Check if a type is truthy or potentially-falsy when it shouldn't be. + + Used in checks like:: + + if x: # <--- + + not x # <--- + + """ + self._check_for_truthy_type(t, expr) + self._check_for_optional_non_truthy_type(t, expr) + def find_type_equals_check( self, node: ComparisonExpr, expr_indices: list[int] ) -> tuple[TypeMap, TypeMap]: @@ -6212,9 +6227,7 @@ def has_no_custom_eq_checks(t: Type) -> bool: if in_boolean_context: # We don't check `:=` values in expressions like `(a := A())`, # because they produce two error messages. - # FIXME: make this a single call again - self.check_for_truthy_type(original_vartype, node) - self.check_for_optional_non_truthy_type(original_vartype, node) + self.check_for_appropriate_truthiness_in_boolean_context(original_vartype, node) vartype = try_expanding_sum_type_to_union(original_vartype, "builtins.bool") if_type = true_only(vartype) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index f50bd4130fa1..777ee9917d74 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -4296,9 +4296,7 @@ def visit_unary_expr(self, e: UnaryExpr) -> Type: op = e.op if op == "not": result: Type = self.bool_type() - # FIXME: make this a single call again - self.chk.check_for_truthy_type(operand_type, e.expr) - self.chk.check_for_optional_non_truthy_type(operand_type, e.expr) + self.chk.check_for_appropriate_truthiness_in_boolean_context(operand_type, e.expr) else: method = operators.unary_op_methods[op] result, method_type = self.check_method_call_by_name(method, operand_type, [], [], e)