diff --git a/.idea/watcherTasks.xml b/.idea/watcherTasks.xml
index 6e069eeaf..266b4324a 100644
--- a/.idea/watcherTasks.xml
+++ b/.idea/watcherTasks.xml
@@ -41,5 +41,9 @@
+
+
+
+
\ No newline at end of file
diff --git a/mypy/binder.py b/mypy/binder.py
index 28462e8d0..48324edb1 100644
--- a/mypy/binder.py
+++ b/mypy/binder.py
@@ -5,6 +5,7 @@
from typing import DefaultDict, Generator, Iterator, List, NamedTuple, Optional, Tuple, Union
from typing_extensions import TypeAlias as _TypeAlias
+import mypy.options
from mypy.erasetype import remove_instance_last_known_values
from mypy.join import join_simple
from mypy.literals import Key, literal, literal_hash, subkeys
@@ -331,7 +332,8 @@ def assign_type(
) -> None:
# We should erase last known value in binder, because if we are using it,
# it means that the target is not final, and therefore can't hold a literal.
- type = remove_instance_last_known_values(type)
+ # HUUHHH?????
+ # type = remove_instance_last_known_values(type)
if self.type_assignments is not None:
# We are in a multiassign from union, defer the actual binding,
diff --git a/mypy/checker.py b/mypy/checker.py
index 0fdb34335..d3dad0da3 100644
--- a/mypy/checker.py
+++ b/mypy/checker.py
@@ -3589,19 +3589,30 @@ def check_assignment(
):
lvalue.node.type = remove_instance_last_known_values(lvalue_type)
+ elif lvalue.node and lvalue.node.is_inferred and rvalue_type:
+ # for literal values
+ # Don't use type binder for definitions of special forms, like named tuples.
+ if not (isinstance(lvalue, NameExpr) and lvalue.is_special_form):
+ self.binder.assign_type(lvalue, rvalue_type, lvalue_type, False)
+
elif index_lvalue:
self.check_indexed_assignment(index_lvalue, rvalue, lvalue)
if inferred:
type_context = self.get_variable_type_context(inferred)
rvalue_type = self.expr_checker.accept(rvalue, type_context=type_context)
+ original_rvalue_type = rvalue_type
if not (
inferred.is_final
or inferred.is_index_var
or (isinstance(lvalue, NameExpr) and lvalue.name == "__match_args__")
):
rvalue_type = remove_instance_last_known_values(rvalue_type)
- self.infer_variable_type(inferred, lvalue, rvalue_type, rvalue)
+ if self.infer_variable_type(inferred, lvalue, rvalue_type, rvalue):
+ self.binder.assign_type(
+ lvalue, original_rvalue_type, original_rvalue_type, False
+ )
+
self.check_assignment_to_slots(lvalue)
# (type, operator) tuples for augmented assignments supported with partial types
@@ -4553,12 +4564,13 @@ def is_definition(self, s: Lvalue) -> bool:
def infer_variable_type(
self, name: Var, lvalue: Lvalue, init_type: Type, context: Context
- ) -> None:
+ ) -> bool:
"""Infer the type of initialized variables from initializer type."""
+ valid = True
if isinstance(init_type, DeletedType):
self.msg.deleted_as_rvalue(init_type, context)
elif (
- not is_valid_inferred_type(init_type, is_lvalue_final=name.is_final)
+ not (valid := is_valid_inferred_type(init_type, is_lvalue_final=name.is_final))
and not self.no_partial_types
):
# We cannot use the type of the initialization expression for full type
@@ -4585,6 +4597,7 @@ def infer_variable_type(
init_type = strip_type(init_type)
self.set_inferred_type(name, lvalue, init_type)
+ return valid
def infer_partial_type(self, name: Var, lvalue: Lvalue, init_type: Type) -> bool:
init_type = get_proper_type(init_type)
diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py
index e447ea0e4..b057fdb94 100644
--- a/mypy/checkexpr.py
+++ b/mypy/checkexpr.py
@@ -2,14 +2,21 @@
from __future__ import annotations
+import builtins
+import contextlib
import enum
+import importlib
+import io
import itertools
import time
from collections import defaultdict
from contextlib import contextmanager
+from types import GetSetDescriptorType
from typing import Callable, ClassVar, Final, Iterable, Iterator, List, Optional, Sequence, cast
from typing_extensions import TypeAlias as _TypeAlias, assert_never, overload
+from basedtyping import TypeFunctionError
+
import mypy.checker
import mypy.errorcodes as codes
from mypy import applytype, erasetype, errorcodes, join, message_registry, nodes, operators, types
@@ -23,6 +30,7 @@
)
from mypy.checkstrformat import StringFormatterChecker
from mypy.erasetype import erase_type, remove_instance_last_known_values, replace_meta_vars
+from mypy.errorcodes import ErrorCode
from mypy.errors import ErrorInfo, ErrorWatcher, report_internal_error
from mypy.expandtype import (
expand_type,
@@ -205,12 +213,14 @@
from mypy.typestate import type_state
from mypy.typevars import fill_typevars
from mypy.util import split_module_names
+from mypy.valuetotype import type_to_value, value_to_type
from mypy.visitor import ExpressionVisitor
# Type of callback user for checking individual function arguments. See
# check_args() below for details.
ArgChecker: _TypeAlias = Callable[
- [Type, Type, ArgKind, Type, int, int, CallableType, Optional[Type], Context, Context], None
+ [Type, Type, ArgKind, Type, int, int, CallableType, Optional[Type], Context, Context, bool],
+ None,
]
# Maximum nesting level for math union in overloads, setting this to large values
@@ -1846,12 +1856,13 @@ def check_callable_call(
fresh_ret_type = freshen_all_functions_type_vars(callee.ret_type)
freeze_all_type_vars(fresh_ret_type)
callee = callee.copy_modified(ret_type=fresh_ret_type)
-
if callee.is_generic():
need_refresh = any(
isinstance(v, (ParamSpecType, TypeVarTupleType)) for v in callee.variables
)
+ # IT"S HERE!
callee = freshen_function_type_vars(callee)
+ # IT"S HERE!
callee = self.infer_function_type_arguments_using_context(callee, context)
if need_refresh:
# Argument kinds etc. may have changed due to
@@ -1909,7 +1920,6 @@ def check_callable_call(
self.check_argument_types(
arg_types, arg_kinds, args, callee, formal_to_actual, context, object_type=object_type
)
-
if (
callee.is_type_obj()
and (len(arg_types) == 1)
@@ -1921,6 +1931,38 @@ def check_callable_call(
# Store the inferred callable type.
self.chk.store_type(callable_node, callee)
+ if callee.is_type_function:
+ with self.msg.filter_errors(filter_errors=True) as error_watcher:
+ if object_type:
+ self.check_arg(
+ caller_type=object_type,
+ original_caller_type=object_type,
+ caller_kind=ArgKind.ARG_POS,
+ callee_type=callee.bound_args[0],
+ n=0,
+ m=0,
+ callee=callee,
+ object_type=object_type,
+ context=context,
+ outer_context=context,
+ type_function=True,
+ )
+
+ self.check_argument_types(
+ arg_types,
+ arg_kinds,
+ args,
+ callee,
+ formal_to_actual,
+ context,
+ object_type=object_type,
+ type_function=True,
+ )
+ if not error_watcher.has_new_errors() and "." in callable_name:
+ ret_type = self.call_type_function(callable_name, object_type, arg_types, context)
+ if ret_type:
+ callee = callee.copy_modified(ret_type=ret_type)
+
if callable_name and (
(object_type is None and self.plugin.get_function_hook(callable_name))
or (object_type is not None and self.plugin.get_method_hook(callable_name))
@@ -1939,6 +1981,71 @@ def check_callable_call(
callee = callee.copy_modified(ret_type=new_ret_type)
return callee.ret_type, callee
+ def call_type_function(
+ self,
+ callable_name: str,
+ object_type: ProperType | None,
+ arg_types: list[ProperType],
+ context: Context,
+ ) -> Type | None:
+ container_name, fn_name = callable_name.rsplit(".", maxsplit=1)
+ resolved = None
+ for part in container_name.split("."):
+ if resolved:
+ m = resolved.names.get(part)
+ else:
+ m = self.chk.modules.get(part)
+ if m:
+ resolved = m
+ is_method = not isinstance(resolved, MypyFile)
+ if is_method:
+ container = resolved.node
+ module_name = container.module_name
+ else:
+ container = resolved
+ module_name = container.fullname
+
+ all_sigs = []
+ object_type = object_type and [object_type] or []
+ for arg in object_type + arg_types:
+ if isinstance(arg, UnionType):
+ if not all_sigs:
+ all_sigs = [[x] for x in arg.items]
+ else:
+ from itertools import product
+
+ all_sigs = product(all_sigs, arg.items)
+ all_sigs = all_sigs or [object_type + arg_types]
+ all_rets = []
+ with contextlib.redirect_stdout(io.StringIO()), contextlib.redirect_stderr(io.StringIO()):
+ mod = importlib.import_module(module_name)
+ container = getattr(mod, container.name) if is_method else mod
+ fn = getattr(container, fn_name)
+ for sig in all_sigs:
+ if isinstance(fn, (GetSetDescriptorType, property)):
+ fn = fn.__get__
+ args = [type_to_value(arg, self.chk) for arg in sig]
+ try:
+ return_value = fn(*args)
+ except RecursionError:
+ self.chk.fail(
+ "maximum recursion depth exceeded while evaluating type function",
+ context=context,
+ )
+ except TypeFunctionError as type_function_error:
+ code = type_function_error.code and ErrorCode(type_function_error.code, "", "")
+ self.chk.fail(type_function_error.message, code=code, context=context)
+ except Exception as exception:
+ self.chk.fail(
+ f"Invocation raises {type(exception).__name__}: {exception}",
+ context,
+ code=errorcodes.CALL_RAISES,
+ )
+ else:
+ all_rets.append(value_to_type(return_value, chk=self.chk))
+
+ return make_simplified_union(all_rets)
+
def can_return_none(self, type: TypeInfo, attr_name: str) -> bool:
"""Is the given attribute a method with a None-compatible return type?
@@ -2175,6 +2282,13 @@ def infer_function_type_arguments(
Return a derived callable type that has the arguments applied.
"""
if self.chk.in_checked_function():
+ if isinstance(callee_type.ret_type, TypeVarType):
+ # if the return type is constant, infer as literal
+ rvalue_type = [
+ remove_instance_last_known_values(arg) if isinstance(arg, Instance) else arg
+ for arg in args
+ ]
+
# Disable type errors during type inference. There may be errors
# due to partial available context information at this time, but
# these errors can be safely ignored as the arguments will be
@@ -2581,6 +2695,8 @@ def check_argument_types(
context: Context,
check_arg: ArgChecker | None = None,
object_type: Type | None = None,
+ *,
+ type_function=False,
) -> None:
"""Check argument types against a callable type.
@@ -2712,6 +2828,7 @@ def check_argument_types(
object_type,
args[actual],
context,
+ type_function,
)
def check_arg(
@@ -2726,12 +2843,16 @@ def check_arg(
object_type: Type | None,
context: Context,
outer_context: Context,
+ type_function=False,
) -> None:
"""Check the type of a single argument in a call."""
caller_type = get_proper_type(caller_type)
original_caller_type = get_proper_type(original_caller_type)
callee_type = get_proper_type(callee_type)
-
+ if type_function:
+ # TODO: make this work at all
+ if not isinstance(caller_type, Instance) or not caller_type.last_known_value:
+ caller_type = self.named_type("builtins.object")
if isinstance(caller_type, DeletedType):
self.msg.deleted_as_rvalue(caller_type, context)
# Only non-abstract non-protocol class can be given where Type[...] is expected...
@@ -3348,6 +3469,7 @@ def check_arg(
object_type: Type | None,
context: Context,
outer_context: Context,
+ type_function: bool,
) -> None:
if not arg_approximate_similarity(caller_type, callee_type):
# No match -- exit early since none of the remaining work can change
@@ -3580,10 +3702,14 @@ def visit_bytes_expr(self, e: BytesExpr) -> Type:
def visit_float_expr(self, e: FloatExpr) -> Type:
"""Type check a float literal (trivial)."""
+ if mypy.options._based:
+ return self.infer_literal_expr_type(e.value, "builtins.float")
return self.named_type("builtins.float")
def visit_complex_expr(self, e: ComplexExpr) -> Type:
"""Type check a complex literal."""
+ if mypy.options._based:
+ return self.infer_literal_expr_type(e.value, "builtins.complex")
return self.named_type("builtins.complex")
def visit_ellipsis(self, e: EllipsisExpr) -> Type:
@@ -6502,6 +6628,7 @@ def narrow_type_from_binder(
known_type, restriction, prohibit_none_typevar_overlap=True
):
return None
+
return narrow_declared_type(known_type, restriction)
return known_type
diff --git a/mypy/errorcodes.py b/mypy/errorcodes.py
index 96488ef7f..49a000d11 100644
--- a/mypy/errorcodes.py
+++ b/mypy/errorcodes.py
@@ -315,6 +315,9 @@ def __hash__(self) -> int:
TYPE_CHECK_ONLY: Final[ErrorCode] = ErrorCode(
"type-check-only", "Value doesn't exist at runtime", "General"
)
+CALL_RAISES: Final[ErrorCode] = ErrorCode(
+ "call-raises", "function call raises an error", "General"
+)
REVEAL: Final = ErrorCode("reveal", "Reveal types at check time", "General")
# Syntax errors are often blocking.
diff --git a/mypy/expandtype.py b/mypy/expandtype.py
index ff9d845ec..190596090 100644
--- a/mypy/expandtype.py
+++ b/mypy/expandtype.py
@@ -1,5 +1,6 @@
from __future__ import annotations
+from contextlib import contextmanager
from typing import Final, Iterable, Mapping, Sequence, TypeVar, cast, overload
from mypy.nodes import ARG_STAR, FakeInfo, Var
@@ -185,6 +186,16 @@ def __init__(self, variables: Mapping[TypeVarId, Type]) -> None:
super().__init__()
self.variables = variables
self.recursive_tvar_guard: dict[TypeVarId, Type | None] = {}
+ self._erase_literals = False
+
+ @contextmanager
+ def erase_literals(self):
+ _erase_literals = self._erase_literals
+ self._erase_literals = True
+ try:
+ yield
+ finally:
+ self._erase_literals = _erase_literals
def visit_unbound_type(self, t: UnboundType) -> Type:
return t
@@ -211,7 +222,8 @@ def visit_erased_type(self, t: ErasedType) -> Type:
return t
def visit_instance(self, t: Instance) -> Type:
- args = self.expand_types_with_unpack(list(t.args))
+ with self.erase_literals():
+ args = self.expand_types_with_unpack(list(t.args))
if isinstance(t.type, FakeInfo):
# The type checker expands function definitions and bodies
@@ -238,7 +250,7 @@ def visit_type_var(self, t: TypeVarType) -> Type:
if t.id.is_self():
t = t.copy_modified(upper_bound=t.upper_bound.accept(self))
repl = self.variables.get(t.id, t)
- if isinstance(repl, ProperType) and isinstance(repl, Instance):
+ if self._erase_literals and isinstance(repl, ProperType) and isinstance(repl, Instance):
# TODO: do we really need to do this?
# If I try to remove this special-casing ~40 tests fail on reveal_type().
return repl.copy_modified(last_known_value=None)
@@ -410,17 +422,18 @@ def visit_callable_type(self, t: CallableType) -> CallableType:
var_arg = t.var_arg()
needs_normalization = False
- if var_arg is not None and isinstance(var_arg.typ, UnpackType):
- needs_normalization = True
- arg_types = self.interpolate_args_for_unpack(t, var_arg.typ)
- else:
- arg_types = self.expand_types(t.arg_types)
- expanded = t.copy_modified(
- arg_types=arg_types,
- ret_type=t.ret_type.accept(self),
- type_guard=t.type_guard and cast(TypeGuardType, t.type_guard.accept(self)),
- type_is=(t.type_is.accept(self) if t.type_is is not None else None),
- )
+ with self.erase_literals():
+ if var_arg is not None and isinstance(var_arg.typ, UnpackType):
+ needs_normalization = True
+ arg_types = self.interpolate_args_for_unpack(t, var_arg.typ)
+ else:
+ arg_types = self.expand_types(t.arg_types)
+ expanded = t.copy_modified(
+ arg_types=arg_types,
+ ret_type=t.ret_type.accept(self),
+ type_guard=t.type_guard and cast(TypeGuardType, t.type_guard.accept(self)),
+ type_is=(t.type_is.accept(self) if t.type_is is not None else None),
+ )
if needs_normalization:
return expanded.with_normalized_var_args()
return expanded
diff --git a/mypy/fastparse.py b/mypy/fastparse.py
index 2e2cd7248..afff56f65 100644
--- a/mypy/fastparse.py
+++ b/mypy/fastparse.py
@@ -2129,7 +2129,8 @@ def numeric_type(self, value: object, n: AST) -> Type:
# Other kinds of numbers (floats, complex) are not valid parameters for
# RawExpressionType so we just pass in 'None' for now. We'll report the
# appropriate error at a later stage.
- numeric_value = None
+ # based: they are valid
+ numeric_value = value
type_name = f"builtins.{type(value).__name__}"
return RawExpressionType(
numeric_value, type_name, line=self.line, column=getattr(n, "col_offset", -1)
diff --git a/mypy/join.py b/mypy/join.py
index c32f6a477..a24fcf60b 100644
--- a/mypy/join.py
+++ b/mypy/join.py
@@ -18,6 +18,7 @@
is_protocol_implementation,
is_subtype,
)
+from mypy.typeops import make_simplified_union
from mypy.types import (
AnyType,
CallableType,
@@ -232,7 +233,7 @@ def join_simple(declaration: Type | None, s: Type, t: Type) -> ProperType:
if declaration is None or is_subtype(value, declaration):
return value
- return declaration
+ return value
def trivial_join(s: Type, t: Type) -> Type:
diff --git a/mypy/meet.py b/mypy/meet.py
index 08af963ea..6d368e92b 100644
--- a/mypy/meet.py
+++ b/mypy/meet.py
@@ -197,6 +197,8 @@ def narrow_declared_type(declared: Type, narrowed: Type) -> Type:
# Special case: 'int' can't be narrowed down to a native int type such as
# i64, since they have different runtime representations.
return original_declared
+ if isinstance(narrowed, Instance) and narrowed.last_known_value:
+ return narrowed
return meet_types(original_declared, original_narrowed)
elif isinstance(declared, (TupleType, TypeType, LiteralType)):
return meet_types(original_declared, original_narrowed)
diff --git a/mypy/nodes.py b/mypy/nodes.py
index 8990f7780..670aa4577 100644
--- a/mypy/nodes.py
+++ b/mypy/nodes.py
@@ -804,6 +804,7 @@ class FuncDef(FuncItem, SymbolNode, Statement):
"dataclass_transform_spec",
"docstring",
"deprecated",
+ "is_type_function",
)
__match_args__ = ("name", "arguments", "type", "body")
@@ -834,6 +835,7 @@ def __init__(
self.dataclass_transform_spec: DataclassTransformSpec | None = None
self.docstring: str | None = None
self.deprecated: str | None = None
+ self.is_type_function = False
@property
def name(self) -> str:
diff --git a/mypy/semanal.py b/mypy/semanal.py
index 2f34392c4..ed1de055c 100644
--- a/mypy/semanal.py
+++ b/mypy/semanal.py
@@ -1062,6 +1062,7 @@ def analyze_func_def(self, defn: FuncDef) -> None:
info = self.type
if info.self_type is not None:
result.variables = [info.self_type] + list(result.variables)
+ result.is_type_function = defn.is_type_function
defn.type = result
self.add_type_alias_deps(analyzer.aliases_used)
self.check_function_signature(defn)
@@ -1883,6 +1884,9 @@ def visit_decorator(self, dec: Decorator) -> None:
dec.func.dataclass_transform_spec = self.parse_dataclass_transform_spec(d)
elif (deprecated := self.get_deprecated(d)) is not None:
dec.func.deprecated = f"function {dec.fullname} is deprecated: {deprecated}"
+ elif refers_to_fullname(d, "basedtyping.type_function"):
+ removed.append(i)
+ dec.func.is_type_function = True
elif not dec.var.is_property:
# We have seen a "non-trivial" decorator before seeing @property, if
# we will see a @property later, give an error, as we don't support this.
diff --git a/mypy/typeanal.py b/mypy/typeanal.py
index 9d6d0ec4d..78c29ca00 100644
--- a/mypy/typeanal.py
+++ b/mypy/typeanal.py
@@ -527,7 +527,6 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool)
return res
elif isinstance(node, TypeInfo):
return self.analyze_type_with_type_info(node, t.args, t, t.empty_tuple_index)
-
elif node.fullname in TYPE_ALIAS_NAMES:
return AnyType(TypeOfAny.special_form)
# Concatenate is an operator, no need for a proper type
@@ -1432,7 +1431,11 @@ def visit_raw_expression_type(self, t: RawExpressionType) -> Type:
if self.report_invalid_types:
msg = None
- if t.base_type_name in ("builtins.int", "builtins.bool"):
+ if (
+ t.base_type_name in ("builtins.int", "builtins.bool")
+ or mypy.options._based
+ and t.base_type_name in ("builtins.float", "builtins.complex")
+ ):
if not self.options.bare_literals:
# The only time it makes sense to use an int or bool is inside of
# a literal type.
@@ -1453,7 +1456,12 @@ def visit_raw_expression_type(self, t: RawExpressionType) -> Type:
self.fail(msg, t, code=codes.VALID_TYPE)
if t.note is not None:
self.note(t.note, t, code=codes.VALID_TYPE)
- if t.base_type_name in ("builtins.int", "builtins.bool"):
+ if t.base_type_name in (
+ "builtins.int",
+ "builtins.bool",
+ "builtins.float",
+ "builtins.complex",
+ ):
v = t.literal_value
assert v is not None
result = LiteralType(
diff --git a/mypy/types.py b/mypy/types.py
index 6036065c4..b9bc01325 100644
--- a/mypy/types.py
+++ b/mypy/types.py
@@ -75,7 +75,7 @@
#
# Note: Float values are only used internally. They are not accepted within
# Literal[...].
-LiteralValue: _TypeAlias = Union[int, str, bool, float]
+LiteralValue: _TypeAlias = Union[int, str, bool, float, complex]
# If we only import type_visitor in the middle of the file, mypy
@@ -2045,6 +2045,7 @@ class CallableType(FunctionLike):
"imprecise_arg_kinds",
"unpack_kwargs", # Was an Unpack[...] with **kwargs used to define this callable?
"fully_typed", # If all type positions are filled.
+ "is_type_function",
)
def __init__(
@@ -2071,6 +2072,7 @@ def __init__(
from_concatenate: bool = False,
imprecise_arg_kinds: bool = False,
unpack_kwargs: bool = False,
+ is_type_function=False,
) -> None:
super().__init__(line, column)
assert len(arg_types) == len(arg_kinds) == len(arg_names)
@@ -2122,6 +2124,7 @@ def __init__(
self.fully_typed = not (
any(is_unannotated_any(arg) for arg in arg_types) or is_unannotated_any(ret_type)
)
+ self.is_type_function = is_type_function
def copy_modified(
self: CT,
@@ -2177,6 +2180,7 @@ def copy_modified(
else self.imprecise_arg_kinds
),
unpack_kwargs=unpack_kwargs if unpack_kwargs is not _dummy else self.unpack_kwargs,
+ is_type_function=self.is_type_function,
)
# Optimization: Only NewTypes are supported as subtypes since
# the class is effectively final, so we can use a cast safely.
@@ -2496,6 +2500,7 @@ def serialize(self) -> JsonDict:
"from_concatenate": self.from_concatenate,
"imprecise_arg_kinds": self.imprecise_arg_kinds,
"unpack_kwargs": self.unpack_kwargs,
+ "is_type_function": self.is_type_function,
}
@classmethod
@@ -2523,6 +2528,7 @@ def deserialize(cls, data: JsonDict) -> CallableType:
from_concatenate=data["from_concatenate"],
imprecise_arg_kinds=data["imprecise_arg_kinds"],
unpack_kwargs=data["unpack_kwargs"],
+ is_type_function=data["is_type_function"],
)
diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi
index 0d02a1845..9d746fb82 100644
--- a/mypy/typeshed/stdlib/builtins.pyi
+++ b/mypy/typeshed/stdlib/builtins.pyi
@@ -73,7 +73,7 @@ from typing_extensions import ( # noqa: Y023
TypeVarTuple,
deprecated,
)
-
+from basedtyping import type_function
if sys.version_info >= (3, 9):
from types import GenericAlias
@@ -234,25 +234,35 @@ class int:
def __new__(cls, x: ConvertibleToInt = ..., /) -> Self: ...
@overload
def __new__(cls, x: str | bytes | bytearray, /, base: SupportsIndex) -> Self: ...
+ @type_function
def as_integer_ratio(self) -> tuple[int, Literal[1]]: ...
@property
+ @type_function
def real(self) -> int: ...
@property
+ @type_function
def imag(self) -> Literal[0]: ...
@property
+ @type_function
def numerator(self) -> int: ...
@property
+ @type_function
def denominator(self) -> Literal[1]: ...
+ @type_function
def conjugate(self) -> int: ...
+ @type_function
def bit_length(self) -> int: ...
if sys.version_info >= (3, 10):
+ @type_function
def bit_count(self) -> int: ...
if sys.version_info >= (3, 11):
+ @type_function
def to_bytes(
self, length: SupportsIndex = 1, byteorder: Literal["little", "big"] = "big", *, signed: bool = False
) -> bytes: ...
@classmethod
+ @type_function
def from_bytes(
cls,
bytes: Iterable[SupportsIndex] | SupportsBytes | ReadableBuffer,
@@ -261,8 +271,10 @@ class int:
signed: bool = False,
) -> Self: ...
else:
+ @type_function
def to_bytes(self, length: SupportsIndex, byteorder: Literal["little", "big"], *, signed: bool = False) -> bytes: ...
@classmethod
+ @type_function
def from_bytes(
cls,
bytes: Iterable[SupportsIndex] | SupportsBytes | ReadableBuffer,
@@ -274,126 +286,221 @@ class int:
if sys.version_info >= (3, 12):
def is_integer(self) -> Literal[True]: ...
+ @type_function
def __add__(self, value: int, /) -> int: ...
+ @type_function
def __sub__(self, value: int, /) -> int: ...
+ @type_function
def __mul__(self, value: int, /) -> int: ...
+ @type_function
def __floordiv__(self, value: int, /) -> int: ...
+ @type_function
def __truediv__(self, value: int, /) -> float: ...
+ @type_function
def __mod__(self, value: int, /) -> int: ...
+ @type_function
def __divmod__(self, value: int, /) -> tuple[int, int]: ...
+ @type_function
def __radd__(self, value: int, /) -> int: ...
+ @type_function
def __rsub__(self, value: int, /) -> int: ...
+ @type_function
def __rmul__(self, value: int, /) -> int: ...
+ @type_function
def __rfloordiv__(self, value: int, /) -> int: ...
+ @type_function
def __rtruediv__(self, value: int, /) -> float: ...
+ @type_function
def __rmod__(self, value: int, /) -> int: ...
+ @type_function
def __rdivmod__(self, value: int, /) -> tuple[int, int]: ...
@overload
+ @type_function
def __pow__(self, x: Literal[0], /) -> Literal[1]: ...
@overload
+ @type_function
def __pow__(self, value: Literal[0], mod: None, /) -> Literal[1]: ...
@overload
+ @type_function
def __pow__(self, value: _PositiveInteger, mod: None = None, /) -> int: ...
@overload
+ @type_function
def __pow__(self, value: _NegativeInteger, mod: None = None, /) -> float: ...
# positive __value -> int; negative __value -> float
# return type must be Any as `int | float` causes too many false-positive errors
@overload
+ @type_function
def __pow__(self, value: int, mod: None = None, /) -> Any: ...
@overload
+ @type_function
def __pow__(self, value: int, mod: int, /) -> int: ...
+ @type_function
def __rpow__(self, value: int, mod: int | None = None, /) -> Any: ...
+ @type_function
def __and__(self, value: int, /) -> int: ...
+ @type_function
def __or__(self, value: int, /) -> int: ...
+ @type_function
def __xor__(self, value: int, /) -> int: ...
+ @type_function
def __lshift__(self, value: int, /) -> int: ...
+ @type_function
def __rshift__(self, value: int, /) -> int: ...
+ @type_function
def __rand__(self, value: int, /) -> int: ...
+ @type_function
def __ror__(self, value: int, /) -> int: ...
+ @type_function
def __rxor__(self, value: int, /) -> int: ...
+ @type_function
def __rlshift__(self, value: int, /) -> int: ...
+ @type_function
def __rrshift__(self, value: int, /) -> int: ...
+ @type_function
def __neg__(self) -> int: ...
+ @type_function
def __pos__(self) -> int: ...
+ @type_function
def __invert__(self) -> int: ...
+ @type_function
def __trunc__(self) -> int: ...
+ @type_function
def __ceil__(self) -> int: ...
+ @type_function
def __floor__(self) -> int: ...
+ @type_function
def __round__(self, ndigits: SupportsIndex = ..., /) -> int: ...
+ @type_function
def __getnewargs__(self) -> tuple[int]: ...
+ @type_function
def __eq__(self, value: object, /) -> bool: ...
+ @type_function
def __ne__(self, value: object, /) -> bool: ...
+ @type_function
def __lt__(self, value: int, /) -> bool: ...
+ @type_function
def __le__(self, value: int, /) -> bool: ...
+ @type_function
def __gt__(self, value: int, /) -> bool: ...
+ @type_function
def __ge__(self, value: int, /) -> bool: ...
+ @type_function
def __float__(self) -> float: ...
+ @type_function
def __int__(self) -> int: ...
+ @type_function
def __abs__(self) -> int: ...
+ @type_function
def __hash__(self) -> int: ...
def __bool__(self) -> bool: ...
+ @type_function
def __index__(self) -> int: ...
class float:
def __new__(cls, x: ConvertibleToFloat = ..., /) -> Self: ...
+ @type_function
def as_integer_ratio(self) -> tuple[int, int]: ...
+ @type_function
def hex(self) -> str: ...
+ @type_function
def is_integer(self) -> bool: ...
@classmethod
+ @type_function
def fromhex(cls, string: str, /) -> Self: ...
@property
+ @type_function
def real(self) -> float: ...
@property
+ @type_function
def imag(self) -> float: ...
+ @type_function
def conjugate(self) -> float: ...
+ @type_function
def __add__(self, value: float, /) -> float: ...
+ @type_function
def __sub__(self, value: float, /) -> float: ...
+ @type_function
def __mul__(self, value: float, /) -> float: ...
+ @type_function
def __floordiv__(self, value: float, /) -> float: ...
+ @type_function
def __truediv__(self, value: float, /) -> float: ...
+ @type_function
def __mod__(self, value: float, /) -> float: ...
+ @type_function
def __divmod__(self, value: float, /) -> tuple[float, float]: ...
@overload
+ @type_function
def __pow__(self, value: int, mod: None = None, /) -> float: ...
# positive __value -> float; negative __value -> complex
# return type must be Any as `float | complex` causes too many false-positive errors
@overload
+ @type_function
def __pow__(self, value: float, mod: None = None, /) -> Any: ...
+ @type_function
def __radd__(self, value: float, /) -> float: ...
+ @type_function
def __rsub__(self, value: float, /) -> float: ...
+ @type_function
def __rmul__(self, value: float, /) -> float: ...
+ @type_function
def __rfloordiv__(self, value: float, /) -> float: ...
+ @type_function
def __rtruediv__(self, value: float, /) -> float: ...
+ @type_function
def __rmod__(self, value: float, /) -> float: ...
+ @type_function
def __rdivmod__(self, value: float, /) -> tuple[float, float]: ...
@overload
+ @type_function
def __rpow__(self, value: _PositiveInteger, mod: None = None, /) -> float: ...
@overload
+ @type_function
def __rpow__(self, value: _NegativeInteger, mod: None = None, /) -> complex: ...
# Returning `complex` for the general case gives too many false-positive errors.
@overload
+ @type_function
def __rpow__(self, value: float, mod: None = None, /) -> Any: ...
+ @type_function
def __getnewargs__(self) -> tuple[float]: ...
+ @type_function
def __trunc__(self) -> int: ...
if sys.version_info >= (3, 9):
+ @type_function
def __ceil__(self) -> int: ...
+ @type_function
def __floor__(self) -> int: ...
@overload
+ @type_function
def __round__(self, ndigits: None = None, /) -> int: ...
@overload
+ @type_function
def __round__(self, ndigits: SupportsIndex, /) -> float: ...
+ @type_function
def __eq__(self, value: object, /) -> bool: ...
+ @type_function
def __ne__(self, value: object, /) -> bool: ...
+ @type_function
def __lt__(self, value: float, /) -> bool: ...
+ @type_function
def __le__(self, value: float, /) -> bool: ...
+ @type_function
def __gt__(self, value: float, /) -> bool: ...
+ @type_function
def __ge__(self, value: float, /) -> bool: ...
+ @type_function
def __neg__(self) -> float: ...
+ @type_function
def __pos__(self) -> float: ...
+ @type_function
def __int__(self) -> int: ...
+ @type_function
def __float__(self) -> float: ...
+ @type_function
+ @type_function
def __abs__(self) -> float: ...
+ @type_function
def __hash__(self) -> int: ...
def __bool__(self) -> bool: ...
@@ -443,70 +550,121 @@ class str(Sequence[str]):
def __new__(cls, object: object = ...) -> Self: ...
@overload
def __new__(cls, object: ReadableBuffer, encoding: str = ..., errors: str = ...) -> Self: ...
+ @type_function
def capitalize(self) -> str: ... # type: ignore[misc]
+ @type_function
def casefold(self) -> str: ... # type: ignore[misc]
+ @type_function
def center(self, width: SupportsIndex, fillchar: str = " ", /) -> str: ... # type: ignore[misc]
+ @type_function
def count(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ... # type: ignore[override]
+ @type_function
def encode(self, encoding: str = "utf-8", errors: str = "strict") -> bytes: ...
+ @type_function
def endswith(
self, suffix: str | tuple[str, ...], start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /
) -> bool: ...
+ @type_function
def expandtabs(self, tabsize: SupportsIndex = 8) -> str: ... # type: ignore[misc]
+ @type_function
def find(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ...
+ @type_function
def format(self, *args: object, **kwargs: object) -> str: ...
+ @type_function
def format_map(self, mapping: _FormatMapMapping, /) -> str: ...
+ @type_function
def index(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ... # type: ignore[override]
+ @type_function
def isalnum(self) -> bool: ...
+ @type_function
def isalpha(self) -> bool: ...
+ @type_function
def isascii(self) -> bool: ...
+ @type_function
def isdecimal(self) -> bool: ...
+ @type_function
def isdigit(self) -> bool: ...
+ @type_function
def isidentifier(self) -> bool: ...
+ @type_function
def islower(self) -> bool: ...
+ @type_function
def isnumeric(self) -> bool: ...
+ @type_function
def isprintable(self) -> bool: ...
+ @type_function
def isspace(self) -> bool: ...
+ @type_function
def istitle(self) -> bool: ...
+ @type_function
def isupper(self) -> bool: ...
+ @type_function
def join(self, iterable: Iterable[str], /) -> str: ... # type: ignore[misc]
+ @type_function
def ljust(self, width: SupportsIndex, fillchar: str = " ", /) -> str: ... # type: ignore[misc]
+ @type_function
def lower(self) -> str: ... # type: ignore[misc]
+ @type_function
def lstrip(self, chars: str | None = None, /) -> str: ... # type: ignore[misc]
+ @type_function
def partition(self, sep: str, /) -> tuple[str, str, str]: ... # type: ignore[misc]
if sys.version_info >= (3, 13):
+ @type_function
def replace(self, old: str, new: str, /, count: SupportsIndex = -1) -> str: ... # type: ignore[misc]
else:
+ @type_function
def replace(self, old: str, new: str, count: SupportsIndex = -1, /) -> str: ... # type: ignore[misc]
if sys.version_info >= (3, 9):
+ @type_function
def removeprefix(self, prefix: str, /) -> str: ... # type: ignore[misc]
+ @type_function
def removesuffix(self, suffix: str, /) -> str: ... # type: ignore[misc]
+ @type_function
def rfind(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ...
+ @type_function
def rindex(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ...
+ @type_function
def rjust(self, width: SupportsIndex, fillchar: str = " ", /) -> str: ... # type: ignore[misc]
+ @type_function
def rpartition(self, sep: str, /) -> tuple[str, str, str]: ... # type: ignore[misc]
+ @type_function
def rsplit(self, sep: str | None = None, maxsplit: SupportsIndex = -1) -> list[str]: ... # type: ignore[misc]
+ @type_function
def rstrip(self, chars: str | None = None, /) -> str: ... # type: ignore[misc]
+ @type_function
def split(self, sep: str | None = None, maxsplit: SupportsIndex = -1) -> list[str]: ... # type: ignore[misc]
+ @type_function
def splitlines(self, keepends: bool = False) -> list[str]: ... # type: ignore[misc]
+ @type_function
def startswith(
self, prefix: str | tuple[str, ...], start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /
) -> bool: ...
+ @type_function
def strip(self, chars: str | None = None, /) -> str: ... # type: ignore[misc]
+ @type_function
def swapcase(self) -> str: ... # type: ignore[misc]
+ @type_function
def title(self) -> str: ... # type: ignore[misc]
+ @type_function
def translate(self, table: _TranslateTable, /) -> str: ...
+ @type_function
def upper(self) -> str: ... # type: ignore[misc]
+ @type_function
def zfill(self, width: SupportsIndex, /) -> str: ... # type: ignore[misc]
@staticmethod
@overload
+ @type_function
def maketrans(x: dict[int, _T] | dict[str, _T] | dict[str | int, _T], /) -> dict[int, _T]: ...
@staticmethod
@overload
+ @type_function
def maketrans(x: str, y: str, /) -> dict[int, int]: ...
@staticmethod
@overload
+ @type_function
def maketrans(x: str, y: str, z: str, /) -> dict[int, int | None]: ...
+ @type_function
def __add__(self, value: str, /) -> str: ... # type: ignore[misc]
# Incompatible with Sequence.__contains__
def __contains__(self, key: str, /) -> bool: ... # type: ignore[override]
@@ -524,6 +682,7 @@ class str(Sequence[str]):
def __ne__(self, value: object, /) -> bool: ...
def __rmul__(self, value: SupportsIndex, /) -> str: ... # type: ignore[misc]
def __getnewargs__(self) -> tuple[str]: ...
+ def __bool__(self) -> bool: ...
class bytes(Sequence[int]):
@overload
@@ -532,12 +691,17 @@ class bytes(Sequence[int]):
def __new__(cls, string: str, /, encoding: str, errors: str = ...) -> Self: ...
@overload
def __new__(cls) -> Self: ...
+ @type_function
def capitalize(self) -> bytes: ...
+ @type_function
def center(self, width: SupportsIndex, fillchar: bytes = b" ", /) -> bytes: ...
+ @type_function
def count( # type: ignore[override]
self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /
) -> int: ...
+ @type_function
def decode(self, encoding: str = "utf-8", errors: str = "strict") -> str: ...
+ @type_function
def endswith(
self,
suffix: ReadableBuffer | tuple[ReadableBuffer, ...],
@@ -545,44 +709,69 @@ class bytes(Sequence[int]):
end: SupportsIndex | None = ...,
/,
) -> bool: ...
+ @type_function
def expandtabs(self, tabsize: SupportsIndex = 8) -> bytes: ...
+ @type_function
def find(
self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /
) -> int: ...
+ @type_function
def hex(self, sep: str | bytes = ..., bytes_per_sep: SupportsIndex = ...) -> str: ...
+ @type_function
def index( # type: ignore[override]
self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /
) -> int: ...
+ @type_function
def isalnum(self) -> bool: ...
+ @type_function
def isalpha(self) -> bool: ...
+ @type_function
def isascii(self) -> bool: ...
+ @type_function
def isdigit(self) -> bool: ...
+ @type_function
def islower(self) -> bool: ...
+ @type_function
def isspace(self) -> bool: ...
+ @type_function
def istitle(self) -> bool: ...
+ @type_function
def isupper(self) -> bool: ...
+ @type_function
def join(self, iterable_of_bytes: Iterable[ReadableBuffer], /) -> bytes: ...
+ @type_function
def ljust(self, width: SupportsIndex, fillchar: bytes | bytearray = b" ", /) -> bytes: ...
+ @type_function
def lower(self) -> bytes: ...
+ @type_function
def lstrip(self, bytes: ReadableBuffer | None = None, /) -> bytes: ...
+ @type_function
def partition(self, sep: ReadableBuffer, /) -> tuple[bytes, bytes, bytes]: ...
+ @type_function
def replace(self, old: ReadableBuffer, new: ReadableBuffer, count: SupportsIndex = -1, /) -> bytes: ...
if sys.version_info >= (3, 9):
+ @type_function
def removeprefix(self, prefix: ReadableBuffer, /) -> bytes: ...
+ @type_function
def removesuffix(self, suffix: ReadableBuffer, /) -> bytes: ...
+ @type_function
def rfind(
self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /
) -> int: ...
+ @type_function
def rindex(
self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /
) -> int: ...
+ @type_function
def rjust(self, width: SupportsIndex, fillchar: bytes | bytearray = b" ", /) -> bytes: ...
+ @type_function
def rpartition(self, sep: ReadableBuffer, /) -> tuple[bytes, bytes, bytes]: ...
def rsplit(self, sep: ReadableBuffer | None = None, maxsplit: SupportsIndex = -1) -> list[bytes]: ...
def rstrip(self, bytes: ReadableBuffer | None = None, /) -> bytes: ...
def split(self, sep: ReadableBuffer | None = None, maxsplit: SupportsIndex = -1) -> list[bytes]: ...
def splitlines(self, keepends: bool = False) -> list[bytes]: ...
+ @type_function
def startswith(
self,
prefix: ReadableBuffer | tuple[ReadableBuffer, ...],
@@ -590,37 +779,62 @@ class bytes(Sequence[int]):
end: SupportsIndex | None = ...,
/,
) -> bool: ...
+ @type_function
def strip(self, bytes: ReadableBuffer | None = None, /) -> bytes: ...
+ @type_function
def swapcase(self) -> bytes: ...
+ @type_function
def title(self) -> bytes: ...
+ @type_function
def translate(self, table: ReadableBuffer | None, /, delete: bytes = b"") -> bytes: ...
+ @type_function
def upper(self) -> bytes: ...
+ @type_function
def zfill(self, width: SupportsIndex, /) -> bytes: ...
@classmethod
+ @type_function
def fromhex(cls, string: str, /) -> Self: ...
@staticmethod
+ @type_function
def maketrans(frm: ReadableBuffer, to: ReadableBuffer, /) -> bytes: ...
+ @type_function
def __len__(self) -> int: ...
def __iter__(self) -> Iterator[int]: ...
+ @type_function
def __hash__(self) -> int: ...
@overload
+ @type_function
def __getitem__(self, key: SupportsIndex, /) -> int: ...
@overload
+ @type_function
def __getitem__(self, key: slice, /) -> bytes: ...
+ @type_function
def __add__(self, value: ReadableBuffer, /) -> bytes: ...
+ @type_function
def __mul__(self, value: SupportsIndex, /) -> bytes: ...
+ @type_function
def __rmul__(self, value: SupportsIndex, /) -> bytes: ...
+ @type_function
def __mod__(self, value: Any, /) -> bytes: ...
# Incompatible with Sequence.__contains__
+ @type_function
def __contains__(self, key: SupportsIndex | ReadableBuffer, /) -> bool: ... # type: ignore[override]
+ @type_function
def __eq__(self, value: object, /) -> bool: ...
+ @type_function
def __ne__(self, value: object, /) -> bool: ...
+ @type_function
def __lt__(self, value: bytes, /) -> bool: ...
+ @type_function
def __le__(self, value: bytes, /) -> bool: ...
+ @type_function
def __gt__(self, value: bytes, /) -> bool: ...
+ @type_function
def __ge__(self, value: bytes, /) -> bool: ...
def __getnewargs__(self) -> tuple[bytes]: ...
+ def __bool__(self) -> bool: ...
if sys.version_info >= (3, 11):
+ @type_function
def __bytes__(self) -> bytes: ...
def __buffer__(self, flags: int, /) -> memoryview: ...
@@ -1853,10 +2067,9 @@ def __import__(
@_as_builtin
def __build_class__(func: Callable[[], CellType | Any], name: str, /, *bases: Any, metaclass: Any = ..., **kwds: Any) -> Any: ...
-# the type of Ellipsis is , but since it's
-# not exposed anywhere under that name, we make it private here.
+
@final
-@type_check_only
+@type_check_only # this symbol is not publicly accessible
class ellipsis: ...
Ellipsis: ellipsis
diff --git a/mypy/valuetotype.py b/mypy/valuetotype.py
new file mode 100644
index 000000000..4662368f3
--- /dev/null
+++ b/mypy/valuetotype.py
@@ -0,0 +1,58 @@
+"""Translate an Expression to a Type value."""
+
+from __future__ import annotations
+
+import builtins
+
+from mypy import checker
+from mypy.types import (
+ FunctionLike,
+ Instance,
+ LiteralType,
+ LiteralValue,
+ NoneType,
+ TupleType,
+ Type,
+ TypeType,
+ UninhabitedType,
+)
+
+
+def value_to_type(value: object, chk: checker.TypeChecker):
+ if isinstance(value, tuple):
+ return TupleType([value_to_type(item) for item in value], fallback=chk.named_type('builtins.tuple'))
+ if isinstance(value, (int, str, float, complex)):
+ type_value = value.__class__
+ return (
+ LiteralType(
+ value,
+ chk.named_type(
+ f"{type_value.__module__}.{type_value.__name__}"
+ ),
+ )
+ )
+ if isinstance(value, type):
+ # TODO: should this be Instance?
+ return TypeType(chk.named_type(f"{value.__module__}.{value.__qualname__}"))
+ if value is None:
+ return NoneType()
+ if value is NotImplemented:
+ return UninhabitedType()
+ typ = value.__class__
+ return chk.named_type(f"{typ.__module__}.{typ.__qualname__}")
+
+def type_to_value(typ: Type, chk: checker.TypeChecker) -> object:
+ # TODO: type args
+ if isinstance(typ, Instance):
+ if typ.last_known_value:
+ return typ.last_known_value.value
+ elif typ.type.fullname.startswith("builtins."):
+ return eval(typ.type.fullname, {"builtins": builtins})
+ elif isinstance(typ, TypeType) or isinstance(typ, FunctionLike) and typ.fallback.type.fullname == "builtins.type":
+ return type
+ elif isinstance(typ, NoneType):
+ return None
+ elif isinstance(typ, LiteralType):
+ return typ.value
+ else:
+ return object
diff --git a/test-data/unit/check-based-assignment.test b/test-data/unit/check-based-assignment.test
new file mode 100644
index 000000000..cadbaad46
--- /dev/null
+++ b/test-data/unit/check-based-assignment.test
@@ -0,0 +1,17 @@
+[case testNarrowToLiteral]
+a = "a"
+reveal_type(a) # Revealed type is "'a'" (narrowed from "str")
+a = "b"
+reveal_type(a) # Revealed type is "'b'" (narrowed from "str")
+b = a
+reveal_type(b) # Revealed type is "'b'" (narrowed from "str")
+b = "c"
+reveal_type(b) # Revealed type is "'c'" (narrowed from "str")
+
+
+[case testNarrowToLiteralGeneric]
+from helper import T
+def f(t: T) -> T: ...
+
+a = f(1)
+reveal_type(a) # revealed type is "1" (narrowed from "int")
diff --git a/test-data/unit/check-based-bare-literals.test b/test-data/unit/check-based-bare-literals.test
index bd61c0cb5..9f0518ead 100644
--- a/test-data/unit/check-based-bare-literals.test
+++ b/test-data/unit/check-based-bare-literals.test
@@ -18,14 +18,21 @@ reveal_type(c) # N: Revealed type is "False"
c2: False | str
reveal_type(c2) # N: Revealed type is "False | str"
-d: 1.1 # E: Invalid type: float literals cannot be used as a type [valid-type]
-d2: 1.1 | str # E: Invalid type: float literals cannot be used as a type [valid-type]
-
-e: 1j # E: Invalid type: complex literals cannot be used as a type [valid-type]
-e2: 1j | str # E: Invalid type: complex literals cannot be used as a type [valid-type]
+d: 1.1
+reveal_type(d) # N: Revealed type is "1.1"
+d2: 1.1 | str
+reveal_type(d2) # N: Revealed type is "1.1 | str"
[builtins fixtures/tuple.pyi]
+[case testBareLiteralLiteralsComplex]
+e: 1j
+reveal_type(e) # N: Revealed type is "1j"
+e2: 1j | str
+reveal_type(e2) # N: Revealed type is "1j | str"
+[builtins fixtures/dict.pyi]
+
+
[case testNoBareLiteralLiterals]
# flags: --python-version 3.10
@@ -109,3 +116,7 @@ import a
from typing import TypeVar
T = TypeVar("T", 1, 2)
a: 1 | 2
+
+
+[case testBareLiteralComplex-writescache]
+a: 1j
diff --git a/test-data/unit/check-based-inference.test b/test-data/unit/check-based-inference.test
new file mode 100644
index 000000000..ea92df9c2
--- /dev/null
+++ b/test-data/unit/check-based-inference.test
@@ -0,0 +1,26 @@
+[case testInferLiteralGeneric]
+from helper import T
+def f(t: T) -> T: ...
+
+reveal_type(f(1)) # N: Revealed type is "1"
+
+
+[case testDontInferLiteralGenericAssignment]
+from helper import T
+def f(t: T) -> T: ...
+
+a = f(1)
+reveal_type(a) # N: Revealed type is "int"
+
+
+[case testDontInferLiteralGenericClass]
+from helper import T
+
+class A(Generic[T]):
+ def __init__(self, t: T): ...
+
+def f(t: T) -> A[T]: ...
+
+reveal_type(f(1)) # N: Revealed type is "A[int]"
+a = f(1)
+reveal_type(a) # N: Revealed type is "A[int]"
diff --git a/test-data/unit/check-based-misc.test b/test-data/unit/check-based-misc.test
index 6f5216b68..3d1b96833 100644
--- a/test-data/unit/check-based-misc.test
+++ b/test-data/unit/check-based-misc.test
@@ -25,7 +25,7 @@ main:3:5:3:31: error: Unused "type: ignore" comment [unused-ignore]
[case testNarrowOnInitialAssignment]
a: object = 1
-reveal_type(a) # N: Revealed type is "int" (narrowed from "object")
+reveal_type(a) # N: Revealed type is "1" (narrowed from "object")
[case testNarrowWithAny]
@@ -35,7 +35,7 @@ from typing import Any, Union
a: Union[int, Any]
if bool():
a = 1
- reveal_type(a) # N: Revealed type is "int" (narrowed from "int | Any")
+ reveal_type(a) # N: Revealed type is "1" (narrowed from "int | Any")
b: Any = 1
reveal_type(b) # N: Revealed type is "Any"
c: Any
@@ -199,7 +199,7 @@ a = False
b: object
if a:
b = 1
-reveal_type(b) # N: Revealed type is "int" (narrowed from "object")
+reveal_type(b) # N: Revealed type is "1" (narrowed from "object")
[case testRedundantExprOnWhileTrue]
diff --git a/test-data/unit/check-based-type-function.test b/test-data/unit/check-based-type-function.test
new file mode 100644
index 000000000..d9ebd3fb0
--- /dev/null
+++ b/test-data/unit/check-based-type-function.test
@@ -0,0 +1,56 @@
+[case typeFunctionAsFunction]
+from basedtyping import type_function
+@type_function
+def f(s: str) -> str:
+ return "a"
+
+reveal_type(f("b")) # Revealed type is "'a'"
+
+
+[case typeFunctionMethod]
+def f(i: int):
+ reveal_type(i + 1) # N: Revealed type is "2"
+ reveal_type(1 + i) # N: Revealed type is "2"
+ reveal_type(i + i) # N: Revealed type is "2"
+
+[file builtins.py]
+from basedtyping import type_function
+class int:
+ @type_function
+ def m(self, other: "int") -> "int":
+ return self + 1
+
+class dict: ...
+
+
+[case typeFunctionReportError]
+from basedtyping import type_function, TypeFunctionError
+
+@type_function
+def F(o: bool):
+ if o is True:
+ raise TypeFunctionError("this is an error", "the-code")
+
+F(True) # E: this is an error [the-code]
+F(False)
+
+def main():
+ F(False)
+ reveal_type(F(True)) # E: this is an error [the-code] \
+ # N: Revealed type is "Never"
+[builtins fixtures/exception.pyi]
+
+
+[case typeFunctionReportRaises]
+from basedtyping import type_function
+
+@type_function
+def F(o: bool):
+ if o is True:
+ raise TypeError("this is an error")
+
+def main():
+ F(False)
+ reveal_type(F(True)) # E: Invocation raises TypeError: this is an error [call-raises] \
+ # N: Revealed type is "Never"
+[builtins fixtures/exception.pyi]
diff --git a/test-data/unit/check-based-type-render.test b/test-data/unit/check-based-type-render.test
index 5ffb19cc5..915edcab5 100644
--- a/test-data/unit/check-based-type-render.test
+++ b/test-data/unit/check-based-type-render.test
@@ -97,7 +97,7 @@ a = 1 # E: Incompatible types in assignment (expression has type "int", variabl
[case testNarrowedFrom]
a: object
a = 1
-reveal_type(a) # N: Revealed type is "int" (narrowed from "object")
+reveal_type(a) # N: Revealed type is "1" (narrowed from "object")
[case testNarrowedFromClass]
diff --git a/test-data/unit/check-based-typevar.test b/test-data/unit/check-based-typevar.test
index fe7073c4d..6cf381f6d 100644
--- a/test-data/unit/check-based-typevar.test
+++ b/test-data/unit/check-based-typevar.test
@@ -51,3 +51,39 @@ class A(Generic[T]): ...
a = A[Any]() # E: Expression type contains "Any" (has type "A[Any]") [no-any-expr]
[builtins fixtures/tuple.pyi]
+
+
+[case testInferLiteralGeneric]
+def f0[T](t: T) -> T:
+ return t
+
+
+reveal_type(f0(17)) # N: Revealed type is "17"
+
+
+def f1[T](t: T) -> (list[T],):
+ return ([t],)
+
+
+reveal_type(f1(17)) # N: Revealed type is "(list[int])"
+
+
+def f2[T](t: T) -> (T,):
+ return (t,)
+
+
+reveal_type(f2(17)) # N: Revealed type is "(17)"
+
+
+def f3[T](t: T) -> list[T]:
+ return [t]
+
+
+reveal_type(f3(17)) # N: Revealed type is "list[int]"
+
+
+def f4[T](t: T) -> (T, list[T]):
+ return [t]
+
+# maybe this should be: (int, list[int])
+reveal_type(f4(17)) # N: Revealed type is "(1, list[int])"
diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test
index 761152131..ad7e348ca 100644
--- a/test-data/unit/check-classes.test
+++ b/test-data/unit/check-classes.test
@@ -1636,7 +1636,7 @@ a.f = a.f
a.f.x # E: "int" has no attribute "x"
a.f = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
a.f = 1
-reveal_type(a.f) # N: Revealed type is "builtins.int"
+reveal_type(a.f) # N: Revealed type is "Literal[1]?"
[builtins fixtures/property.pyi]
[case testPropertyWithDeleterButNoSetter]
diff --git a/test-data/unit/check-columns.test b/test-data/unit/check-columns.test
index 2baf9b6f9..0bd48243d 100644
--- a/test-data/unit/check-columns.test
+++ b/test-data/unit/check-columns.test
@@ -282,7 +282,7 @@ if int():
[case testColumnRedundantCast]
# flags: --warn-redundant-casts
from typing import cast
-y = 1
+y: int
x = cast(int, y) # E:5: Redundant cast to "int"
[case testColumnTypeSignatureHasTooFewArguments]
diff --git a/test-data/unit/check-custom-plugin.test b/test-data/unit/check-custom-plugin.test
index 0e8052369..5b2991071 100644
--- a/test-data/unit/check-custom-plugin.test
+++ b/test-data/unit/check-custom-plugin.test
@@ -901,8 +901,8 @@ plugins=/test-data/unit/plugins/descriptor.py
def dynamic_signature(arg1: str) -> str: ...
a: int = 1
-reveal_type(dynamic_signature(a)) # N: Revealed type is "builtins.int"
-b: bytes = b'foo'
+reveal_type(dynamic_signature(a)) # N: Revealed type is "Literal[1]?"
+b: bytes
reveal_type(dynamic_signature(b)) # N: Revealed type is "builtins.bytes"
[file mypy.ini]
\[mypy]
diff --git a/test-data/unit/check-enum.test b/test-data/unit/check-enum.test
index e801ce2a4..95909b93c 100644
--- a/test-data/unit/check-enum.test
+++ b/test-data/unit/check-enum.test
@@ -1363,9 +1363,12 @@ class Foo(Enum):
A = 1
B = 2
-a = Foo.A
+a: Foo
reveal_type(a.value) # N: Revealed type is "Union[Literal[1]?, Literal[2]?]"
reveal_type(a._value_) # N: Revealed type is "Union[Literal[1]?, Literal[2]?]"
+a = Foo.A
+reveal_type(a.value) # N: Revealed type is "Literal[1]?"
+reveal_type(a._value_) # N: Revealed type is "Literal[1]?"
[builtins fixtures/enum.pyi]
[case testNewSetsUnexpectedValueType]
diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test
index cee8ee5da..1ac81760e 100644
--- a/test-data/unit/check-errorcodes.test
+++ b/test-data/unit/check-errorcodes.test
@@ -1133,7 +1133,7 @@ def unsafe_func(x: object) -> Union[int, str]:
[case testUnimportedRevealType]
# flags: --enable-error-code=unimported-reveal
-x = 1
+x: int
reveal_type(x)
[out]
main:3: error: Name "reveal_type" is not defined [unimported-reveal]
@@ -1143,7 +1143,7 @@ main:3: note: Revealed type is "builtins.int"
[case testUnimportedRevealTypePy311]
# flags: --enable-error-code=unimported-reveal --python-version=3.11
-x = 1
+x: int
reveal_type(x)
[out]
main:3: error: Name "reveal_type" is not defined [unimported-reveal]
@@ -1166,14 +1166,14 @@ main:4: note: 'reveal_type' always outputs 'Any' in unchecked functions
[case testUnimportedRevealTypeImportedTypingExtensions]
# flags: --enable-error-code=unimported-reveal
from typing_extensions import reveal_type
-x = 1
+x: int
reveal_type(x) # N: Revealed type is "builtins.int"
[builtins fixtures/isinstancelist.pyi]
[case testUnimportedRevealTypeImportedTyping311]
# flags: --enable-error-code=unimported-reveal --python-version=3.11
from typing import reveal_type
-x = 1
+x: int
reveal_type(x) # N: Revealed type is "builtins.int"
[builtins fixtures/isinstancelist.pyi]
[typing fixtures/typing-full.pyi]
diff --git a/test-data/unit/check-expressions.test b/test-data/unit/check-expressions.test
index baac06425..5e6a34279 100644
--- a/test-data/unit/check-expressions.test
+++ b/test-data/unit/check-expressions.test
@@ -987,7 +987,7 @@ main:4: error: "A" not callable
[case testAssertType]
from typing import assert_type, Any
from typing_extensions import Literal
-a: int = 1
+a: int
returned = assert_type(a, int)
reveal_type(returned) # N: Revealed type is "builtins.int"
assert_type(a, str) # E: Expression is of type "int", not "str"
@@ -1002,7 +1002,7 @@ from typing import assert_type, TypeVar, Generic
from typing_extensions import Literal
T = TypeVar("T")
def f(x: T) -> T: return x
-assert_type(f(1), int)
+assert_type(f(1), Literal[1])
class Gen(Generic[T]):
def __new__(cls, obj: T) -> Gen[T]: ...
assert_type(Gen(1), Gen[int])
@@ -1839,14 +1839,14 @@ def f():
x = 42
reveal_type(x)
[out]
-main:4: note: Revealed type is "builtins.int"
+main:4: note: Revealed type is "Literal[42]?"
[case testRevealTypedDef]
def f() -> None:
x = 42
reveal_type(x)
[out]
-main:3: note: Revealed type is "builtins.int"
+main:3: note: Revealed type is "Literal[42]?"
[case testLambdaTypedContext]
def f() -> None:
diff --git a/test-data/unit/check-flags.test b/test-data/unit/check-flags.test
index f1c35ee40..ff79f2533 100644
--- a/test-data/unit/check-flags.test
+++ b/test-data/unit/check-flags.test
@@ -1671,8 +1671,8 @@ strict = false
[case testStrictAndStrictEquality]
-- maybe a little useless because theres no strict but w/e
# flags: --strict-equality
-x = 0
-y = ''
+x: int
+y: str
if x == y: # E: Non-overlapping equality check (left operand type: "int", right operand type: "str")
int()
[builtins fixtures/ops.pyi]
@@ -2212,7 +2212,7 @@ bad_return_type('no args taken!')
def f(x):
pass
-y = 1
+y: int
f(reveal_type(y)) # E: Call to untyped function "f" in typed context \
# N: Revealed type is "builtins.int"
diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test
index c15265345..33f31b7cf 100644
--- a/test-data/unit/check-functions.test
+++ b/test-data/unit/check-functions.test
@@ -1575,7 +1575,7 @@ f = g
if g():
def f(): pass
f()
-f(1) # E: Too many arguments
+f(1) # E: Too many arguments for "g"
[case testRedefineFunctionDefinedAsVariableInitializedToNone]
def g(): pass
diff --git a/test-data/unit/check-functools.test b/test-data/unit/check-functools.test
index c331029dd..85de33938 100644
--- a/test-data/unit/check-functools.test
+++ b/test-data/unit/check-functools.test
@@ -248,8 +248,8 @@ reveal_type(p2("a")) # N: Revealed type is "builtins.str"
def bar(a: T, b: U) -> U: ...
p3 = functools.partial(bar, 1)
-reveal_type(p3(2)) # N: Revealed type is "builtins.int"
-reveal_type(p3("a")) # N: Revealed type is "builtins.str"
+reveal_type(p3(2)) # N: Revealed type is "Literal[2]?"
+reveal_type(p3("a")) # N: Revealed type is "Literal['a']?"
[builtins fixtures/dict.pyi]
[case testFunctoolsPartialCallable]
diff --git a/test-data/unit/check-generics.test b/test-data/unit/check-generics.test
index 043428bb4..8e0f8901f 100644
--- a/test-data/unit/check-generics.test
+++ b/test-data/unit/check-generics.test
@@ -833,13 +833,13 @@ def f1(x: T) -> SameTP[T]:
a, b, c = f1(1) # E: Need more than 2 values to unpack (3 expected)
x, y = f1(1)
-reveal_type(x) # N: Revealed type is "builtins.int"
+reveal_type(x) # N: Revealed type is "Literal[1]?"
def f2(x: IntTP[T]) -> IntTP[T]:
return x
f2((1, 2, 3)) # E: Argument 1 to "f2" has incompatible type "Tuple[int, int, int]"; expected "Tuple[int, Never]"
-reveal_type(f2((1, 'x'))) # N: Revealed type is "Tuple[builtins.int, builtins.str]"
+reveal_type(f2((1, 'x'))) # N: Revealed type is "Tuple[builtins.int, Literal['x']?]"
[builtins fixtures/for.pyi]
@@ -2750,7 +2750,7 @@ T= TypeVar("T")
def func(var: T) -> T:
return var
-reveal_type(func(1)) # N: Revealed type is "builtins.int"
+reveal_type(func(1)) # N: Revealed type is "Literal[1]?"
[builtins fixtures/tuple.pyi]
@@ -3480,7 +3480,7 @@ def fake_partial(fun: Callable[[A1, A2], R], arg: A1) -> Callable[[A2], R]: ...
f_pid = fake_partial(apply, id)
reveal_type(f_pid) # N: Revealed type is "def [A2] (A2`2) -> A2`2"
-reveal_type(f_pid(1)) # N: Revealed type is "builtins.int"
+reveal_type(f_pid(1)) # N: Revealed type is "Literal[1]?"
[case testInvalidTypeVarParametersConcrete]
from typing import Callable, Generic, ParamSpec, Protocol, TypeVar, overload
diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test
index f3cf83e6e..58732f61a 100644
--- a/test-data/unit/check-incremental.test
+++ b/test-data/unit/check-incremental.test
@@ -1176,10 +1176,10 @@ reveal_type(foo)
[rechecked m, n]
[stale]
[out1]
-tmp/n.py:2: note: Revealed type is "builtins.str"
+tmp/n.py:2: note: Revealed type is "Literal['hello']?"
tmp/m.py:3: error: Argument 1 to "accept_int" has incompatible type "str"; expected "int"
[out2]
-tmp/n.py:2: note: Revealed type is "builtins.float"
+tmp/n.py:2: note: Revealed type is "Literal[3.14]?"
tmp/m.py:3: error: Argument 1 to "accept_int" has incompatible type "float"; expected "int"
[case testIncrementalReplacingImports]
diff --git a/test-data/unit/check-inference-context.test b/test-data/unit/check-inference-context.test
index a16b61817..5b2f333bf 100644
--- a/test-data/unit/check-inference-context.test
+++ b/test-data/unit/check-inference-context.test
@@ -920,7 +920,7 @@ from typing import TypeVar, Union, List
T = TypeVar('T')
def f(x: Union[T, List[int]]) -> Union[T, List[int]]: pass
-reveal_type(f(1)) # N: Revealed type is "Union[builtins.int, builtins.list[builtins.int]]"
+reveal_type(f(1)) # N: Revealed type is "Union[Literal[1]?, builtins.list[builtins.int]]"
reveal_type(f([])) # N: Revealed type is "builtins.list[builtins.int]"
reveal_type(f(None)) # N: Revealed type is "Union[None, builtins.list[builtins.int]]"
[builtins fixtures/list.pyi]
@@ -931,7 +931,7 @@ from typing import TypeVar, Union, List
T = TypeVar('T')
def f(x: Union[T, List[int]]) -> Union[T, List[int]]: pass
-reveal_type(f(1)) # N: Revealed type is "Union[builtins.int, builtins.list[builtins.int]]"
+reveal_type(f(1)) # N: Revealed type is "Union[Literal[1]?, builtins.list[builtins.int]]"
reveal_type(f([])) # N: Revealed type is "builtins.list[builtins.int]"
reveal_type(f(None)) # N: Revealed type is "Union[None, builtins.list[builtins.int]]"
[builtins fixtures/list.pyi]
@@ -946,7 +946,7 @@ class C(Generic[T]):
def f(self, x: Union[T, S]) -> Union[T, S]: pass
c = C[List[int]]()
-reveal_type(c.f('')) # N: Revealed type is "Union[builtins.list[builtins.int], builtins.str]"
+reveal_type(c.f('')) # N: Revealed type is "Union[builtins.list[builtins.int], Literal['']?]"
reveal_type(c.f([1])) # N: Revealed type is "builtins.list[builtins.int]"
reveal_type(c.f([])) # N: Revealed type is "builtins.list[builtins.int]"
reveal_type(c.f(None)) # N: Revealed type is "Union[builtins.list[builtins.int], None]"
diff --git a/test-data/unit/check-inference.test b/test-data/unit/check-inference.test
index 74813ed6e..7a0edc0ad 100644
--- a/test-data/unit/check-inference.test
+++ b/test-data/unit/check-inference.test
@@ -138,7 +138,7 @@ def f() -> None:
import typing
def f() -> None:
a = g
- a(B()) # E: Argument 1 has incompatible type "B"; expected "A"
+ a(B()) # E: Argument 1 to "g" has incompatible type "B"; expected "A"
a(A())
def g(a: 'A') -> None: pass
@@ -151,7 +151,7 @@ class B: pass
import typing
def f() -> None:
a = A
- a(A()) # E: Too many arguments
+ a(A()) # E: Too many arguments for "A"
a()
t = a # type: type
@@ -343,7 +343,7 @@ for var2 in [g, h, i, j, k, l]:
reveal_type(var2) # N: Revealed type is "Union[builtins.int, builtins.str]"
for var3 in [m, n, o, p, q, r]:
- reveal_type(var3) # N: Revealed type is "Union[builtins.int, Any]"
+ reveal_type(var3) # N: Revealed type is "builtins.int"
T = TypeVar("T", bound=Type[Foo])
@@ -2552,8 +2552,8 @@ def make_tuple(elem: T) -> Tuple[T]:
def main() -> None:
((a, b),) = make_tuple((1, 2))
- reveal_type(a) # N: Revealed type is "builtins.int"
- reveal_type(b) # N: Revealed type is "builtins.int"
+ reveal_type(a) # N: Revealed type is "Literal[1]?"
+ reveal_type(b) # N: Revealed type is "Literal[2]?"
[builtins fixtures/tuple.pyi]
[out]
diff --git a/test-data/unit/check-literal.test b/test-data/unit/check-literal.test
index 5c09b5134..e2e0f1bfa 100644
--- a/test-data/unit/check-literal.test
+++ b/test-data/unit/check-literal.test
@@ -1001,14 +1001,14 @@ none2 = None
none3: None = None
reveal_type(int1) # N: Revealed type is "Literal[1]"
-reveal_type(int2) # N: Revealed type is "builtins.int"
-reveal_type(int3) # N: Revealed type is "builtins.int"
+reveal_type(int2) # N: Revealed type is "Literal[1]?"
+reveal_type(int3) # N: Revealed type is "Literal[1]?"
reveal_type(str1) # N: Revealed type is "Literal['foo']"
-reveal_type(str2) # N: Revealed type is "builtins.str"
-reveal_type(str3) # N: Revealed type is "builtins.str"
+reveal_type(str2) # N: Revealed type is "Literal['foo']?"
+reveal_type(str3) # N: Revealed type is "Literal['foo']?"
reveal_type(bool1) # N: Revealed type is "Literal[True]"
-reveal_type(bool2) # N: Revealed type is "builtins.bool"
-reveal_type(bool3) # N: Revealed type is "builtins.bool"
+reveal_type(bool2) # N: Revealed type is "Literal[True]?"
+reveal_type(bool3) # N: Revealed type is "Literal[True]?"
reveal_type(none1) # N: Revealed type is "None"
reveal_type(none2) # N: Revealed type is "None"
reveal_type(none3) # N: Revealed type is "None"
@@ -1029,14 +1029,14 @@ b = "foo"
c = True
d = None
-w = a # E: Incompatible types in assignment (expression has type "int", variable has type "Literal[1]")
-x = b # E: Incompatible types in assignment (expression has type "str", variable has type "Literal['foo']")
-y = c # E: Incompatible types in assignment (expression has type "bool", variable has type "Literal[True]")
+w = a
+x = b
+y = c
z = d # This is ok: Literal[None] and None are equivalent.
-combined = a # E: Incompatible types in assignment (expression has type "int", variable has type "Optional[Literal[1, 'foo', True]]")
-combined = b # E: Incompatible types in assignment (expression has type "str", variable has type "Optional[Literal[1, 'foo', True]]")
-combined = c # E: Incompatible types in assignment (expression has type "bool", variable has type "Optional[Literal[1, 'foo', True]]")
+combined = a
+combined = b
+combined = c
combined = d # Also ok, for similar reasons.
e: Literal[1] = 1
@@ -1345,7 +1345,7 @@ def f1(x: T, y: str) -> Union[T, str]: ...
def f1(x, y): pass
a: Literal[1]
-reveal_type(f1(1, 1)) # N: Revealed type is "builtins.int"
+reveal_type(f1(1, 1)) # N: Revealed type is "Literal[1]?"
reveal_type(f1(a, 1)) # N: Revealed type is "Literal[1]"
@overload
@@ -1354,7 +1354,7 @@ def f2(x: T, y: Literal[3]) -> T: ...
def f2(x: T, y: str) -> Union[T]: ...
def f2(x, y): pass
-reveal_type(f2(1, 3)) # N: Revealed type is "builtins.int"
+reveal_type(f2(1, 3)) # N: Revealed type is "Literal[1]?"
reveal_type(f2(a, 3)) # N: Revealed type is "Literal[1]"
@overload
@@ -1363,7 +1363,7 @@ def f3(x: Literal[3]) -> Literal[3]: ...
def f3(x: T) -> T: ...
def f3(x): pass
-reveal_type(f3(1)) # N: Revealed type is "builtins.int"
+reveal_type(f3(1)) # N: Revealed type is "Literal[1]?"
reveal_type(f3(a)) # N: Revealed type is "Literal[1]"
@overload
@@ -1373,7 +1373,7 @@ def f4(x: T) -> T: ...
def f4(x): pass
b: Literal['foo']
-reveal_type(f4(1)) # N: Revealed type is "builtins.int"
+reveal_type(f4(1)) # N: Revealed type is "Literal[1]?"
reveal_type(f4(a)) # N: Revealed type is "Literal[1]"
reveal_type(f4("foo")) # N: Revealed type is "builtins.str"
@@ -1551,7 +1551,7 @@ def expects_literal(x: Literal[3]) -> None: pass
def expects_int(x: int) -> None: pass
a: Literal[3]
-reveal_type(foo(3)) # N: Revealed type is "builtins.int"
+reveal_type(foo(3)) # N: Revealed type is "Literal[3]?"
reveal_type(foo(a)) # N: Revealed type is "Literal[3]"
expects_literal(3)
@@ -1670,9 +1670,9 @@ reveal_type(func1(b)) # E: Value of type variable "TLiteral" of "func1" cannot
reveal_type(func1(c)) # E: Value of type variable "TLiteral" of "func1" cannot be "int" \
# N: Revealed type is "builtins.int"
-reveal_type(func2(3)) # N: Revealed type is "builtins.int"
+reveal_type(func2(3)) # N: Revealed type is "Literal[3]?"
reveal_type(func2(a)) # N: Revealed type is "Literal[3]"
-reveal_type(func2(4)) # N: Revealed type is "builtins.int"
+reveal_type(func2(4)) # N: Revealed type is "Literal[4]?"
reveal_type(func2(b)) # N: Revealed type is "Literal[4]"
reveal_type(func2(c)) # N: Revealed type is "builtins.int"
[builtins fixtures/tuple.pyi]
@@ -2464,7 +2464,7 @@ c = a
def expect_3(x: Literal[3]) -> None: pass
expect_3(a)
expect_3(b)
-expect_3(c) # E: Argument 1 to "expect_3" has incompatible type "int"; expected "Literal[3]"
+expect_3(c)
[builtins fixtures/tuple.pyi]
[out]
@@ -2682,12 +2682,12 @@ expects_test1_foo(Test2.FOO) # E: Argument 1 to "expects_test1_foo" has incompa
expects_test2_foo(Test1.FOO) # E: Argument 1 to "expects_test2_foo" has incompatible type "Literal[Test1.FOO]"; expected "Literal[Test2.FOO]"
# Make sure enums follow the same semantics as 'x = 1' vs 'x: Final = 1'
-var1 = Test1.FOO
+var1: Test1
final1: Final = Test1.FOO
expects_test1_foo(var1) # E: Argument 1 to "expects_test1_foo" has incompatible type "Test1"; expected "Literal[Test1.FOO]"
expects_test1_foo(final1)
-var2 = Test2.FOO
+var2: Test2
final2: Final = Test2.FOO
expects_test2_foo(var2) # E: Argument 1 to "expects_test2_foo" has incompatible type "Test2"; expected "Literal[Test2.FOO]"
expects_test2_foo(final2)
@@ -2728,19 +2728,19 @@ reveal_type(Test5.FOO.name) # N: Revealed type is "Literal['FOO']?"
[builtins fixtures/tuple.pyi]
[out]
-[case testLiteralBinderLastValueErased]
-# mypy: strict-equality
-
-from typing_extensions import Literal
-
-def takes_three(x: Literal[3]) -> None: ...
-x: object
-x = 3
-
-takes_three(x) # E: Argument 1 to "takes_three" has incompatible type "int"; expected "Literal[3]"
-if x == 2: # OK
- ...
-[builtins fixtures/bool.pyi]
+# [case testLiteralBinderLastValueErased]
+# # mypy: strict-equality
+#
+# from typing_extensions import Literal
+#
+# def takes_three(x: Literal[3]) -> None: ...
+# x: object
+# x = 3
+#
+# takes_three(x) # E: Argument 1 to "takes_three" has incompatible type "int"; expected "Literal[3]"
+# if x == 2: # OK
+# ...
+# [builtins fixtures/bool.pyi]
[case testLiteralBinderLastValueErasedPartialTypes]
# mypy: strict-equality
diff --git a/test-data/unit/check-modules.test b/test-data/unit/check-modules.test
index 7fbdfbf4d..759ff47ea 100644
--- a/test-data/unit/check-modules.test
+++ b/test-data/unit/check-modules.test
@@ -1990,7 +1990,7 @@ x = 42
[case testModuleAliasToQualifiedImport]
import package.module
alias = package.module
-reveal_type(alias.whatever('/')) # N: Revealed type is "builtins.str"
+reveal_type(alias.whatever('/')) # N: Revealed type is "Literal['/']?"
[file package/__init__.py]
[file package/module.py]
@@ -2003,7 +2003,7 @@ def whatever(x: T) -> T: pass
import mod
import othermod
alias = mod.submod
-reveal_type(alias.whatever('/')) # N: Revealed type is "builtins.str"
+reveal_type(alias.whatever('/')) # N: Revealed type is "Literal['/']?"
if int():
alias = othermod # E: Cannot assign multiple modules to name "alias" without explicit "types.ModuleType" annotation
[file mod.py]
diff --git a/test-data/unit/check-newsemanal.test b/test-data/unit/check-newsemanal.test
index 5d283d50b..8c93833d7 100644
--- a/test-data/unit/check-newsemanal.test
+++ b/test-data/unit/check-newsemanal.test
@@ -284,7 +284,7 @@ import a
MYPY = False
if MYPY:
from b import x as y
-x = 0
+x: int
def y(): pass # E: Name "y" already defined on line 4
reveal_type(y) # N: Revealed type is "builtins.int"
@@ -311,7 +311,7 @@ import a
[file a.py]
from b import x as y
-x = 0
+x: int
def y(): pass # E: Name "y" already defined on line 2
reveal_type(y) # N: Revealed type is "builtins.int"
diff --git a/test-data/unit/check-optional.test b/test-data/unit/check-optional.test
index 91feff357..61d1ad7dc 100644
--- a/test-data/unit/check-optional.test
+++ b/test-data/unit/check-optional.test
@@ -119,7 +119,7 @@ reveal_type(z2) # N: Revealed type is "Union[Literal[0], builtins.str, None]"
[case testLambdaReturningNone]
f = lambda: None
-x = f() # E: Function does not return a value (it only ever returns None)
+x = f() # E: does not return a value (it only ever returns None)
reveal_type(x) # N: Revealed type is "None"
[case testNoneArgumentType]
@@ -609,8 +609,8 @@ reveal_type(u(None, C())) # N: Revealed type is "Union[__main__.C, None]"
reveal_type(u(a, None)) # N: Revealed type is "Union[None, Any]"
reveal_type(u(None, a)) # N: Revealed type is "Union[Any, None]"
-reveal_type(u(1, None)) # N: Revealed type is "Union[None, builtins.int]"
-reveal_type(u(None, 1)) # N: Revealed type is "Union[builtins.int, None]"
+reveal_type(u(1, None)) # N: Revealed type is "Union[None, Literal[1]?]"
+reveal_type(u(None, 1)) # N: Revealed type is "Union[Literal[1]?, None]"
[case testOptionalAndAnyBaseClass]
from typing import Any, Optional
@@ -738,7 +738,7 @@ def g(x: Optional[int]) -> int:
if x is None:
reveal_type(x) # N: Revealed type is "None"
x = 1
- reveal_type(x) # N: Revealed type is "builtins.int"
+ reveal_type(x) # N: Revealed type is "Literal[1]?"
# Since we've assigned to x, the special case None behavior shouldn't happen
x = f()
reveal_type(x) # N: Revealed type is "Union[builtins.int, None]"
@@ -794,11 +794,11 @@ from typing import Any, Optional
def f1(b: bool) -> Optional[int]:
if b:
z = 10
- reveal_type(z) # N: Revealed type is "builtins.int"
+ reveal_type(z) # N: Revealed type is "Literal[10]?"
else:
z = None
reveal_type(z) # N: Revealed type is "None"
- reveal_type(z) # N: Revealed type is "Union[builtins.int, None]"
+ reveal_type(z) # N: Revealed type is "Union[Literal[10]?, None]"
return z
def f2(b: bool) -> int:
@@ -914,7 +914,7 @@ def f16(z: Any) -> None:
break
else:
y = None
- reveal_type(y) # N: Revealed type is "Union[builtins.int, None]"
+ reveal_type(y) # N: Revealed type is "Union[Literal[50]?, None]"
def f17(b: bool, c: bool, d: bool) -> None:
if b:
@@ -933,7 +933,7 @@ def f18(b: bool, c: bool, d: bool) -> None:
z = 5
else:
z = None
- reveal_type(z) # N: Revealed type is "Union[builtins.int, None]"
+ reveal_type(z) # N: Revealed type is "Union[Literal[5]?, None]"
def f19(b: bool, c: bool, d: bool) -> None:
if b:
@@ -942,7 +942,7 @@ def f19(b: bool, c: bool, d: bool) -> None:
z = None
if c:
z = 6
- reveal_type(z) # N: Revealed type is "Union[builtins.int, None]"
+ reveal_type(z) # N: Revealed type is "Union[Literal[6]?, None]"
def f20(b: bool) -> None:
if b:
@@ -1020,13 +1020,13 @@ from typing import Any, Optional
def f1(b: bool) -> Optional[int]:
if b:
z = 10
- reveal_type(z) # N: Revealed type is "builtins.int"
+ reveal_type(z) # N: Revealed type is "Literal[10]?"
else:
# Force the node to get deferred between the two assignments
Defer().defer
z = None
reveal_type(z) # N: Revealed type is "None"
- reveal_type(z) # N: Revealed type is "Union[builtins.int, None]"
+ reveal_type(z) # N: Revealed type is "Union[Literal[10]?, None]"
return z
class Defer:
diff --git a/test-data/unit/check-python312.test b/test-data/unit/check-python312.test
index 8be22c952..03f45068c 100644
--- a/test-data/unit/check-python312.test
+++ b/test-data/unit/check-python312.test
@@ -979,8 +979,8 @@ def g[T: int, S: (str, None)](x: T, y: S) -> T | S:
return x
[out2]
-tmp/a.py:2: note: Revealed type is "builtins.int"
-tmp/a.py:3: note: Revealed type is "Union[builtins.int, builtins.str]"
+tmp/a.py:2: note: Revealed type is "Literal[1]?"
+tmp/a.py:3: note: Revealed type is "Union[Literal[1]?, builtins.str]"
tmp/a.py:4: error: Value of type variable "T" of "g" cannot be "str"
tmp/a.py:5: error: Value of type variable "S" of "g" cannot be "int"
tmp/a.py:5: note: "S" of "g" is a constrained type variable, it is not generic
@@ -1082,23 +1082,23 @@ class C:
reveal_type(y) # N: Revealed type is "T`-1"
return cast(T, y)
-reveal_type(C().m(1)) # N: Revealed type is "builtins.int"
+reveal_type(C().m(1)) # N: Revealed type is "Literal[1]?"
[case testPEP695ScopingBasics]
T = 1
def f[T](x: T) -> T:
T = 'a'
- reveal_type(T) # N: Revealed type is "builtins.str"
+ reveal_type(T) # N: Revealed type is "Literal['a']?"
return x
-reveal_type(T) # N: Revealed type is "builtins.int"
+reveal_type(T) # N: Revealed type is "Literal[1]?"
class C[T]:
T = 1.2
reveal_type(T) # N: Revealed type is "builtins.float"
-reveal_type(T) # N: Revealed type is "builtins.int"
+reveal_type(T) # N: Revealed type is "Literal[1]?"
[case testPEP695ClassScoping]
class C:
@@ -1113,7 +1113,7 @@ C().m(1, C.D()) # E: Value of type variable "T" of "m" of "C" cannot be "int"
[case testPEP695NestedGenericFunction]
def f[T](x: T) -> T:
reveal_type(f(x)) # N: Revealed type is "T`-1"
- reveal_type(f(1)) # N: Revealed type is "builtins.int"
+ reveal_type(f(1)) # N: Revealed type is "Literal[1]?"
def ff(x: T) -> T:
y: T = x
@@ -1124,12 +1124,12 @@ def f[T](x: T) -> T:
def g[S](a: S) -> S:
ff(a) # E: Argument 1 to "ff" has incompatible type "S"; expected "T"
return a
- reveal_type(g(1)) # N: Revealed type is "builtins.int"
+ reveal_type(g(1)) # N: Revealed type is "Literal[1]?"
reveal_type(g(x)) # N: Revealed type is "T`-1"
def h[S](a: S) -> S:
return a
- reveal_type(h(1)) # N: Revealed type is "builtins.int"
+ reveal_type(h(1)) # N: Revealed type is "Literal[1]?"
reveal_type(h(x)) # N: Revealed type is "T`-1"
return x
@@ -1398,8 +1398,8 @@ class C:
class D(C):
pass
-reveal_type(C.m(1)) # N: Revealed type is "Tuple[__main__.C, builtins.int]"
-reveal_type(D.m(1)) # N: Revealed type is "Tuple[__main__.D, builtins.int]"
+reveal_type(C.m(1)) # N: Revealed type is "Tuple[__main__.C, Literal[1]?]"
+reveal_type(D.m(1)) # N: Revealed type is "Tuple[__main__.D, Literal[1]?]"
class E[T]:
def m(self) -> Self:
@@ -1412,9 +1412,9 @@ class F[T](E[T]):
pass
reveal_type(E[int]().m()) # N: Revealed type is "__main__.E[builtins.int]"
-reveal_type(E[int]().mm(b'x')) # N: Revealed type is "Tuple[__main__.E[builtins.int], builtins.bytes]"
+reveal_type(E[int]().mm(b'x')) # N: Revealed type is "Tuple[__main__.E[builtins.int], Literal[b'x']?]"
reveal_type(F[str]().m()) # N: Revealed type is "__main__.F[builtins.str]"
-reveal_type(F[str]().mm(b'x')) # N: Revealed type is "Tuple[__main__.F[builtins.str], builtins.bytes]"
+reveal_type(F[str]().mm(b'x')) # N: Revealed type is "Tuple[__main__.F[builtins.str], Literal[b'x']?]"
[builtins fixtures/tuple.pyi]
[case testPEP695CallAlias]
@@ -1586,7 +1586,7 @@ type C = int # E: Name "C" already defined on line 1
A = 0
type A = str # E: Name "A" already defined on line 4
-reveal_type(A) # N: Revealed type is "builtins.int"
+reveal_type(A) # N: Revealed type is "Literal[0]?"
[case testPEP695RedefineAsTypeAlias2]
from m import D
diff --git a/test-data/unit/check-python38.test b/test-data/unit/check-python38.test
index f0ce96c96..b9e272ae3 100644
--- a/test-data/unit/check-python38.test
+++ b/test-data/unit/check-python38.test
@@ -206,23 +206,24 @@ h(1)
i()
i(1)
f(arg=0) # E: Unexpected keyword argument "arg" for "f"
-g(arg=0) # E: Unexpected keyword argument "arg"
+g(arg=0) # E: Unexpected keyword argument "arg" for
h(arg=0) # E: Unexpected keyword argument "arg" for "h"
-i(arg=0) # E: Unexpected keyword argument "arg"
+i(arg=0) # E: Unexpected keyword argument "arg" for
[case testWalrus]
from typing import NamedTuple, Optional, List
from typing_extensions import Final
if a := 2:
- reveal_type(a) # N: Revealed type is "builtins.int"
+ reveal_type(a) # N: Revealed type is "Literal[2]?"
while b := "x":
- reveal_type(b) # N: Revealed type is "builtins.str"
+ reveal_type(b) # N: Revealed type is "Literal['x']?"
l = [y2 := 1, y2 + 2, y2 + 3]
reveal_type(y2) # N: Revealed type is "builtins.int"
-reveal_type(l) # N: Revealed type is "builtins.list[builtins.int]"
+# TODO: get rid of the `| 3`
+reveal_type(l) # N: Revealed type is "builtins.list[builtins.int | Literal[3]?]"
filtered_data = [y3 for x in l if (y3 := a) is not None]
reveal_type(filtered_data) # N: Revealed type is "builtins.list[builtins.int]"
diff --git a/test-data/unit/check-redefine.test b/test-data/unit/check-redefine.test
index 4a6ea7385..8b677082b 100644
--- a/test-data/unit/check-redefine.test
+++ b/test-data/unit/check-redefine.test
@@ -45,9 +45,9 @@ def f() -> None:
def g() -> None:
x: int
x = 1
- reveal_type(x) # N: Revealed type is "builtins.int"
+ reveal_type(x) # N: Revealed type is "Literal[1]?"
x = ''
- reveal_type(x) # N: Revealed type is "builtins.str"
+ reveal_type(x) # N: Revealed type is "Literal['']?"
[case testRedefineLocalUsingOldValue]
# flags: --allow-redefinition
@@ -297,18 +297,18 @@ def f() -> None:
# flags: --allow-redefinition
def f() -> None:
x = 1
- reveal_type(x) # N: Revealed type is "builtins.int"
+ reveal_type(x) # N: Revealed type is "Literal[1]?"
x: object
reveal_type(x) # N: Revealed type is "builtins.object"
def g() -> None:
x = 1
- reveal_type(x) # N: Revealed type is "builtins.int"
+ reveal_type(x) # N: Revealed type is "Literal[1]?"
x: object
reveal_type(x) # N: Revealed type is "builtins.object"
def h() -> None:
x: int
x = 1
- reveal_type(x) # N: Revealed type is "builtins.int"
+ reveal_type(x) # N: Revealed type is "Literal[1]?"
x: object
x: object = '' # E: Name "x" already defined on line 16
def farg(x: int) -> None:
@@ -340,7 +340,7 @@ class A:
reveal_type(self.x) # N: Revealed type is "builtins.int"
self = f()
self.y: str = ''
- reveal_type(self.y) # N: Revealed type is "builtins.str"
+ reveal_type(self.y) # N: Revealed type is "Literal['']?"
def f() -> A: return A()
@@ -361,9 +361,9 @@ reveal_type(x)
x = ''
reveal_type(x)
[out]
-tmp/m.py:2: note: Revealed type is "builtins.int"
+tmp/m.py:2: note: Revealed type is "Literal[0]?"
tmp/m.py:4: note: Revealed type is "builtins.object"
-tmp/m.py:6: note: Revealed type is "builtins.str"
+tmp/m.py:6: note: Revealed type is "Literal['']?"
main:3: note: Revealed type is "builtins.str"
[case testRedefineGlobalForIndex]
@@ -398,13 +398,13 @@ reveal_type(a) # N: Revealed type is "typing.Iterable[builtins.int]"
[case testRedefineGlobalWithSeparateDeclaration]
# flags: --allow-redefinition
x = ''
-reveal_type(x) # N: Revealed type is "builtins.str"
+reveal_type(x) # N: Revealed type is "Literal['']?"
x: int
x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
reveal_type(x) # N: Revealed type is "builtins.int"
x: object
x = 1
-reveal_type(x) # N: Revealed type is "builtins.int"
+reveal_type(x) # N: Revealed type is "Literal[1]?"
if int():
x = object()
@@ -414,7 +414,7 @@ from typing import Iterable, TypeVar, Union
T = TypeVar('T')
def f(x: T) -> Iterable[Union[T, str]]: pass
x = 0
-reveal_type(x) # N: Revealed type is "builtins.int"
+reveal_type(x) # N: Revealed type is "Literal[0]?"
for x in f(x):
pass
reveal_type(x) # N: Revealed type is "Union[builtins.int, builtins.str]"
@@ -458,13 +458,13 @@ def g() -> None:
[case testRedefineAsException]
# flags: --allow-redefinition
e = 1
-reveal_type(e) # N: Revealed type is "builtins.int"
+reveal_type(e) # N: Revealed type is "Literal[1]?"
try:
pass
except Exception as e:
reveal_type(e) # N: Revealed type is "builtins.Exception"
e = ''
-reveal_type(e) # N: Revealed type is "builtins.str"
+reveal_type(e) # N: Revealed type is "Literal['']?"
[builtins fixtures/exception.pyi]
[case testRedefineUsingWithStatement]
@@ -529,7 +529,7 @@ def f(arg: str) -> str:
from a import g
_ = g
-_('a') # E: Argument 1 has incompatible type "str"; expected "int"
+_('a') # E: Argument 1 to "g" has incompatible type "str"; expected "int"
reveal_type(_(1)) # N: Revealed type is "builtins.int"
[file a.py]
diff --git a/test-data/unit/check-selftype.test b/test-data/unit/check-selftype.test
index b77e773e9..2568b8d76 100644
--- a/test-data/unit/check-selftype.test
+++ b/test-data/unit/check-selftype.test
@@ -1121,7 +1121,7 @@ S = TypeVar('S')
class C(Generic[T]):
def limited(self: C[str], arg: S) -> S: ...
-reveal_type(C[str]().limited(0)) # N: Revealed type is "builtins.int"
+reveal_type(C[str]().limited(0)) # N: Revealed type is "Literal[0]?"
[case testSelfTypeMultipleTypeVars]
from typing import Generic, TypeVar, Tuple
@@ -1647,8 +1647,8 @@ class D(C[int]): ...
c: C[int]
d: D
-reveal_type(c.meth("test")) # N: Revealed type is "Tuple[__main__.C[builtins.int], builtins.str, builtins.int]"
-reveal_type(d.meth("test")) # N: Revealed type is "Tuple[__main__.D, builtins.str, builtins.int]"
+reveal_type(c.meth("test")) # N: Revealed type is "Tuple[__main__.C[builtins.int], Literal['test']?, builtins.int]"
+reveal_type(d.meth("test")) # N: Revealed type is "Tuple[__main__.D, Literal['test']?, builtins.int]"
[builtins fixtures/tuple.pyi]
[case testTypingSelfRecursiveInit]
@@ -1799,7 +1799,7 @@ class C:
def foo(self, x: S) -> Tuple[Self, S]: ...
reveal_type(C.foo) # N: Revealed type is "def [Self <: __main__.C, S] (self: Self`1, x: S`2) -> Tuple[Self`1, S`2]"
-reveal_type(C().foo(42)) # N: Revealed type is "Tuple[__main__.C, builtins.int]"
+reveal_type(C().foo(42)) # N: Revealed type is "Tuple[__main__.C, Literal[42]?]"
[builtins fixtures/tuple.pyi]
[case testTypingSelfTypeVarClashAttr]
@@ -1813,7 +1813,7 @@ class C:
foo: Callable[[S, Self], Tuple[Self, S]]
reveal_type(C().foo) # N: Revealed type is "def [S] (S`1, __main__.C) -> Tuple[__main__.C, S`1]"
-reveal_type(C().foo(42, C())) # N: Revealed type is "Tuple[__main__.C, builtins.int]"
+reveal_type(C().foo(42, C())) # N: Revealed type is "Tuple[__main__.C, Literal[42]?]"
class This: ...
[builtins fixtures/tuple.pyi]
@@ -2083,7 +2083,7 @@ class Partial2:
p: Partial
reveal_type(p()) # N: Revealed type is "Never"
p2: Partial2
-reveal_type(p2(42)) # N: Revealed type is "builtins.int"
+reveal_type(p2(42)) # N: Revealed type is "Literal[42]?"
[case testAccessingSelfClassVarInClassMethod]
from typing import Self, ClassVar, Type, TypeVar
diff --git a/test-data/unit/check-serialize.test b/test-data/unit/check-serialize.test
index 81da94c05..b31341dac 100644
--- a/test-data/unit/check-serialize.test
+++ b/test-data/unit/check-serialize.test
@@ -81,8 +81,8 @@ T = TypeVar('T')
def f(x: T) -> T: return x
[out2]
-tmp/a.py:2: note: Revealed type is "builtins.int"
-tmp/a.py:3: note: Revealed type is "builtins.str"
+tmp/a.py:2: note: Revealed type is "Literal[1]?"
+tmp/a.py:3: note: Revealed type is "Literal['']?"
[case testSerializeFunctionReturningGenericFunction]
import a
@@ -100,7 +100,7 @@ T = TypeVar('T')
def f() -> Callable[[T], T]: pass
[out2]
tmp/a.py:2: note: Revealed type is "def () -> def [T] (T`-1) -> T`-1"
-tmp/a.py:3: note: Revealed type is "builtins.str"
+tmp/a.py:3: note: Revealed type is "Literal['']?"
[case testSerializeArgumentKinds]
import a
diff --git a/test-data/unit/check-statements.test b/test-data/unit/check-statements.test
index 106e4fb70..85f170329 100644
--- a/test-data/unit/check-statements.test
+++ b/test-data/unit/check-statements.test
@@ -2115,11 +2115,11 @@ class B(): pass
main:8: error: Incompatible types in assignment (expression has type "A", variable has type "B")
[case testAugmentedAssignmentIntFloat]
-weight0 = 65.5
+weight0: float
reveal_type(weight0) # N: Revealed type is "builtins.float"
if int():
weight0 = 65
- reveal_type(weight0) # N: Revealed type is "builtins.int"
+ reveal_type(weight0) # N: Revealed type is "Literal[65]?"
weight0 *= 'a' # E: Incompatible types in assignment (expression has type "str", variable has type "float")
weight0 *= 0.5
reveal_type(weight0) # N: Revealed type is "builtins.float"
@@ -2131,10 +2131,10 @@ if int():
[case testAugmentedAssignmentIntFloatMember]
class A:
def __init__(self) -> None:
- self.weight0 = 65.5
+ self.weight0: float
reveal_type(self.weight0) # N: Revealed type is "builtins.float"
self.weight0 = 65
- reveal_type(self.weight0) # N: Revealed type is "builtins.int"
+ reveal_type(self.weight0) # N: Revealed type is "Literal[65]?"
self.weight0 *= 'a' # E: Incompatible types in assignment (expression has type "str", variable has type "float")
self.weight0 *= 0.5
reveal_type(self.weight0) # N: Revealed type is "builtins.float"
diff --git a/test-data/unit/check-tuples.test b/test-data/unit/check-tuples.test
index e3607775b..f1884d997 100644
--- a/test-data/unit/check-tuples.test
+++ b/test-data/unit/check-tuples.test
@@ -317,7 +317,7 @@ a: A
b: B
x: Tuple[A, B, C]
y: Tuple[A, C, E]
-n = 0
+n: int
if int():
a = t1[1] # E: Incompatible types in assignment (expression has type "B", variable has type "A")
@@ -1424,8 +1424,8 @@ f(0) # E: Argument 1 to "f" has incompatible type "int"; expected "Tuple[()]"
[case testNonliteralTupleIndex]
t = (0, "")
-x = 0
-y = ""
+x: int
+y: str
reveal_type(t[x]) # N: Revealed type is "Union[builtins.int, builtins.str]"
t[y] # E: No overload variant of "__getitem__" of "tuple" matches argument type "str" \
# N: Possible overload variants: \
@@ -1436,7 +1436,7 @@ t[y] # E: No overload variant of "__getitem__" of "tuple" matches argument type
[case testNonliteralTupleSlice]
t = (0, "")
-x = 0
+x: int
y = ""
reveal_type(t[x:]) # N: Revealed type is "builtins.tuple[Union[builtins.int, builtins.str], ...]"
t[y:] # E: Slice index must be an integer, SupportsIndex or None
diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test
index baea0e9ac..34bd18093 100644
--- a/test-data/unit/check-typeddict.test
+++ b/test-data/unit/check-typeddict.test
@@ -53,7 +53,7 @@ p = Point(42, 1337) # E: Expected keyword arguments, {...}, or dict(...) in Typ
[case testCannotCreateTypedDictInstanceNonLiteralItemName]
from mypy_extensions import TypedDict
Point = TypedDict('Point', {'x': int, 'y': int})
-x = 'x'
+x: str
p = Point({x: 42, 'y': 1337}) # E: Expected TypedDict key to be string literal
[builtins fixtures/dict.pyi]
@@ -1649,10 +1649,10 @@ reveal_type(a.setdefault('x', 1)) # N: Revealed type is "builtins.int"
reveal_type(a.setdefault('y', [])) # N: Revealed type is "builtins.list[builtins.int]"
a.setdefault('y', '') # E: Argument 2 to "setdefault" of "TypedDict" has incompatible type "str"; expected "List[int]" \
# E: Argument 2 to "setdefault" of "TypedDict" has incompatible type "str"; expected "List[int]"
-x = ''
+x: str
a.setdefault(x, 1) # E: Expected TypedDict key to be string literal
alias = a.setdefault
-alias(x, 1) # E: Argument 1 has incompatible type "str"; expected "Never"
+alias(x, 1) # E: Argument 1 to "setdefault" of "TypedDict" has incompatible type "str"; expected "Never"
a.update({})
a.update({'x': 1})
@@ -1681,11 +1681,11 @@ reveal_type(a.pop('x', '')) # N: Revealed type is "Union[builtins.int, Literal['
reveal_type(a.pop('x', (1, 2))) # N: Revealed type is "Union[builtins.int, Tuple[Literal[1]?, Literal[2]?]]"
a.pop('invalid', '') # E: TypedDict "A" has no key "invalid"
b.pop('x') # E: Key "x" of TypedDict "B" cannot be deleted
-x = ''
+x: str
b.pop(x) # E: Expected TypedDict key to be string literal
pop = b.pop
-pop('x') # E: Argument 1 has incompatible type "str"; expected "Never"
-pop('invalid') # E: Argument 1 has incompatible type "str"; expected "Never"
+pop('x') # E: Argument 1 to "pop" of "TypedDict" has incompatible type "str"; expected "Never"
+pop('invalid') # E: Argument 1 to "pop" of "TypedDict" has incompatible type "str"; expected "Never"
[builtins fixtures/dict.pyi]
[case testTypedDictDel]
@@ -1700,7 +1700,7 @@ b: B
del a['x']
del a['invalid'] # E: TypedDict "A" has no key "invalid"
del b['x'] # E: Key "x" of TypedDict "B" cannot be deleted
-s = ''
+s: str
del a[s] # E: Expected TypedDict key to be string literal
del b[s] # E: Expected TypedDict key to be string literal
alias = b.__delitem__
diff --git a/test-data/unit/check-typeis.test b/test-data/unit/check-typeis.test
index 894700640..0c05881a1 100644
--- a/test-data/unit/check-typeis.test
+++ b/test-data/unit/check-typeis.test
@@ -605,12 +605,12 @@ def func1(name: object):
if guard(name, name):
reveal_type(name) # N: Revealed type is "builtins.object"
if guard(name, 1):
- reveal_type(name) # N: Revealed type is "builtins.int"
+ reveal_type(name) # N: Revealed type is "Literal[1]?"
def func2(name: int):
reveal_type(name) # N: Revealed type is "builtins.int"
if guard(name, True):
- reveal_type(name) # N: Revealed type is "builtins.bool"
+ reveal_type(name) # N: Revealed type is "Literal[True]?"
[builtins fixtures/tuple.pyi]
[case testTypeIsWithGenericInstance]
diff --git a/test-data/unit/check-typevar-tuple.test b/test-data/unit/check-typevar-tuple.test
index 25829f89d..e64001d47 100644
--- a/test-data/unit/check-typevar-tuple.test
+++ b/test-data/unit/check-typevar-tuple.test
@@ -2461,7 +2461,7 @@ Ts = TypeVarTuple("Ts")
@cm
def test(x: T, *args: Unpack[Ts]) -> Tuple[T, Unpack[Ts]]: ...
-reveal_type(test) # N: Revealed type is "def [T, Ts] (builtins.list[T`2], *args: Unpack[Ts`-2]) -> __main__.CM[Tuple[T`2, Unpack[Ts`-2]]]"
+reveal_type(test) # N: Revealed type is "def [T, Ts] (builtins.list[T`3], *args: Unpack[Ts`-2]) -> __main__.CM[Tuple[T`3, Unpack[Ts`-2]]]"
[builtins fixtures/tuple.pyi]
[case testMixingTypeVarTupleAndParamSpec]
diff --git a/test-data/unit/check-unions.test b/test-data/unit/check-unions.test
index 117dc4fdf..848a2e778 100644
--- a/test-data/unit/check-unions.test
+++ b/test-data/unit/check-unions.test
@@ -287,16 +287,16 @@ reveal_type(u(C(), None)) # N: Revealed type is "__main__.C"
reveal_type(u(None, C())) # N: Revealed type is "__main__.C"
# Normal instance type and None, simplify
-reveal_type(u(1, None)) # N: Revealed type is "builtins.int"
-reveal_type(u(None, 1)) # N: Revealed type is "builtins.int"
+reveal_type(u(1, None)) # N: Revealed type is "Literal[1]?"
+reveal_type(u(None, 1)) # N: Revealed type is "Literal[1]?"
# Normal instance type and base-class-Any, no simplification
-reveal_type(u(C(), 1)) # N: Revealed type is "Union[builtins.int, __main__.C]"
-reveal_type(u(1, C())) # N: Revealed type is "Union[__main__.C, builtins.int]"
+reveal_type(u(C(), 1)) # N: Revealed type is "Union[Literal[1]?, __main__.C]"
+reveal_type(u(1, C())) # N: Revealed type is "Union[__main__.C, Literal[1]?]"
# Normal instance type and Any, no simplification
-reveal_type(u(1, a)) # N: Revealed type is "Union[Any, builtins.int]"
-reveal_type(u(a, 1)) # N: Revealed type is "Union[builtins.int, Any]"
+reveal_type(u(1, a)) # N: Revealed type is "Union[Any, Literal[1]?]"
+reveal_type(u(a, 1)) # N: Revealed type is "Union[Literal[1]?, Any]"
# Any and base-class-Any, no simplification
reveal_type(u(C(), a)) # N: Revealed type is "Union[Any, __main__.C]"
@@ -307,8 +307,8 @@ reveal_type(u(1, object())) # N: Revealed type is "builtins.object"
reveal_type(u(object(), 1)) # N: Revealed type is "builtins.object"
# Two normal instance types, no simplification
-reveal_type(u(1, '')) # N: Revealed type is "Union[builtins.str, builtins.int]"
-reveal_type(u('', 1)) # N: Revealed type is "Union[builtins.int, builtins.str]"
+reveal_type(u(1, '')) # N: Revealed type is "Union[Literal['']?, Literal[1]?]"
+reveal_type(u('', 1)) # N: Revealed type is "Union[Literal[1]?, Literal['']?]"
[case testUnionSimplificationWithDuplicateItems]
from typing import Any, TypeVar, Union
@@ -322,11 +322,11 @@ def u(x: T, y: S, z: R) -> Union[R, S, T]: pass
a: Any
-reveal_type(u(1, 1, 1)) # N: Revealed type is "builtins.int"
+reveal_type(u(1, 1, 1)) # N: Revealed type is "Literal[1]?"
reveal_type(u(C(), C(), None)) # N: Revealed type is "Union[None, __main__.C]"
-reveal_type(u(a, a, 1)) # N: Revealed type is "Union[builtins.int, Any]"
+reveal_type(u(a, a, 1)) # N: Revealed type is "Union[Literal[1]?, Any]"
reveal_type(u(a, C(), a)) # N: Revealed type is "Union[Any, __main__.C]"
-reveal_type(u('', 1, 1)) # N: Revealed type is "Union[builtins.int, builtins.str]"
+reveal_type(u('', 1, 1)) # N: Revealed type is "Union[Literal[1]?, Literal['']?]"
[case testUnionAndBinaryOperation]
from typing import Union
@@ -360,10 +360,10 @@ T = TypeVar('T')
S = TypeVar('S')
def u(x: T, y: S) -> Union[T, S]: pass
-reveal_type(u(1, 2.3)) # N: Revealed type is "Union[builtins.int, builtins.float]"
-reveal_type(u(2.3, 1)) # N: Revealed type is "Union[builtins.float, builtins.int]"
-reveal_type(u(False, 2.2)) # N: Revealed type is "Union[builtins.bool, builtins.float]"
-reveal_type(u(2.2, False)) # N: Revealed type is "Union[builtins.float, builtins.bool]"
+reveal_type(u(1, 2.3)) # N: Revealed type is "Union[Literal[1]?, Literal[2.3]?]"
+reveal_type(u(2.3, 1)) # N: Revealed type is "Union[Literal[2.3]?, Literal[1]?]"
+reveal_type(u(False, 2.2)) # N: Revealed type is "Union[Literal[False]?, Literal[2.2]?]"
+reveal_type(u(2.2, False)) # N: Revealed type is "Union[Literal[2.2]?, Literal[False]?]"
[builtins fixtures/primitives.pyi]
[case testSimplifyingUnionWithTypeTypes1]
@@ -384,14 +384,14 @@ reveal_type(u(t_a, t_a)) # N: Revealed type is "Type[Any]"
reveal_type(u(type, type)) # N: Revealed type is "def (x: builtins.object) -> builtins.type"
# One type, other non-type
-reveal_type(u(t_s, 1)) # N: Revealed type is "Union[builtins.int, Type[builtins.str]]"
-reveal_type(u(1, t_s)) # N: Revealed type is "Union[Type[builtins.str], builtins.int]"
-reveal_type(u(type, 1)) # N: Revealed type is "Union[builtins.int, def (x: builtins.object) -> builtins.type]"
-reveal_type(u(1, type)) # N: Revealed type is "Union[def (x: builtins.object) -> builtins.type, builtins.int]"
-reveal_type(u(t_a, 1)) # N: Revealed type is "Union[builtins.int, Type[Any]]"
-reveal_type(u(1, t_a)) # N: Revealed type is "Union[Type[Any], builtins.int]"
-reveal_type(u(t_o, 1)) # N: Revealed type is "Union[builtins.int, Type[builtins.object]]"
-reveal_type(u(1, t_o)) # N: Revealed type is "Union[Type[builtins.object], builtins.int]"
+reveal_type(u(t_s, 1)) # N: Revealed type is "Union[Literal[1]?, Type[builtins.str]]"
+reveal_type(u(1, t_s)) # N: Revealed type is "Union[Type[builtins.str], Literal[1]?]"
+reveal_type(u(type, 1)) # N: Revealed type is "Union[Literal[1]?, def (x: builtins.object) -> builtins.type]"
+reveal_type(u(1, type)) # N: Revealed type is "Union[def (x: builtins.object) -> builtins.type, Literal[1]?]"
+reveal_type(u(t_a, 1)) # N: Revealed type is "Union[Literal[1]?, Type[Any]]"
+reveal_type(u(1, t_a)) # N: Revealed type is "Union[Type[Any], Literal[1]?]"
+reveal_type(u(t_o, 1)) # N: Revealed type is "Union[Literal[1]?, Type[builtins.object]]"
+reveal_type(u(1, t_o)) # N: Revealed type is "Union[Type[builtins.object], Literal[1]?]"
[case testSimplifyingUnionWithTypeTypes2]
from typing import TypeVar, Union, Type, Any
@@ -613,7 +613,7 @@ reveal_type(obj) # N: Revealed type is "Union[__main__.B, __main__.C]"
reveal_type(new) # N: Revealed type is "Union[__main__.B, __main__.C]"
obj = 1
-reveal_type(obj) # N: Revealed type is "builtins.int"
+reveal_type(obj) # N: Revealed type is "Literal[1]?"
[builtins fixtures/list.pyi]
[case testUnionMultiassignAlreadyDeclared]
diff --git a/test-data/unit/check-unreachable-code.test b/test-data/unit/check-unreachable-code.test
index 80c7605cb..40f8a79a2 100644
--- a/test-data/unit/check-unreachable-code.test
+++ b/test-data/unit/check-unreachable-code.test
@@ -428,7 +428,7 @@ if sys.version_info == (3, 11):
x = "foo"
else:
x = 3
-reveal_type(x) # N: Revealed type is "builtins.str"
+reveal_type(x) # N: Revealed type is "Literal['foo']?"
[builtins fixtures/ops.pyi]
[out]
@@ -439,7 +439,7 @@ if sys.version_info == (3, 6):
x = "foo"
else:
x = 3
-reveal_type(x) # N: Revealed type is "builtins.int"
+reveal_type(x) # N: Revealed type is "Literal[3]?"
[builtins fixtures/ops.pyi]
[out]
@@ -450,7 +450,7 @@ if sys.platform == 'linux':
x = "foo"
else:
x = 3
-reveal_type(x) # N: Revealed type is "builtins.str"
+reveal_type(x) # N: Revealed type is "Literal['foo']?"
[builtins fixtures/ops.pyi]
[out]
@@ -461,7 +461,7 @@ if sys.platform == 'linux':
x = "foo"
else:
x = 3
-reveal_type(x) # N: Revealed type is "builtins.int"
+reveal_type(x) # N: Revealed type is "Literal[3]?"
[builtins fixtures/ops.pyi]
[out]
@@ -472,7 +472,7 @@ if sys.platform.startswith('win'):
x = "foo"
else:
x = 3
-reveal_type(x) # N: Revealed type is "builtins.str"
+reveal_type(x) # N: Revealed type is "Literal['foo']?"
[builtins fixtures/ops.pyi]
[out]
@@ -510,12 +510,12 @@ if PY2 and sys.platform == 'linux':
x = 'foo'
else:
x = 3
-reveal_type(x) # N: Revealed type is "builtins.int"
+reveal_type(x) # N: Revealed type is "Literal[3]?"
if sys.platform == 'linux' and PY2:
y = 'foo'
else:
y = 3
-reveal_type(y) # N: Revealed type is "builtins.int"
+reveal_type(y) # N: Revealed type is "Literal[3]?"
[builtins fixtures/ops.pyi]
[case testShortCircuitOrWithConditionalAssignment]
@@ -528,12 +528,12 @@ if PY2 or sys.platform == 'linux':
x = 'foo'
else:
x = 3
-reveal_type(x) # N: Revealed type is "builtins.str"
+reveal_type(x) # N: Revealed type is "Literal['foo']?"
if sys.platform == 'linux' or PY2:
y = 'foo'
else:
y = 3
-reveal_type(y) # N: Revealed type is "builtins.str"
+reveal_type(y) # N: Revealed type is "Literal['foo']?"
[builtins fixtures/ops.pyi]
[case testShortCircuitNoEvaluation]
diff --git a/test-data/unit/check-varargs.test b/test-data/unit/check-varargs.test
index 2f5b4f72b..0392f9b3b 100644
--- a/test-data/unit/check-varargs.test
+++ b/test-data/unit/check-varargs.test
@@ -953,7 +953,7 @@ class Person(TypedDict, Generic[T]):
value: T
def foo(**kwargs: Unpack[Person[T]]) -> T: ...
-reveal_type(foo(name="test", value=42)) # N: Revealed type is "builtins.int"
+reveal_type(foo(name="test", value=42)) # N: Revealed type is "Literal[42]?"
[builtins fixtures/dict.pyi]
[case testUnpackKwargsInference]
diff --git a/test-data/unit/check-warnings.test b/test-data/unit/check-warnings.test
index 45d24ce9c..cfc713e18 100644
--- a/test-data/unit/check-warnings.test
+++ b/test-data/unit/check-warnings.test
@@ -6,7 +6,7 @@
[case testRedundantCast]
# flags: --warn-redundant-casts
from typing import cast
-a = 1
+a: int
b = cast(str, a)
c = cast(int, a)
[out]
diff --git a/test-data/unit/cmdline.test b/test-data/unit/cmdline.test
index bd077d407..723a3d676 100644
--- a/test-data/unit/cmdline.test
+++ b/test-data/unit/cmdline.test
@@ -464,9 +464,9 @@ int_pow.py:5: note: Revealed type is "builtins.int"
int_pow.py:6: note: Revealed type is "Literal[1]"
int_pow.py:7: note: Revealed type is "builtins.float"
int_pow.py:8: note: Revealed type is "builtins.float"
-int_pow.py:9: note: Revealed type is "Any"
+int_pow.py:9: note: Revealed type is "builtins.int"
int_pow.py:10: note: Revealed type is "builtins.int"
-int_pow.py:11: note: Revealed type is "Any"
+int_pow.py:11: note: Revealed type is "Literal[1]"
== Return code: 0
[case testDisallowAnyGenericsBuiltinCollectionsPre39]
@@ -912,8 +912,8 @@ test_between(1 + 1)
tabs.py:2: error: Incompatible return value type (got "None", expected "str")
return None
^~~~
-tabs.py:4: error: Argument 1 to "test_between" has incompatible type "int";
-expected "str"
+tabs.py:4: error: Argument 1 to "test_between" has incompatible type
+"Literal[2]"; expected "str"
test_between(1 + 1)
^~~~~~~~~~~~
diff --git a/test-data/unit/fine-grained.test b/test-data/unit/fine-grained.test
index 4e275ba90..42aa1663b 100644
--- a/test-data/unit/fine-grained.test
+++ b/test-data/unit/fine-grained.test
@@ -10170,7 +10170,7 @@ class C(B): ...
[out]
==
==
-main.py:2: note: Revealed type is "builtins.int"
+main.py:2: note: Revealed type is "Literal[42]?"
[case testBoundGenericMethodParamSpecFine]
import main
diff --git a/test-data/unit/lib-stub/basedtyping.pyi b/test-data/unit/lib-stub/basedtyping.pyi
index 6433b360f..f36853e7a 100644
--- a/test-data/unit/lib-stub/basedtyping.pyi
+++ b/test-data/unit/lib-stub/basedtyping.pyi
@@ -7,3 +7,5 @@
Untyped = 0
Intersection = 1
FunctionType = 2
+def type_function(fn): ...
+class TypeFunctionError(Exception): ...
diff --git a/test-data/unit/pep561.test b/test-data/unit/pep561.test
index cbe2c2a83..ca37e9819 100644
--- a/test-data/unit/pep561.test
+++ b/test-data/unit/pep561.test
@@ -116,8 +116,8 @@ dne("abc")
[out]
testTypedPkgNamespaceImportAs.py:4: error: Cannot find implementation or library stub for module named "typedpkg_ns.a.dne"
testTypedPkgNamespaceImportAs.py:4: note: See https://kotlinisland.github.io/basedmypy/running_mypy.html#missing-imports
-testTypedPkgNamespaceImportAs.py:10: error: Argument 1 has incompatible type "bool"; expected "str"
-testTypedPkgNamespaceImportAs.py:11: error: Argument 1 has incompatible type "int"; expected "bool"
+testTypedPkgNamespaceImportAs.py:10: error: Argument 1 to "af" has incompatible type "bool"; expected "str"
+testTypedPkgNamespaceImportAs.py:11: error: Argument 1 to "bf" has incompatible type "int"; expected "bool"
[case testTypedPkgNamespaceRegImport]
# pkgs: typedpkg, typedpkg_ns_a
@@ -136,8 +136,8 @@ dne("abc")
[out]
testTypedPkgNamespaceRegImport.py:4: error: Cannot find implementation or library stub for module named "typedpkg_ns.a.dne"
testTypedPkgNamespaceRegImport.py:4: note: See https://kotlinisland.github.io/basedmypy/running_mypy.html#missing-imports
-testTypedPkgNamespaceRegImport.py:10: error: Argument 1 has incompatible type "bool"; expected "str"
-testTypedPkgNamespaceRegImport.py:11: error: Argument 1 has incompatible type "int"; expected "bool"
+testTypedPkgNamespaceRegImport.py:10: error: Argument 1 to "af" has incompatible type "bool"; expected "str"
+testTypedPkgNamespaceRegImport.py:11: error: Argument 1 to "bf" has incompatible type "int"; expected "bool"
-- This is really testing the test framework to make sure incremental works
[case testPep561TestIncremental]
diff --git a/test-data/unit/typexport-basic.test b/test-data/unit/typexport-basic.test
index bcaa71469..32ebcb806 100644
--- a/test-data/unit/typexport-basic.test
+++ b/test-data/unit/typexport-basic.test
@@ -188,8 +188,8 @@ a or a
not a
[builtins fixtures/bool.pyi]
[out]
-OpExpr(4) : builtins.int
-OpExpr(5) : builtins.int
+OpExpr(4) : Union[Literal[0], Literal[1]?]
+OpExpr(5) : Union[Literal[1]?, Literal[0]]
UnaryExpr(6) : builtins.bool
[case testBooleanOpsOnBools]