Skip to content

Commit df4717e

Browse files
authored
Represent bottom type as Never in messages (#15996)
Fixes #15950
1 parent 9a0aca1 commit df4717e

32 files changed

+111
-111
lines changed

mypy/checker.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3934,7 +3934,7 @@ def is_valid_defaultdict_partial_value_type(self, t: ProperType) -> bool:
39343934
Examples:
39353935
39363936
* t is 'int' --> True
3937-
* t is 'list[<nothing>]' --> True
3937+
* t is 'list[Never]' --> True
39383938
* t is 'dict[...]' --> False (only generic types with a single type
39393939
argument supported)
39403940
"""
@@ -3980,7 +3980,7 @@ def set_inference_error_fallback_type(self, var: Var, lvalue: Lvalue, type: Type
39803980
x = [] # type: ignore
39813981
x.append(1) # Should be ok!
39823982
3983-
We implement this here by giving x a valid type (replacing inferred <nothing> with Any).
3983+
We implement this here by giving x a valid type (replacing inferred Never with Any).
39843984
"""
39853985
fallback = self.inference_error_fallback_type(type)
39863986
self.set_inferred_type(var, lvalue, fallback)
@@ -7403,7 +7403,7 @@ def is_valid_inferred_type(typ: Type, is_lvalue_final: bool = False) -> bool:
74037403
class InvalidInferredTypes(BoolTypeQuery):
74047404
"""Find type components that are not valid for an inferred type.
74057405
7406-
These include <Erased> type, and any <nothing> types resulting from failed
7406+
These include <Erased> type, and any uninhabited types resulting from failed
74077407
(ambiguous) type inference.
74087408
"""
74097409

@@ -7424,15 +7424,15 @@ def visit_type_var(self, t: TypeVarType) -> bool:
74247424

74257425

74267426
class SetNothingToAny(TypeTranslator):
7427-
"""Replace all ambiguous <nothing> types with Any (to avoid spurious extra errors)."""
7427+
"""Replace all ambiguous Uninhabited types with Any (to avoid spurious extra errors)."""
74287428

74297429
def visit_uninhabited_type(self, t: UninhabitedType) -> Type:
74307430
if t.ambiguous:
74317431
return AnyType(TypeOfAny.from_error)
74327432
return t
74337433

74347434
def visit_type_alias_type(self, t: TypeAliasType) -> Type:
7435-
# Target of the alias cannot be an ambiguous <nothing>, so we just
7435+
# Target of the alias cannot be an ambiguous UninhabitedType, so we just
74367436
# replace the arguments.
74377437
return t.copy_modified(args=[a.accept(self) for a in t.args])
74387438

@@ -7774,7 +7774,7 @@ def is_subtype_no_promote(left: Type, right: Type) -> bool:
77747774

77757775

77767776
def is_overlapping_types_no_promote_no_uninhabited_no_none(left: Type, right: Type) -> bool:
7777-
# For the purpose of unsafe overload checks we consider list[<nothing>] and list[int]
7777+
# For the purpose of unsafe overload checks we consider list[Never] and list[int]
77787778
# non-overlapping. This is consistent with how we treat list[int] and list[str] as
77797779
# non-overlapping, despite [] belongs to both. Also this will prevent false positives
77807780
# for failed type inference during unification.

mypy/checkexpr.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2080,7 +2080,7 @@ def infer_function_type_arguments(
20802080
):
20812081
freeze_all_type_vars(applied)
20822082
return applied
2083-
# If it didn't work, erase free variables as <nothing>, to avoid confusing errors.
2083+
# If it didn't work, erase free variables as uninhabited, to avoid confusing errors.
20842084
unknown = UninhabitedType()
20852085
unknown.ambiguous = True
20862086
inferred_args = [
@@ -2444,7 +2444,7 @@ def check_argument_types(
24442444
callee_arg_types = [orig_callee_arg_type]
24452445
callee_arg_kinds = [ARG_STAR]
24462446
else:
2447-
# TODO: Any and <nothing> can appear in Unpack (as a result of user error),
2447+
# TODO: Any and Never can appear in Unpack (as a result of user error),
24482448
# fail gracefully here and elsewhere (and/or normalize them away).
24492449
assert isinstance(unpacked_type, Instance)
24502450
assert unpacked_type.type.fullname == "builtins.tuple"

mypy/expandtype.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ def expand_unpack(self, t: UnpackType) -> list[Type]:
285285
):
286286
return [UnpackType(typ=repl)]
287287
elif isinstance(repl, (AnyType, UninhabitedType)):
288-
# Replace *Ts = Any with *Ts = *tuple[Any, ...] and some for <nothing>.
288+
# Replace *Ts = Any with *Ts = *tuple[Any, ...] and some for Never.
289289
# These types may appear here as a result of user error or failed inference.
290290
return [UnpackType(t.type.tuple_fallback.copy_modified(args=[repl]))]
291291
else:

mypy/meet.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -968,11 +968,11 @@ def typed_dict_mapping_overlap(
968968
969969
As usual empty, dictionaries lie in a gray area. In general, List[str] and List[str]
970970
are considered non-overlapping despite empty list belongs to both. However, List[int]
971-
and List[<nothing>] are considered overlapping.
971+
and List[Never] are considered overlapping.
972972
973973
So here we follow the same logic: a TypedDict with no required keys is considered
974974
non-overlapping with Mapping[str, <some type>], but is considered overlapping with
975-
Mapping[<nothing>, <nothing>]. This way we avoid false positives for overloads, and also
975+
Mapping[Never, Never]. This way we avoid false positives for overloads, and also
976976
avoid false positives for comparisons like SomeTypedDict == {} under --strict-equality.
977977
"""
978978
left, right = get_proper_types((left, right))

mypy/messages.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,7 +2068,7 @@ def report_protocol_problems(
20682068
if supertype.type.fullname in exclusions.get(type(subtype), []):
20692069
return
20702070
if any(isinstance(tp, UninhabitedType) for tp in get_proper_types(supertype.args)):
2071-
# We don't want to add notes for failed inference (e.g. Iterable[<nothing>]).
2071+
# We don't want to add notes for failed inference (e.g. Iterable[Never]).
20722072
# This will be only confusing a user even more.
20732073
return
20742074

@@ -2395,7 +2395,7 @@ def quote_type_string(type_string: str) -> str:
23952395
"""Quotes a type representation for use in messages."""
23962396
no_quote_regex = r"^<(tuple|union): \d+ items>$"
23972397
if (
2398-
type_string in ["Module", "overloaded function", "<nothing>", "<deleted>"]
2398+
type_string in ["Module", "overloaded function", "Never", "<deleted>"]
23992399
or type_string.startswith("Module ")
24002400
or re.match(no_quote_regex, type_string) is not None
24012401
or type_string.endswith("?")
@@ -2597,7 +2597,7 @@ def format_literal_value(typ: LiteralType) -> str:
25972597
if typ.is_noreturn:
25982598
return "NoReturn"
25992599
else:
2600-
return "<nothing>"
2600+
return "Never"
26012601
elif isinstance(typ, TypeType):
26022602
type_name = "type" if options.use_lowercase_names() else "Type"
26032603
return f"{type_name}[{format(typ.item)}]"

mypy/solve.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,8 @@ def test(x: U) -> U: ...
300300
common_upper_bound_p = get_proper_type(common_upper_bound)
301301
# We include None for when strict-optional is disabled.
302302
if isinstance(common_upper_bound_p, (UninhabitedType, NoneType)):
303-
# This will cause to infer <nothing>, which is better than a free TypeVar
304-
# that has an upper bound <nothing>.
303+
# This will cause to infer Never, which is better than a free TypeVar
304+
# that has an upper bound Never.
305305
return None
306306

307307
values: list[Type] = []

mypy/typeops.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ class B(A): pass
330330
)
331331

332332
# Update the method signature with the solutions found.
333-
# Technically, some constraints might be unsolvable, make them <nothing>.
333+
# Technically, some constraints might be unsolvable, make them Never.
334334
to_apply = [t if t is not None else UninhabitedType() for t in typeargs]
335335
func = expand_type(func, {tv.id: arg for tv, arg in zip(self_vars, to_apply)})
336336
variables = [v for v in func.variables if v not in self_vars]

mypy/types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3103,7 +3103,7 @@ def visit_none_type(self, t: NoneType) -> str:
31033103
return "None"
31043104

31053105
def visit_uninhabited_type(self, t: UninhabitedType) -> str:
3106-
return "<nothing>"
3106+
return "Never"
31073107

31083108
def visit_erased_type(self, t: ErasedType) -> str:
31093109
return "<Erased>"

test-data/unit/check-classes.test

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7718,13 +7718,13 @@ class D:
77187718
def __init__(self) -> NoReturn: ...
77197719

77207720
if object():
7721-
reveal_type(A()) # N: Revealed type is "<nothing>"
7721+
reveal_type(A()) # N: Revealed type is "Never"
77227722
if object():
7723-
reveal_type(B()) # N: Revealed type is "<nothing>"
7723+
reveal_type(B()) # N: Revealed type is "Never"
77247724
if object():
7725-
reveal_type(C()) # N: Revealed type is "<nothing>"
7725+
reveal_type(C()) # N: Revealed type is "Never"
77267726
if object():
7727-
reveal_type(D()) # N: Revealed type is "<nothing>"
7727+
reveal_type(D()) # N: Revealed type is "Never"
77287728

77297729
[case testOverloadedNewAndInitNoReturn]
77307730
from typing import NoReturn, overload
@@ -7764,19 +7764,19 @@ class D:
77647764
def __init__(self, a: int = ...) -> None: ...
77657765

77667766
if object():
7767-
reveal_type(A()) # N: Revealed type is "<nothing>"
7767+
reveal_type(A()) # N: Revealed type is "Never"
77687768
reveal_type(A(1)) # N: Revealed type is "__main__.A"
77697769

77707770
if object():
7771-
reveal_type(B()) # N: Revealed type is "<nothing>"
7771+
reveal_type(B()) # N: Revealed type is "Never"
77727772
reveal_type(B(1)) # N: Revealed type is "__main__.B"
77737773

77747774
if object():
7775-
reveal_type(C()) # N: Revealed type is "<nothing>"
7775+
reveal_type(C()) # N: Revealed type is "Never"
77767776
reveal_type(C(1)) # N: Revealed type is "__main__.C"
77777777

77787778
if object():
7779-
reveal_type(D()) # N: Revealed type is "<nothing>"
7779+
reveal_type(D()) # N: Revealed type is "Never"
77807780
reveal_type(D(1)) # N: Revealed type is "__main__.D"
77817781

77827782
[case testClassScopeImportWithWrapperAndError]

test-data/unit/check-dataclass-transform.test

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ class FunctionModel:
506506
integer_: tuple
507507

508508
FunctionModel(string_="abc", integer_=1)
509-
FunctionModel(string_="abc", integer_=tuple()) # E: Argument "integer_" to "FunctionModel" has incompatible type "Tuple[<nothing>, ...]"; expected "int"
509+
FunctionModel(string_="abc", integer_=tuple()) # E: Argument "integer_" to "FunctionModel" has incompatible type "Tuple[Never, ...]"; expected "int"
510510

511511
[typing fixtures/typing-full.pyi]
512512
[builtins fixtures/dataclasses.pyi]
@@ -529,7 +529,7 @@ class FunctionModel:
529529
integer_: int
530530

531531
FunctionModel(string_="abc", integer_=1)
532-
FunctionModel(string_="abc", integer_=tuple()) # E: Argument "integer_" to "FunctionModel" has incompatible type "Tuple[<nothing>, ...]"; expected "int"
532+
FunctionModel(string_="abc", integer_=tuple()) # E: Argument "integer_" to "FunctionModel" has incompatible type "Tuple[Never, ...]"; expected "int"
533533

534534
[typing fixtures/typing-full.pyi]
535535
[builtins fixtures/dataclasses.pyi]
@@ -552,7 +552,7 @@ class BaseClassModel(ModelBase):
552552
integer_: tuple
553553

554554
BaseClassModel(string_="abc", integer_=1)
555-
BaseClassModel(string_="abc", integer_=tuple()) # E: Argument "integer_" to "BaseClassModel" has incompatible type "Tuple[<nothing>, ...]"; expected "int"
555+
BaseClassModel(string_="abc", integer_=tuple()) # E: Argument "integer_" to "BaseClassModel" has incompatible type "Tuple[Never, ...]"; expected "int"
556556

557557
[typing fixtures/typing-full.pyi]
558558
[builtins fixtures/dataclasses.pyi]
@@ -574,7 +574,7 @@ class BaseClassModel(ModelBase):
574574
integer_: int
575575

576576
BaseClassModel(string_="abc", integer_=1)
577-
BaseClassModel(string_="abc", integer_=tuple()) # E: Argument "integer_" to "BaseClassModel" has incompatible type "Tuple[<nothing>, ...]"; expected "int"
577+
BaseClassModel(string_="abc", integer_=tuple()) # E: Argument "integer_" to "BaseClassModel" has incompatible type "Tuple[Never, ...]"; expected "int"
578578

579579
[typing fixtures/typing-full.pyi]
580580
[builtins fixtures/dataclasses.pyi]
@@ -599,7 +599,7 @@ class MetaClassModel(ModelBaseWithMeta):
599599
integer_: tuple
600600

601601
MetaClassModel(string_="abc", integer_=1)
602-
MetaClassModel(string_="abc", integer_=tuple()) # E: Argument "integer_" to "MetaClassModel" has incompatible type "Tuple[<nothing>, ...]"; expected "int"
602+
MetaClassModel(string_="abc", integer_=tuple()) # E: Argument "integer_" to "MetaClassModel" has incompatible type "Tuple[Never, ...]"; expected "int"
603603

604604
[typing fixtures/typing-full.pyi]
605605
[builtins fixtures/dataclasses.pyi]
@@ -624,7 +624,7 @@ class MetaClassModel(ModelBaseWithMeta):
624624
integer_: int
625625

626626
MetaClassModel(string_="abc", integer_=1)
627-
MetaClassModel(string_="abc", integer_=tuple()) # E: Argument "integer_" to "MetaClassModel" has incompatible type "Tuple[<nothing>, ...]"; expected "int"
627+
MetaClassModel(string_="abc", integer_=tuple()) # E: Argument "integer_" to "MetaClassModel" has incompatible type "Tuple[Never, ...]"; expected "int"
628628

629629
[typing fixtures/typing-full.pyi]
630630
[builtins fixtures/dataclasses.pyi]

0 commit comments

Comments
 (0)