Skip to content

Fix inference when unpacking union type #19650

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

hauntsaninja
Copy link
Collaborator

@hauntsaninja hauntsaninja commented Aug 12, 2025

I wonder if primer will be big, I could see people expecting unsound union behaviour here...

Copy link
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

tornado (https://github.com/tornadoweb/tornado)
+ tornado/routing.py:355: error: Argument 2 to "Rule" has incompatible type "*Union[list[Any], tuple[Any], tuple[Any, dict[str, Any]], tuple[Any, dict[str, Any], str]]"; expected "Optional[dict[str, Any]]"  [arg-type]
+ tornado/routing.py:355: error: Argument 2 to "Rule" has incompatible type "*Union[list[Any], tuple[Any], tuple[Any, dict[str, Any]], tuple[Any, dict[str, Any], str]]"; expected "Optional[str]"  [arg-type]
+ tornado/routing.py:357: error: Argument 1 to "Rule" has incompatible type "*Union[list[Any], tuple[Union[str, Matcher], Any], tuple[Union[str, Matcher], Any, dict[str, Any]], tuple[Union[str, Matcher], Any, dict[str, Any], str]]"; expected "Matcher"  [arg-type]
+ tornado/routing.py:357: error: Argument 1 to "Rule" has incompatible type "*Union[list[Any], tuple[Union[str, Matcher], Any], tuple[Union[str, Matcher], Any, dict[str, Any]], tuple[Union[str, Matcher], Any, dict[str, Any], str]]"; expected "Optional[dict[str, Any]]"  [arg-type]
+ tornado/routing.py:357: error: Argument 1 to "Rule" has incompatible type "*Union[list[Any], tuple[Union[str, Matcher], Any], tuple[Union[str, Matcher], Any, dict[str, Any]], tuple[Union[str, Matcher], Any, dict[str, Any], str]]"; expected "Optional[str]"  [arg-type]
+ tornado/web.py:1897: error: Argument 1 to "log_exception" of "RequestHandler" has incompatible type "*Union[tuple[type[BaseException], BaseException, TracebackType], tuple[None, None, None]]"; expected "Optional[BaseException]"  [arg-type]
+ tornado/web.py:1897: error: Argument 1 to "log_exception" of "RequestHandler" has incompatible type "*Union[tuple[type[BaseException], BaseException, TracebackType], tuple[None, None, None]]"; expected "Optional[TracebackType]"  [arg-type]
+ tornado/simple_httpclient.py:446: error: Argument 1 to "_handle_exception" of "_HTTPConnection" has incompatible type "*Union[tuple[type[BaseException], BaseException, TracebackType], tuple[None, None, None]]"; expected "Optional[BaseException]"  [arg-type]
+ tornado/simple_httpclient.py:446: error: Argument 1 to "_handle_exception" of "_HTTPConnection" has incompatible type "*Union[tuple[type[BaseException], BaseException, TracebackType], tuple[None, None, None]]"; expected "Optional[TracebackType]"  [arg-type]
+ tornado/simple_httpclient.py:526: error: Argument 1 to "_handle_exception" of "_HTTPConnection" has incompatible type "*Union[tuple[type[BaseException], BaseException, TracebackType], tuple[None, None, None]]"; expected "Optional[BaseException]"  [arg-type]
+ tornado/simple_httpclient.py:526: error: Argument 1 to "_handle_exception" of "_HTTPConnection" has incompatible type "*Union[tuple[type[BaseException], BaseException, TracebackType], tuple[None, None, None]]"; expected "Optional[TracebackType]"  [arg-type]
+ tornado/simple_httpclient.py:586: error: Argument 1 to "_handle_exception" of "_HTTPConnection" has incompatible type "*Union[tuple[type[BaseException], BaseException, TracebackType], tuple[None, None, None]]"; expected "Optional[BaseException]"  [arg-type]
+ tornado/simple_httpclient.py:586: error: Argument 1 to "_handle_exception" of "_HTTPConnection" has incompatible type "*Union[tuple[type[BaseException], BaseException, TracebackType], tuple[None, None, None]]"; expected "Optional[TracebackType]"  [arg-type]
+ tornado/websocket.py:665: error: Argument 1 to "log_exception" of "_WebSocketDelegate" has incompatible type "*Union[tuple[type[BaseException], BaseException, TracebackType], tuple[None, None, None]]"; expected "Optional[BaseException]"  [arg-type]
+ tornado/websocket.py:665: error: Argument 1 to "log_exception" of "_WebSocketDelegate" has incompatible type "*Union[tuple[type[BaseException], BaseException, TracebackType], tuple[None, None, None]]"; expected "Optional[TracebackType]"  [arg-type]
+ tornado/websocket.py:973: error: Argument 1 to "log_exception" of "RequestHandler" has incompatible type "*Union[tuple[type[BaseException], BaseException, TracebackType], tuple[None, None, None]]"; expected "Optional[BaseException]"  [arg-type]
+ tornado/websocket.py:973: error: Argument 1 to "log_exception" of "RequestHandler" has incompatible type "*Union[tuple[type[BaseException], BaseException, TracebackType], tuple[None, None, None]]"; expected "Optional[TracebackType]"  [arg-type]

aiohttp (https://github.com/aio-libs/aiohttp)
+ aiohttp/web_urldispatcher.py:671: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
+ https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
+ Please report a bug at https://github.com/python/mypy/issues
+ version: 1.18.0+dev.ef9ed5deb278f3ad66ef5234a79b981e7ef04d40
+ aiohttp/web_urldispatcher.py:671: : note: use --pdb to drop into pdb
- aiohttp/resolver.py:16: error: Unused "type: ignore" comment  [unused-ignore]
- aiohttp/resolver.py:160: error: Unused "type: ignore" comment  [unused-ignore]
- aiohttp/resolver.py:165: error: Unused "type: ignore" comment  [unused-ignore]
- aiohttp/web_protocol.py:628:41: error: Name "task" may be undefined  [possibly-undefined]
- aiohttp/web_protocol.py:628:41: note: See https://mypy.rtfd.io/en/stable/_refs.html#code-possibly-undefined for more info
- aiohttp/web_protocol.py:634:21: error: Name "task" may be undefined  [possibly-undefined]
- aiohttp/pytest_plugin.py:37: error: Unused "type: ignore" comment  [unused-ignore]
+ Traceback (most recent call last):
+   File "", line 8, in <module>
+     sys.exit(console_entry())
+   File "/__main__.py", line 15, in console_entry
+     main()
+   File "/main.py", line 127, in main
+     res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
+   File "/main.py", line 211, in run_build
+     res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
+   File "/build.py", line 191, in build
+     result = _build(
+   File "/build.py", line 267, in _build
+     graph = dispatch(sources, manager, stdout)
+   File "/build.py", line 2939, in dispatch
+     process_graph(graph, manager)
+   File "/build.py", line 3337, in process_graph
+     process_stale_scc(graph, scc, manager)
+   File "/build.py", line 3438, in process_stale_scc
+     graph[id].type_check_first_pass()
+   File "/build.py", line 2311, in type_check_first_pass
+     self.type_checker().check_first_pass()
+   File "/checker.py", line 527, in check_first_pass
+     self.accept(d)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1263, in accept
+     return visitor.visit_class_def(self)
+   File "/checker.py", line 2666, in visit_class_def
+     self.accept(defn.defs)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1344, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 3127, in visit_block
+     self.accept(s)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 874, in accept
+     return visitor.visit_func_def(self)
+   File "/checker.py", line 1195, in visit_func_def
+     self._visit_func_def(defn)
+   File "/checker.py", line 1199, in _visit_func_def
+     self.check_func_item(defn, name=defn.name)
+   File "/checker.py", line 1234, in check_func_item
+     self.check_func_def(defn, typ, name, allow_empty)
+   File "/checker.py", line 1507, in check_func_def
+     self.accept(item.body)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1344, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 3127, in visit_block
+     self.accept(s)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1667, in accept
+     return visitor.visit_try_stmt(self)
+   File "/checker.py", line 5084, in visit_try_stmt
+     self.visit_try_without_finally(s, try_frame=bool(s.finally_body))
+   File "/checker.py", line 5130, in visit_try_without_finally
+     t = self.check_except_handler_test(typ, s.is_star)
+   File "/checker.py", line 5157, in check_except_handler_test
+     typ = self.expr_checker.accept(n)
+   File "/checkexpr.py", line 6067, in accept
+     typ = self.accept_maybe_cache(node, type_context=type_context)
+   File "/checkexpr.py", line 6102, in accept_maybe_cache
+     typ = node.accept(self)
+   File "/nodes.py", line 2420, in accept
+     return visitor.visit_tuple_expr(self)
+            ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
+   File "/checkexpr.py", line 5257, in visit_tuple_expr
+     return self.check_lst_expr(e, "builtins.tuple", "<tuple>")
+            ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   File "/checkexpr.py", line 5149, in check_lst_expr
+     out = self.check_call(
+           ~~~~~~~~~~~~~~~^
+         constructor,
+         ^^^^^^^^^^^^
+     ...<2 lines>...
+         e,
+         ^^
+     )[0]
+     ^
+   File "/checkexpr.py", line 1604, in check_call
+     return self.check_callable_call(
+            ~~~~~~~~~~~~~~~~~~~~~~~~^
+         callee,
+         ^^^^^^^
+     ...<6 lines>...
+         object_type,
+         ^^^^^^^^^^^^
+     )
+     ^
+   File "/checkexpr.py", line 1783, in check_callable_call
+     callee = self.infer_function_type_arguments(
+         callee, args, arg_kinds, arg_names, formal_to_actual, need_refresh, context
+     )
+   File "/checkexpr.py", line 2122, in infer_function_type_arguments
+     inferred_args, _ = infer_function_type_arguments(
+                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
+         callee_type,
+         ^^^^^^^^^^^^
+     ...<5 lines>...
+         strict=self.chk.in_checked_function(),
+         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+     )
+     ^
+   File "/infer.py", line 57, in infer_function_type_arguments
+     constraints = infer_constraints_for_callable(
+         callee_type, arg_types, arg_kinds, arg_names, formal_to_actual, context
+     )
+   File "/constraints.py", line 246, in infer_constraints_for_callable
+     actual_type = mapper.expand_actual_type(
+         actual_arg_type,
+     ...<2 lines>...
+         callee.arg_kinds[i],
+     )
+   File "/argmap.py", line 217, in expand_actual_type
+     self.expand_actual_type(
+     ~~~~~~~~~~~~~~~~~~~~~~~^
+         item,
+         ^^^^^
+     ...<3 lines>...
+         allow_unpack=allow_unpack,
+         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+     )
+     ^
+   File "/argmap.py", line 234, in expand_actual_type
+     item = actual_type.items[self.tuple_index - 1]
+            ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
+ IndexError: list index out of range

sockeye (https://github.com/awslabs/sockeye)
+ sockeye/training.py:936: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
+ https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
+ Please report a bug at https://github.com/python/mypy/issues
+ version: 1.18.0+dev.ef9ed5deb278f3ad66ef5234a79b981e7ef04d40
+ sockeye/training.py:936: : note: use --pdb to drop into pdb
- sockeye/training.py:359: error: Unused "type: ignore" comment  [unused-ignore]
- sockeye/training.py:366: error: Unused "type: ignore" comment  [unused-ignore]
- sockeye/training.py:386: error: Unused "type: ignore" comment  [unused-ignore]
- sockeye/training.py:402: error: Unused "type: ignore" comment  [unused-ignore]
- sockeye/training.py:410: error: Unused "type: ignore" comment  [unused-ignore]
- sockeye/training.py:660: error: Unused "type: ignore" comment  [unused-ignore]
- sockeye/training.py:703: error: Unused "type: ignore" comment  [unused-ignore]
- sockeye/training.py:771: error: Unused "type: ignore" comment  [unused-ignore]
- sockeye/scoring.py:86: error: Unused "type: ignore" comment  [unused-ignore]
- sockeye/train.py:1152: error: Unused "type: ignore" comment  [unused-ignore]
+ Traceback (most recent call last):
+   File "", line 8, in <module>
+     sys.exit(console_entry())
+   File "/__main__.py", line 15, in console_entry
+     main()
+   File "/main.py", line 127, in main
+     res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
+   File "/main.py", line 211, in run_build
+     res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
+   File "/build.py", line 191, in build
+     result = _build(
+   File "/build.py", line 267, in _build
+     graph = dispatch(sources, manager, stdout)
+   File "/build.py", line 2939, in dispatch
+     process_graph(graph, manager)
+   File "/build.py", line 3337, in process_graph
+     process_stale_scc(graph, scc, manager)
+   File "/build.py", line 3438, in process_stale_scc
+     graph[id].type_check_first_pass()
+   File "/build.py", line 2311, in type_check_first_pass
+     self.type_checker().check_first_pass()
+   File "/checker.py", line 527, in check_first_pass
+     self.accept(d)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1263, in accept
+     return visitor.visit_class_def(self)
+   File "/checker.py", line 2666, in visit_class_def
+     self.accept(defn.defs)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1344, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 3127, in visit_block
+     self.accept(s)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 874, in accept
+     return visitor.visit_func_def(self)
+   File "/checker.py", line 1195, in visit_func_def
+     self._visit_func_def(defn)
+   File "/checker.py", line 1199, in _visit_func_def
+     self.check_func_item(defn, name=defn.name)
+   File "/checker.py", line 1234, in check_func_item
+     self.check_func_def(defn, typ, name, allow_empty)
+   File "/checker.py", line 1507, in check_func_def
+     self.accept(item.body)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1344, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 3127, in visit_block
+     self.accept(s)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1612, in accept
+     return visitor.visit_if_stmt(self)
+   File "/checker.py", line 4978, in visit_if_stmt
+     self.accept(b)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1344, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 3127, in visit_block
+     self.accept(s)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1612, in accept
+     return visitor.visit_if_stmt(self)
+   File "/checker.py", line 4978, in visit_if_stmt
+     self.accept(b)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1344, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 3127, in visit_block
+     self.accept(s)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1612, in accept
+     return visitor.visit_if_stmt(self)
+   File "/checker.py", line 4978, in visit_if_stmt
+     self.accept(b)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1344, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 3127, in visit_block
+     self.accept(s)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1364, in accept
+     return visitor.visit_expression_stmt(self)
+   File "/checker.py", line 4843, in visit_expression_stmt
+     expr_type = self.expr_checker.accept(s.expr, allow_none_return=True, always_allow_any=True)
+   File "/checkexpr.py", line 6041, in accept
+     typ = self.visit_call_expr(node, allow_none_return=True)
+   File "/checkexpr.py", line 527, in visit_call_expr
+     return self.visit_call_expr_inner(e, allow_none_return=allow_none_return)
+            ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   File "/checkexpr.py", line 661, in visit_call_expr_inner
+     ret_type = self.check_call_expr_with_callee_type(
+         callee_type, e, fullname, object_type, member
+     )
+   File "/checkexpr.py", line 1511, in check_call_expr_with_callee_type
+     ret_type, callee_type = self.check_call(
+                             ~~~~~~~~~~~~~~~^
+         callee_type,
+         ^^^^^^^^^^^^
+     ...<6 lines>...
+         object_type=object_type,
+         ^^^^^^^^^^^^^^^^^^^^^^^^
+     )
+     ^
+   File "/checkexpr.py", line 1604, in check_call
+     return self.check_callable_call(
+            ~~~~~~~~~~~~~~~~~~~~~~~~^
+         callee,
+         ^^^^^^^
+     ...<6 lines>...
+         object_type,
+         ^^^^^^^^^^^^
+     )
+     ^
+   File "/checkexpr.py", line 1828, in check_callable_call
+     self.check_argument_types(
+     ~~~~~~~~~~~~~~~~~~~~~~~~~^
+         arg_types, arg_kinds, args, callee, formal_to_actual, context, object_type=object_type
+         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+     )
+     ^
+   File "/checkexpr.py", line 2635, in check_argument_types
+     expanded_actual = mapper.expand_actual_type(
+         actual_type,
+     ...<3 lines>...
+         allow_unpack=isinstance(callee_arg_type, UnpackType),
+     )
+   File "/argmap.py", line 217, in expand_actual_type
+     self.expand_actual_type(
+     ~~~~~~~~~~~~~~~~~~~~~~~^
+         item,
+         ^^^^^
+     ...<3 lines>...
+         allow_unpack=allow_unpack,
+         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+     )
+     ^
+   File "/argmap.py", line 234, in expand_actual_type
+     item = actual_type.items[self.tuple_index - 1]
+            ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
+ IndexError: list index out of range

altair (https://github.com/vega/altair)
+ altair/datasets/_readimpl.py:316: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
+ https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
+ Please report a bug at https://github.com/python/mypy/issues
+ version: 1.18.0+dev.ef9ed5deb278f3ad66ef5234a79b981e7ef04d40
+ altair/datasets/_readimpl.py:316: : note: use --pdb to drop into pdb
- altair/utils/core.py:328: error: Redundant cast to "bool"  [redundant-cast]
- altair/utils/core.py:356: error: Redundant cast to "_PandasDataFrameT"  [redundant-cast]
- altair/vegalite/v6/api.py:1125: error: Redundant cast to "_Conditional[list[_ConditionClosed]]"  [redundant-cast]
- tests/vegalite/v6/test_theme.py:1060: error: Redundant cast to "str"  [redundant-cast]
- tests/vegalite/v6/test_theme.py:1073: error: Unused "type: ignore" comment  [unused-ignore]
- tests/vegalite/v6/test_theme.py:1074: error: Unused "type: ignore" comment  [unused-ignore]
- tests/vegalite/v6/test_renderers.py:16: error: Unused "type: ignore" comment  [unused-ignore]
+ Traceback (most recent call last):
+   File "", line 8, in <module>
+     sys.exit(console_entry())
+   File "/__main__.py", line 15, in console_entry
+     main()
+   File "/main.py", line 127, in main
+     res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
+   File "/main.py", line 211, in run_build
+     res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
+   File "/build.py", line 191, in build
+     result = _build(
+   File "/build.py", line 267, in _build
+     graph = dispatch(sources, manager, stdout)
+   File "/build.py", line 2939, in dispatch
+     process_graph(graph, manager)
+   File "/build.py", line 3337, in process_graph
+     process_stale_scc(graph, scc, manager)
+   File "/build.py", line 3438, in process_stale_scc
+     graph[id].type_check_first_pass()
+   File "/build.py", line 2311, in type_check_first_pass
+     self.type_checker().check_first_pass()
+   File "/checker.py", line 527, in check_first_pass
+     self.accept(d)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 874, in accept
+     return visitor.visit_func_def(self)
+   File "/checker.py", line 1195, in visit_func_def
+     self._visit_func_def(defn)
+   File "/checker.py", line 1199, in _visit_func_def
+     self.check_func_item(defn, name=defn.name)
+   File "/checker.py", line 1234, in check_func_item
+     self.check_func_def(defn, typ, name, allow_empty)
+   File "/checker.py", line 1507, in check_func_def
+     self.accept(item.body)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1344, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 3127, in visit_block
+     self.accept(s)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1540, in accept
+     return visitor.visit_return_stmt(self)
+   File "/checker.py", line 4856, in visit_return_stmt
+     self.check_return_stmt(s)
+   File "/checker.py", line 4892, in check_return_stmt
+     self.expr_checker.accept(
+   File "/checkexpr.py", line 6067, in accept
+     typ = self.accept_maybe_cache(node, type_context=type_context)
+   File "/checkexpr.py", line 6102, in accept_maybe_cache
+     typ = node.accept(self)
+   File "/nodes.py", line 2420, in accept
+     return visitor.visit_tuple_expr(self)
+            ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
+   File "/checkexpr.py", line 5257, in visit_tuple_expr
+     return self.check_lst_expr(e, "builtins.tuple", "<tuple>")
+            ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   File "/checkexpr.py", line 5149, in check_lst_expr
+     out = self.check_call(
+           ~~~~~~~~~~~~~~~^
+         constructor,
+         ^^^^^^^^^^^^
+     ...<2 lines>...
+         e,
+         ^^
+     )[0]
+     ^
+   File "/checkexpr.py", line 1604, in check_call
+     return self.check_callable_call(
+            ~~~~~~~~~~~~~~~~~~~~~~~~^
+         callee,
+         ^^^^^^^
+     ...<6 lines>...
+         object_type,
+         ^^^^^^^^^^^^
+     )
+     ^
+   File "/checkexpr.py", line 1828, in check_callable_call
+     self.check_argument_types(
+     ~~~~~~~~~~~~~~~~~~~~~~~~~^
+         arg_types, arg_kinds, args, callee, formal_to_actual, context, object_type=object_type
+         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+     )
+     ^
+   File "/checkexpr.py", line 2635, in check_argument_types
+     expanded_actual = mapper.expand_actual_type(
+         actual_type,
+     ...<3 lines>...
+         allow_unpack=isinstance(callee_arg_type, UnpackType),
+     )
+   File "/argmap.py", line 217, in expand_actual_type
+     self.expand_actual_type(
+     ~~~~~~~~~~~~~~~~~~~~~~~^
+         item,
+         ^^^^^
+     ...<3 lines>...
+         allow_unpack=allow_unpack,
+         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+     )
+     ^
+   File "/argmap.py", line 234, in expand_actual_type
+     item = actual_type.items[self.tuple_index - 1]
+            ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
+ IndexError: list index out of range

Tanjun (https://github.com/FasterSpeeding/Tanjun)
+ tanjun/conversion.py:266: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
+ https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
+ Please report a bug at https://github.com/python/mypy/issues
+ version: 1.18.0+dev.ef9ed5deb278f3ad66ef5234a79b981e7ef04d40
+ tanjun/conversion.py:266: : note: use --pdb to drop into pdb
- tanjun/dependencies/data.py:170: error: Unused "type: ignore" comment  [unused-ignore]
- tanjun/dependencies/reloaders.py:404: error: "ABC" has no attribute "type"  [attr-defined]
- tanjun/dependencies/reloaders.py:404: error: "ABC" has no attribute "name"  [attr-defined]
- tanjun/dependencies/reloaders.py:404: error: "ABC" has no attribute "build"  [attr-defined]
- tanjun/context/slash.py:982: error: List item 0 has incompatible type "_OtherT"; expected "_T"  [list-item]
- tanjun/context/slash.py:1035: error: Signature of "command" incompatible with supertype "Context"  [override]
- tanjun/context/slash.py:1035: note:      Superclass:
- tanjun/context/slash.py:1035: note:          ExecutableCommand[SlashContext] | None
- tanjun/context/slash.py:1035: note:      Subclass:
- tanjun/context/slash.py:1035: note:          BaseSlashCommand | None
- tanjun/context/message.py:134: error: Signature of "command" incompatible with supertype "Context"  [override]
- tanjun/context/message.py:134: note:      Superclass:
- tanjun/context/message.py:134: note:          ExecutableCommand[MessageContext] | None
- tanjun/context/message.py:134: note:      Subclass:
- tanjun/context/message.py:134: note:          MessageCommand[Any] | None
- tanjun/context/autocomplete.py:204: error: Returning Any from function declared to return "TextableChannel"  [no-any-return]
- tanjun/context/autocomplete.py:204: error: "AutocompleteInteraction" has no attribute "fetch_channel"  [attr-defined]
- tanjun/context/autocomplete.py:212: error: Returning Any from function declared to return "TextableGuildChannel | None"  [no-any-return]
- tanjun/context/autocomplete.py:212: error: "AutocompleteInteraction" has no attribute "get_channel"  [attr-defined]
- tanjun/schedules.py:347: error: Argument 1 to "call_with_async_di" of "Client" has incompatible type "_CallbackSigT"; expected "Callable[..., Coroutine[Any, Any, Never] | Never]"  [arg-type]
- tanjun/schedules.py:373: error: Argument 1 to "call_with_async_di" of "Client" has incompatible type "Callable[..., Coroutine[Any, Any, None]]"; expected "Callable[..., Coroutine[Any, Any, Never] | Never]"  [arg-type]
- tanjun/schedules.py:396: error: Argument 1 to "call_with_async_di" of "Client" has incompatible type "Callable[..., Coroutine[Any, Any, None]]"; expected "Callable[..., Coroutine[Any, Any, Never] | Never]"  [arg-type]
- tanjun/schedules.py:1067: error: Argument 1 to "call_with_async_di" of "Client" has incompatible type "_CallbackSigT"; expected "Callable[..., Coroutine[Any, Any, Never] | Never]"  [arg-type]
- tanjun/parsing.py:1632: error: Statement is unreachable  [unreachable]
- tanjun/parsing.py:1642: error: Statement is unreachable  [unreachable]
- tanjun/context/menu.py:102: error: Signature of "command" incompatible with supertype "Context"  [override]
- tanjun/context/menu.py:102: note:      Superclass:
- tanjun/context/menu.py:102: note:          ExecutableCommand[MenuContext] | None
- tanjun/context/menu.py:102: note:      Subclass:
- tanjun/context/menu.py:102: note:          MenuCommand[Any, Any] | None
- tanjun/context/menu.py:132: error: Incompatible return value type (got "Unique", expected "InteractionMember | User | Message")  [return-value]
- tanjun/context/menu.py:144: error: Incompatible return value type (got "CommandType", expected "Literal[CommandType.USER, CommandType.MESSAGE]")  [return-value]
- tanjun/context/menu.py:200: error: Argument "default" to "resolve_to_member" of "MenuContext" has incompatible type "None"; expected "User"  [arg-type]
- tanjun/dependencies/limiters.py:812: error: Incompatible types in assignment (expression has type "_Cooldown", variable has type "AbstractCooldownBucket | None")  [assignment]
- tanjun/dependencies/limiters.py:814: error: Item "AbstractCooldownBucket" of "AbstractCooldownBucket | None" has no attribute "check"  [union-attr]
- tanjun/dependencies/limiters.py:814: error: Item "None" of "AbstractCooldownBucket | None" has no attribute "check"  [union-attr]
- tanjun/dependencies/limiters.py:850: error: Incompatible types in assignment (expression has type "_Cooldown | None", variable has type "AbstractCooldownBucket | None")  [assignment]
- tanjun/checks.py:1026: error: Statement is unreachable  [unreachable]
- tanjun/checks.py:1140: error: Statement is unreachable  [unreachable]
- tanjun/commands/slash.py:381: error: Redundant cast to "_SlashCallbackSigT"  [redundant-cast]
- tanjun/commands/slash.py:820: error: Statement is unreachable  [unreachable]
- tanjun/commands/slash.py:1223: error: "_SlashCommandBuilder" has no attribute "set_is_dm_enabled"  [attr-defined]
- tanjun/commands/slash.py:1225: error: "_SlashCommandBuilder" has no attribute "set_is_dm_enabled"  [attr-defined]
- tanjun/commands/slash.py:1644: error: Redundant cast to "_SlashCallbackSigT"  [redundant-cast]
- tanjun/commands/slash.py:1716: error: "_SlashCommandBuilder" has no attribute "set_is_dm_enabled"  [attr-defined]
- tanjun/commands/slash.py:1718: error: "_SlashCommandBuilder" has no attribute "set_is_dm_enabled"  [attr-defined]
- tanjun/commands/slash.py:1787: error: Statement is unreachable  [unreachable]
- tanjun/commands/slash.py:3191: error: Argument 1 to "call_with_async_di" of "Context" has incompatible type "_SlashCallbackSigT"; expected "Callable[..., Coroutine[Any, Any, Never] | Never]"  [arg-type]
- tanjun/commands/slash.py:3222: error: Incompatible types in assignment (expression has type "Callable[[AutocompleteContext, float, VarArg(Any), KwArg(Any)], Coroutine[Any, Any, None]] | None", variable has type "Callable[[AutocompleteContext, str, VarArg(Any), KwArg(Any)], Coroutine[Any, Any, None]] | None")  [assignment]
- tanjun/commands/slash.py:3225: error: Incompatible types in assignment (expression has type "Callable[[AutocompleteContext, int, VarArg(Any), KwArg(Any)], Coroutine[Any, Any, None]] | None", variable has type "Callable[[AutocompleteContext, str, VarArg(Any), KwArg(Any)], Coroutine[Any, Any, None]] | None")  [assignment]
- tanjun/commands/slash.py:3235: error: Argument 1 to "call_with_async_di" of "Context" has incompatible type "Callable[[AutocompleteContext, str, VarArg(Any), KwArg(Any)], Coroutine[Any, Any, None]]"; expected "Callable[..., Coroutine[Any, Any, Never] | Never]"  [arg-type]
- tanjun/commands/message.py:109: error: Redundant cast to "_MessageCallbackSigT"  [redundant-cast]
- tanjun/commands/message.py:166: error: Redundant cast to "_MessageCallbackSigT"  [redundant-cast]
- tanjun/commands/message.py:236: error: Redundant cast to "_MessageCallbackSigT"  [redundant-cast]
- tanjun/commands/message.py:346: error: Argument 1 to "call_with_async_di" of "Context" has incompatible type "_MessageCallbackSigT"; expected "Callable[..., Coroutine[Any, Any, Never] | Never]"  [arg-type]
- tanjun/commands/menu.py:63: error: Type application is only supported for generic classes  [misc]
- tanjun/commands/menu.py:176: error: "_CallbackishT?[_MessageCallbackSigT`-1]" has no attribute "callback"  [attr-defined]
- tanjun/commands/menu.py:179: error: Statement is unreachable  [unreachable]
- tanjun/commands/menu.py:303: error: "_CallbackishT?[_UserCallbackSigT`-1]" has no attribute "callback"  [attr-defined]
- tanjun/commands/menu.py:306: error: Statement is unreachable  [unreachable]
- tanjun/commands/menu.py:537: error: Unused "type: ignore" comment  [unused-ignore]
- tanjun/commands/menu.py:622: error: "ContextMenuCommandBuilder" has no attribute "set_is_dm_enabled"  [attr-defined]
- tanjun/commands/menu.py:624: error: "ContextMenuCommandBuilder" has no attribute "set_is_dm_enabled"  [attr-defined]
- tanjun/commands/menu.py:689: error: Argument 1 to "call_with_async_di" of "Context" has incompatible type "_AnyMenuCallbackSigT"; expected "Callable[..., Coroutine[Any, Any, Never] | Never]"  [arg-type]
- tanjun/clients.py:1357: error: Argument 1 to "declare_application_commands" of "Client" has incompatible type "chain[ABC]"; expected "Iterable[AppCommand[Any] | CommandBuilder]"  [arg-type]
- tanjun/clients.py:1414: error: "CommandBuilder" has no attribute "is_dm_enabled"  [attr-defined]
- tanjun/clients.py:1415: error: "CommandBuilder" has no attribute "set_is_dm_enabled"  [attr-defined]
- tanjun/clients.py:1492: error: "CommandBuilder" has no attribute "is_dm_enabled"  [attr-defined]
- tanjun/clients.py:1493: error: "CommandBuilder" has no attribute "set_is_dm_enabled"  [attr-defined]
- tanjun/clients.py:2294: error: Argument 1 to "call_with_async_di" of "Context" has incompatible type "Callable[[MessageContext, VarArg(Any), KwArg(Any)], Coroutine[Any, Any, Iterable[str]]]"; expected "Callable[..., Coroutine[Any, Any, Never] | Never]"  [arg-type]
- tanjun/annotations.py:1448: error: Statement is unreachable  [unreachable]
- tanjun/annotations.py:1453: error: Statement is unreachable  [unreachable]
- tanjun/annotations.py:1458: error: Statement is unreachable  [unreachable]
- tanjun/annotations.py:1466: error: Statement is unreachable  [unreachable]
- tanjun/annotations.py:1601: error: Incompatible return value type (got "<typing special form>", expected "type[_T]")  [return-value]
- tanjun/annotations.py:1611: error: Redundant cast to "type[_T]"  [redundant-cast]
- tanjun/annotations.py:1855: error: Incompatible return value type (got "<typing special form>", expected "type[str]")  [return-value]
- tanjun/annotations.py:2268: error: Incompatible return value type (got "<typing special form>", expected "type[PartialChannel]")  [return-value]
+ Traceback (most recent call last):
+   File "", line 8, in <module>
+     sys.exit(console_entry())
+   File "/__main__.py", line 15, in console_entry
+     main()
+   File "/main.py", line 127, in main
+     res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
+   File "/main.py", line 211, in run_build
+     res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
+   File "/build.py", line 191, in build
+     result = _build(
+   File "/build.py", line 267, in _build
+     graph = dispatch(sources, manager, stdout)
+   File "/build.py", line 2939, in dispatch
+     process_graph(graph, manager)
+   File "/build.py", line 3337, in process_graph
+     process_stale_scc(graph, scc, manager)
+   File "/build.py", line 3438, in process_stale_scc
+     graph[id].type_check_first_pass()
+   File "/build.py", line 2311, in type_check_first_pass
+     self.type_checker().check_first_pass()
+   File "/checker.py", line 527, in check_first_pass
+     self.accept(d)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1263, in accept
+     return visitor.visit_class_def(self)
+   File "/checker.py", line 2666, in visit_class_def
+     self.accept(defn.defs)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1344, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 3127, in visit_block
+     self.accept(s)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 874, in accept
+     return visitor.visit_func_def(self)
+   File "/checker.py", line 1195, in visit_func_def
+     self._visit_func_def(defn)
+   File "/checker.py", line 1199, in _visit_func_def
+     self.check_func_item(defn, name=defn.name)
+   File "/checker.py", line 1234, in check_func_item
+     self.check_func_def(defn, typ, name, allow_empty)
+   File "/checker.py", line 1507, in check_func_def
+     self.accept(item.body)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1344, in accept
+     return visitor.visit_block(self)
+   File "/checker.py", line 3127, in visit_block
+     self.accept(s)
+   File "/checker.py", line 638, in accept
+     stmt.accept(self)
+   File "/nodes.py", line 1431, in accept
+     return visitor.visit_assignment_stmt(self)
+   File "/checker.py", line 3178, in visit_assignment_stmt
+     self.check_assignment(s.lvalues[-1], s.rvalue, s.type is None, s.new_syntax)
+   File "/checker.py", line 3390, in check_assignment
+     rvalue_type = self.expr_checker.accept(rvalue, type_context=type_context)
+   File "/checkexpr.py", line 6067, in accept
+     typ = self.accept_maybe_cache(node, type_context=type_context)
+   File "/checkexpr.py", line 6102, in accept_maybe_cache
+     typ = node.accept(self)
+   File "/nodes.py", line 2055, in accept
+     return visitor.visit_call_expr(self)
+            ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
+   File "/checkexpr.py", line 527, in visit_call_expr
+     return self.visit_call_expr_inner(e, allow_none_return=allow_none_return)
+            ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   File "/checkexpr.py", line 661, in visit_call_expr_inner
+     ret_type = self.check_call_expr_with_callee_type(
+         callee_type, e, fullname, object_type, member
+     )
+   File "/checkexpr.py", line 1511, in check_call_expr_with_callee_type
+     ret_type, callee_type = self.check_call(
+                             ~~~~~~~~~~~~~~~^
+         callee_type,
+         ^^^^^^^^^^^^
+     ...<6 lines>...
+         object_type=object_type,
+         ^^^^^^^^^^^^^^^^^^^^^^^^
+     )
+     ^
+   File "/checkexpr.py", line 1604, in check_call
+     return self.check_callable_call(
+            ~~~~~~~~~~~~~~~~~~~~~~~~^
+         callee,
+         ^^^^^^^
+     ...<6 lines>...
+         object_type,
+         ^^^^^^^^^^^^
+     )
+     ^
+   File "/checkexpr.py", line 1828, in check_callable_call
+     self.check_argument_types(
+     ~~~~~~~~~~~~~~~~~~~~~~~~~^
+         arg_types, arg_kinds, args, callee, formal_to_actual, context, object_type=object_type
+         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+     )
+     ^
+   File "/checkexpr.py", line 2635, in check_argument_types
+     expanded_actual = mapper.expand_actual_type(
+         actual_type,
+     ...<3 lines>...
+         allow_unpack=isinstance(callee_arg_type, UnpackType),
+     )
+   File "/argmap.py", line 217, in expand_actual_type
+     self.expand_actual_type(
+     ~~~~~~~~~~~~~~~~~~~~~~~^
+         item,
+         ^^^^^
+     ...<3 lines>...
+         allow_unpack=allow_unpack,
+         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+     )
+     ^
+   File "/argmap.py", line 234, in expand_actual_type
+     item = actual_type.items[self.tuple_index - 1]
+            ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
+ IndexError: list index out of range

zulip (https://github.com/zulip/zulip)
+ zerver/models/lookups.py:17: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
+ https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
+ Please report a bug at https://github.com/python/mypy/issues
+ version: 1.18.0+dev.ef9ed5deb278f3ad66ef5234a79b981e7ef04d40
+ zerver/models/lookups.py:17: : note: use --pdb to drop into pdb
- zerver/lib/queue.py:235: error: Unused "type: ignore" comment  [unused-ignore]
- zerver/lib/queue.py:251: error: Unused "type: ignore" comment  [unused-ignore]
- zerver/migrations/0544_copy_avatar_images.py:135: error: Unused "type: ignore" comment  [unused-ignore]
- zerver/lib/response.py:43: error: Unused "type: ignore" comment  [unused-ignore]
- zerver/tornado/handlers.py:93: error: Unused "type: ignore" comment  [unused-ignore]
- zerver/lib/logging_util.py:257: error: "AbstractBaseUser" has no attribute "delivery_email"  [attr-defined]
- zerver/lib/logging_util.py:257: error: "AbstractBaseUser" has no attribute "realm"  [attr-defined]
- zerver/lib/cache.py:603: error: "UserProfile" has no attribute "realm_id"; maybe "realm"?  [attr-defined]
- zerver/lib/cache.py:608: error: "UserProfile" has no attribute "realm_id"; maybe "realm"?  [attr-defined]
- zerver/lib/cache.py:611: error: "UserProfile" has no attribute "realm_id"; maybe "realm"?  [attr-defined]
- zerver/lib/cache.py:612: error: "UserProfile" has no attribute "realm_id"; maybe "realm"?  [attr-defined]
- zerver/lib/cache.py:615: error: "UserProfile" has no attribute "realm_id"; maybe "realm"?  [attr-defined]
- zerver/lib/cache.py:623: error: "UserProfile" has no attribute "realm_id"; maybe "realm"?  [attr-defined]
- zerver/lib/cache.py:628: error: "MutedUser" has no attribute "muted_user_id"; maybe "muted_user"?  [attr-defined]
- zerver/lib/cache.py:697: error: "Stream" has no attribute "realm_id"; maybe "realm"?  [attr-defined]
- zerver/lib/cache.py:741: error: "SubMessage" has no attribute "message_id"; maybe "message"?  [attr-defined]
- zerver/models/users.py:62: error: Need type annotation for "enter_sends"  [var-annotated]
- zerver/models/users.py:68: error: Need type annotation for "left_side_userlist"  [var-annotated]
- zerver/models/users.py:69: error: Need type annotation for "default_language"  [var-annotated]
- zerver/models/users.py:72: error: Need type annotation for "web_home_view"  [var-annotated]
- zerver/models/users.py:73: error: Need type annotation for "web_escape_navigates_to_home_view"  [var-annotated]
- zerver/models/users.py:74: error: Need type annotation for "fluid_layout_width"  [var-annotated]
- zerver/models/users.py:75: error: Need type annotation for "high_contrast_mode"  [var-annotated]
- zerver/models/users.py:76: error: Need type annotation for "translate_emoticons"  [var-annotated]
- zerver/models/users.py:77: error: Need type annotation for "display_emoji_reaction_users"  [var-annotated]
- zerver/models/users.py:78: error: Need type annotation for "twenty_four_hour_time"  [var-annotated]
- zerver/models/users.py:79: error: Need type annotation for "starred_message_counts"  [var-annotated]
- zerver/models/users.py:80: error: Need type annotation for "web_suggest_update_timezone"  [var-annotated]
- zerver/models/users.py:85: error: Need type annotation for "color_scheme"  [var-annotated]
- zerver/models/users.py:93: error: Need type annotation for "web_font_size_px"  [var-annotated]
- zerver/models/users.py:94: error: Need type annotation for "web_line_height_percent"  [var-annotated]
- zerver/models/users.py:99: error: Need type annotation for "web_animate_image_previews"  [var-annotated]
- zerver/models/users.py:113: error: Need type annotation for "demote_inactive_streams"  [var-annotated]
- zerver/models/users.py:117: error: Need type annotation for "web_left_sidebar_show_channel_folders"  [var-annotated]
- zerver/models/users.py:132: error: Need type annotation for "web_mark_read_on_scroll_policy"  [var-annotated]
- zerver/models/users.py:150: error: Need type annotation for "web_channel_default_view"  [var-annotated]
- zerver/models/users.py:166: error: Need type annotation for "emojiset"  [var-annotated]
- zerver/models/users.py:177: error: Need type annotation for "user_list_style"  [var-annotated]
- zerver/models/users.py:188: error: Need type annotation for "web_stream_unreads_count_display_policy"  [var-annotated]
- zerver/models/users.py:192: error: Need type annotation for "web_left_sidebar_unreads_count_summary"  [var-annotated]
- zerver/models/users.py:196: error: Need type annotation for "web_navigate_to_sent_message"  [var-annotated]
- zerver/models/users.py:200: error: Need type annotation for "email_notifications_batching_period_seconds"  [var-annotated]
- zerver/models/users.py:203: error: Need type annotation for "enable_stream_desktop_notifications"  [var-annotated]
- zerver/models/users.py:204: error: Need type annotation for "enable_stream_email_notifications"  [var-annotated]
- zerver/models/users.py:205: error: Need type annotation for "enable_stream_push_notifications"  [var-annotated]
- zerver/models/users.py:206: error: Need type annotation for "enable_stream_audible_notifications"  [var-annotated]
- zerver/models/users.py:207: error: Need type annotation for "notification_sound"  [var-annotated]
- zerver/models/users.py:208: error: Need type annotation for "wildcard_mentions_notify"  [var-annotated]
- zerver/models/users.py:211: error: Need type annotation for "enable_followed_topic_desktop_notifications"  [var-annotated]
- zerver/models/users.py:212: error: Need type annotation for "enable_followed_topic_email_notifications"  [var-annotated]
- zerver/models/users.py:213: error: Need type annotation for "enable_followed_topic_push_notifications"  [var-annotated]
- zerver/models/users.py:214: error: Need type annotation for "enable_followed_topic_audible_notifications"  [var-annotated]
- zerver/models/users.py:215: error: Need type annotation for "enable_followed_topic_wildcard_mentions_notify"  [var-annotated]
- zerver/models/users.py:218: error: Need type annotation for "enable_desktop_notifications"  [var-annotated]
- zerver/models/users.py:219: error: Need type annotation for "pm_content_in_desktop_notifications"  [var-annotated]
- zerver/models/users.py:220: error: Need type annotation for "enable_sounds"  [var-annotated]
- zerver/models/users.py:221: error: Need type annotation for "enable_offline_email_notifications"  [var-annotated]
- zerver/models/users.py:222: error: Need type annotation for "message_content_in_email_notifications"  [var-annotated]
- zerver/models/users.py:223: error: Need type annotation for "enable_offline_push_notifications"  [var-annotated]
- zerver/models/users.py:224: error: Need type annotation for "enable_online_push_notifications"  [var-annotated]
- zerver/models/users.py:236: error: Need type annotation for "desktop_icon_count_display"  [var-annotated]
- zerver/models/users.py:240: error: Need type annotation for "enable_digest_emails"  [var-annotated]
- zerver/models/users.py:241: error: Need type annotation for "enable_login_emails"  [var-annotated]
- zerver/models/users.py:242: error: Need type annotation for "enable_marketing_emails"  [var-annotated]
- zerver/models/users.py:243: error: Need type annotation for "presence_enabled"  [var-annotated]
- zerver/models/users.py:253: error: Need type annotation for "realm_name_in_email_notifications_policy"  [var-annotated]
- zerver/models/users.py:274: error: Need type annotation for "automatically_follow_topics_policy"  [var-annotated]
- zerver/models/users.py:277: error: Need type annotation for "automatically_unmute_topics_in_muted_streams_policy"  [var-annotated]
- zerver/models/users.py:280: error: Need type annotation for "automatically_follow_topics_where_mentioned"  [var-annotated]
- zerver/models/users.py:282: error: Need type annotation for "resolved_topic_notice_auto_read_policy"  [var-annotated]
- zerver/models/users.py:289: error: Need type annotation for "enable_drafts_synchronization"  [var-annotated]
- zerver/models/users.py:292: error: Need type annotation for "send_stream_typing_notifications"  [var-annotated]
- zerver/models/users.py:293: error: Need type annotation for "send_private_typing_notifications"  [var-annotated]
- zerver/models/users.py:294: error: Need type annotation for "send_read_receipts"  [var-annotated]
- zerver/models/users.py:295: error: Need type annotation for "allow_private_data_export"  [var-annotated]
- zerver/models/users.py:298: error: Need type annotation for "receives_typing_notifications"  [var-annotated]
- zerver/models/users.py:309: error: Need type annotation for "email_address_visibility"  [var-annotated]
- zerver/models/users.py:324: error: Need type annotation for "hide_ai_features"  [var-annotated]
- zerver/models/users.py:456: error: Need type annotation for "realm"  [var-annotated]
- zerver/models/users.py:494: error: Need type annotation for "id"  [var-annotated]
- zerver/models/users.py:512: error: Need type annotation for "delivery_email"  [var-annotated]
- zerver/models/users.py:513: error: Need type annotation for "email"  [var-annotated]
- zerver/models/users.py:515: error: Need type annotation for "realm"  [var-annotated]
- zerver/models/users.py:517: error: Need type annotation for "recipient"  [var-annotated]
- zerver/models/users.py:526: error: Need type annotation for "full_name"  [var-annotated]
- zerver/models/users.py:528: error: Need type annotation for "date_joined"  [var-annotated]
- zerver/models/users.py:536: error: Need type annotation for "tos_version"  [var-annotated]
- zerver/models/users.py:537: error: Need type annotation for "api_key"  [var-annotated]
- zerver/models/users.py:543: error: Need type annotation for "uuid"  [var-annotated]
- zerver/models/users.py:546: error: Need type annotation for "is_staff"  [var-annotated]
- zerver/models/users.py:553: error: Need type annotation for "is_active"  [var-annotated]
- zerver/models/users.py:555: error: Need type annotation for "is_bot"  [var-annotated]
- zerver/models/users.py:556: error: Need type annotation for "bot_type"  [var-annotated]
- zerver/models/users.py:557: error: Need type annotation for "bot_owner"  [var-annotated]
- zerver/models/users.py:569: error: Need type annotation for "role"  [var-annotated]
- zerver/models/users.py:611: error: Need type annotation for "long_term_idle"  [var-annotated]
- zerver/models/users.py:614: error: Need type annotation for "last_active_message_id"  [var-annotated]
- zerver/models/users.py:620: error: Need type annotation for "is_mirror_dummy"  [var-annotated]
- zerver/models/users.py:624: error: Need type annotation for "can_forge_sender"  [var-annotated]
- zerver/models/users.py:626: error: Need type annotation for "can_create_users"  [var-annotated]
- zerver/models/users.py:628: error: Need type annotation for "can_change_user_emails"  [var-annotated]
- zerver/models/users.py:631: error: Need type annotation for "last_reminder"  [var-annotated]
- zerver/models/users.py:638: error: Need type annotation for "rate_limits"  [var-annotated]
- zerver/models/users.py:641: error: Need type annotation for "default_sending_stream"  [var-annotated]
- zerver/models/users.py:647: error: Need type annotation for "default_events_register_stream"  [var-annotated]
- zerver/models/users.py:653: error: Need type annotation for "default_all_public_streams"  [var-annotated]
- zerver/models/users.py:663: error: Need type annotation for "timezone"  [var-annotated]
- zerver/models/users.py:671: error: Need type annotation for "avatar_source"  [var-annotated]
- zerver/models/users.py:674: error: Need type annotation for "avatar_version"  [var-annotated]
- zerver/models/users.py:678: error: Need type annotation for "avatar_hash"  [var-annotated]
- zerver/models/users.py:733: error: "CustomProfileFieldValue" has no attribute "field_id"; maybe "field"?  [attr-defined]

... (truncated 1945 lines) ...```

Comment on lines +217 to +225
self.expand_actual_type(
item,
actual_kind=actual_kind,
formal_name=formal_name,
formal_kind=formal_kind,
allow_unpack=allow_unpack,
)
for item in actual_type.items
]
Copy link
Contributor

@randolf-scholz randolf-scholz Aug 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work because the mapper has mutable state (self.tuple_index), so one would need to create multiple copies of the current mapper and apply them independently.

But then this will run into problems if the union is of differently sized tuple, since then you end up with incongruent state across the different copies.

Solving this problem generally seems intractable due to combinatorial explosion: consider f(*x1, *x2, ..., *xn). If each $x_k$ is comprised of a union of $m_k$ differently sized tuples, then there are $m_1⋅m_2⋅…⋅m_k$ possible paths.

So at best I think one can do this union splitting if the Union doesn't contain tuples, or if all contained tuples are of equal length.

@randolf-scholz
Copy link
Contributor

randolf-scholz commented Aug 15, 2025

Mind taking a look at #19651? (it got bigger than I initially intended, but if improves the inference in quite a few cases and the primer finds quite a few errors that went previously undetected)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants