diff --git a/mypy/applytype.py b/mypy/applytype.py index c8003795ba0b..731200a06b65 100644 --- a/mypy/applytype.py +++ b/mypy/applytype.py @@ -39,7 +39,7 @@ def get_target_type( skip_unsatisfied: bool, ) -> Type | None: p_type = get_proper_type(type) - if isinstance(p_type, UninhabitedType) and tvar.has_default(): + if isinstance(p_type, UninhabitedType) and p_type.ambiguous and tvar.has_default(): return tvar.default if isinstance(tvar, ParamSpecType): return type diff --git a/mypy/checker.py b/mypy/checker.py index 80402e71dce6..2cb3d69b2d77 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -4552,7 +4552,7 @@ def check_lvalue( self.check_lvalue(sub_expr)[0] or # This type will be used as a context for further inference of rvalue, # we put Uninhabited if there is no information available from lvalue. - UninhabitedType() + UninhabitedType(ambiguous=True) for sub_expr in lvalue.items ] lvalue_type = TupleType(types, self.named_type("builtins.tuple")) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 48ea7ab51f61..c968e5cc6923 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -2085,7 +2085,7 @@ def infer_function_type_arguments_using_context( # Only substitute non-Uninhabited and non-erased types. new_args: list[Type | None] = [] for arg in args: - if has_uninhabited_component(arg) or has_erased_component(arg): + if has_ambiguous_uninhabited_component(arg) or has_erased_component(arg): new_args.append(None) else: new_args.append(arg) @@ -6719,8 +6719,8 @@ def visit_uninhabited_type(self, t: UninhabitedType) -> bool: return True -def has_ambiguous_uninhabited_component(t: Type) -> bool: - return t.accept(HasAmbiguousUninhabitedComponentsQuery()) +def has_ambiguous_uninhabited_component(t: Type | None) -> bool: + return t is not None and t.accept(HasAmbiguousUninhabitedComponentsQuery()) class HasAmbiguousUninhabitedComponentsQuery(types.BoolTypeQuery): diff --git a/mypy/types.py b/mypy/types.py index 40c3839e2efc..898a3344a3a5 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -1389,9 +1389,9 @@ class UninhabitedType(ProperType): ambiguous: bool # Is this a result of inference for a variable without constraints? - def __init__(self, line: int = -1, column: int = -1) -> None: + def __init__(self, line: int = -1, column: int = -1, *, ambiguous: bool = False) -> None: super().__init__(line, column) - self.ambiguous = False + self.ambiguous = ambiguous def can_be_true_default(self) -> bool: return False diff --git a/test-data/unit/check-typevar-defaults.test b/test-data/unit/check-typevar-defaults.test index 535d882ccf3c..7987178d1fe0 100644 --- a/test-data/unit/check-typevar-defaults.test +++ b/test-data/unit/check-typevar-defaults.test @@ -150,6 +150,15 @@ def func_error_alias2( reveal_type(c) # N: Revealed type is "builtins.dict[builtins.int, builtins.float]" [builtins fixtures/dict.pyi] +[case testTypeVarDefaultsExplicitNever] +from typing import Generic, Never, TypeVar + +D = TypeVar("D", default=int) +class WithDefault(Generic[D]): pass + +never_with_default: WithDefault[Never] = WithDefault() +explicit_with_default: WithDefault[Never] = WithDefault[Never]() + [case testTypeVarDefaultsFunctions] from typing import TypeVar, ParamSpec, List, Union, Callable, Tuple from typing_extensions import TypeVarTuple, Unpack