diff --git a/mypy/checker.py b/mypy/checker.py index 6d70dcb90e94..39b7711eea73 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -6543,10 +6543,6 @@ def comparison_type_narrowing_helper(self, node: ComparisonExpr) -> tuple[TypeMa if ( literal(expr) == LITERAL_TYPE - and not is_literal_none(expr) - and not is_literal_not_implemented(expr) - and not is_false_literal(expr) - and not is_true_literal(expr) and not self.is_literal_enum(expr) and not ( isinstance(p_expr := get_proper_type(expr_type), CallableType) diff --git a/mypy/literals.py b/mypy/literals.py index 50720da35548..0d86b2c238ba 100644 --- a/mypy/literals.py +++ b/mypy/literals.py @@ -35,6 +35,7 @@ OpExpr, ParamSpecExpr, PromoteExpr, + RefExpr, RevealExpr, SetComprehension, SetExpr, @@ -44,6 +45,7 @@ SuperExpr, TempNode, TupleExpr, + TypeAlias, TypeAliasExpr, TypeApplication, TypedDictExpr, @@ -55,6 +57,7 @@ YieldExpr, YieldFromExpr, ) +from mypy.types import is_named_instance from mypy.visitor import ExpressionVisitor # [Note Literals and literal_hash] @@ -97,6 +100,9 @@ Key: _TypeAlias = tuple[Any, ...] +LITERAL_NAMES = frozenset( + ("builtins.True", "builtins.False", "builtins.None", "builtins.NotImplemented") +) def literal_hash(e: Expression) -> Key | None: @@ -135,10 +141,23 @@ def literal(e: Expression) -> int: else: return LITERAL_NO - elif isinstance(e, NameExpr): - if isinstance(e.node, Var) and e.node.is_final and e.node.final_value is not None: + elif isinstance(e, RefExpr): + if ( + isinstance(e, NameExpr) + and isinstance(e.node, Var) + and e.node.is_final + and e.node.final_value is not None + ): return LITERAL_YES - return LITERAL_TYPE + + if e.fullname in LITERAL_NAMES: + return LITERAL_YES + elif isinstance(e.node, TypeAlias) and not e.node.python_3_12_type_alias: + if is_named_instance(e.node.target, LITERAL_NAMES): + return LITERAL_YES + + if isinstance(e, NameExpr): + return LITERAL_TYPE if isinstance(e, (IntExpr, FloatExpr, ComplexExpr, StrExpr, BytesExpr)): return LITERAL_YES diff --git a/mypy/types.py b/mypy/types.py index 025812e25f0a..f4ecf0003dce 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -4040,8 +4040,8 @@ def visit_type_alias_type(self, t: TypeAliasType, /) -> list[mypy.nodes.TypeAlia return res -def is_named_instance(t: Type, fullnames: str | tuple[str, ...]) -> TypeGuard[Instance]: - if not isinstance(fullnames, tuple): +def is_named_instance(t: Type, fullnames: str | Iterable[str]) -> TypeGuard[Instance]: + if isinstance(fullnames, str): fullnames = (fullnames,) t = get_proper_type(t)