diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 603acbe84f0f..fcbc619f5ea4 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -1671,6 +1671,10 @@ def check_call( object_type, original_type=callee, ) + elif isinstance(callee, UninhabitedType): + ret = UninhabitedType() + ret.ambiguous = callee.ambiguous + return callee, ret else: return self.msg.not_callable(callee, context), AnyType(TypeOfAny.from_error) diff --git a/mypy/checkmember.py b/mypy/checkmember.py index 5b5580a648a8..a1c84f07e473 100644 --- a/mypy/checkmember.py +++ b/mypy/checkmember.py @@ -69,6 +69,7 @@ TypeVarLikeType, TypeVarTupleType, TypeVarType, + UninhabitedType, UnionType, get_proper_type, ) @@ -268,6 +269,10 @@ def _analyze_member_access( if not mx.suppress_errors: mx.msg.deleted_as_rvalue(typ, mx.context) return AnyType(TypeOfAny.from_error) + elif isinstance(typ, UninhabitedType): + attr_type = UninhabitedType() + attr_type.ambiguous = typ.ambiguous + return attr_type return report_missing_attribute(mx.original_type, typ, name, mx) diff --git a/test-data/unit/check-unreachable-code.test b/test-data/unit/check-unreachable-code.test index 368431127b76..f425410a9774 100644 --- a/test-data/unit/check-unreachable-code.test +++ b/test-data/unit/check-unreachable-code.test @@ -1587,3 +1587,19 @@ x = 0 # not unreachable f2: Callable[[], NoReturn] = lambda: foo() x = 0 # not unreachable + +[case testAttributeNoReturn] +# flags: --warn-unreachable +from typing import Optional, NoReturn, TypeVar + +def foo() -> NoReturn: + raise + +T = TypeVar("T") +def bar(x: Optional[list[T]] = None) -> T: + ... + +reveal_type(bar().attr) # N: Revealed type is "Never" +1 # not unreachable +reveal_type(foo().attr) # N: Revealed type is "Never" +1 # E: Statement is unreachable
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: