mypy
mypy copied to clipboard
Crash on `run_in_executor`
Mypy crashes on loop.run_in_executor
with the message "Parameters cannot be constrained to"
(A clear and concise description of what the bug is.)
Run mypy aio_processes.py
aio_processes.py:
import asyncio
import typing as tp
from concurrent.futures import ProcessPoolExecutor
P = tp.ParamSpec("P")
R = tp.TypeVar("R")
# additional wrapper since run_in_executor doesn't accept kwargs
def _call(
func: tp.Callable[..., R],
args: tp.Any,
kwargs: tp.Any,
) -> R:
return func(*args, **kwargs)
async def to_process(func: tp.Callable[P, R], *args: P.args, **kwargs: P.kwargs) -> R:
"""
execute a function in a subprocess managed by asyncio
WARNING: args and kwargs will be pickled to be sent to the subprocess
this can be expensive, especially if you are sending large data structures (i.e. DataFrames)
NOTE: asyncio provides a similar function, `to_thread`, which is useful to take advantage of
the event loop for IO-bound code, without needing to pickle args and kwargs
"""
with ProcessPoolExecutor(max_workers=1) as ppe:
loop = asyncio.get_running_loop()
result = await loop.run_in_executor(ppe, _call, func, args, kwargs)
return result
Expected Behavior
Mypy type-checks the file
Actual Behavior
Mypy crashes
$ mypy aio_processes.py --show-traceback
aio_processes.py:30: 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.10.0+dev.e2fc1f28935806ca04b18fab277217f583b51594
Traceback (most recent call last):
File "/home/peters/src-me/proc_aio_mypy/venv/bin/mypy", line 8, in <module>
sys.exit(console_entry())
File "/home/peters/src-others/mypy/mypy/__main__.py", line 15, in console_entry
main()
File "/home/peters/src-others/mypy/mypy/main.py", line 100, in main
res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
File "/home/peters/src-others/mypy/mypy/main.py", line 182, in run_build
res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
File "/home/peters/src-others/mypy/mypy/build.py", line 192, in build
result = _build(
File "/home/peters/src-others/mypy/mypy/build.py", line 266, in _build
graph = dispatch(sources, manager, stdout)
File "/home/peters/src-others/mypy/mypy/build.py", line 2942, in dispatch
process_graph(graph, manager)
File "/home/peters/src-others/mypy/mypy/build.py", line 3340, in process_graph
process_stale_scc(graph, scc, manager)
File "/home/peters/src-others/mypy/mypy/build.py", line 3441, in process_stale_scc
graph[id].type_check_first_pass()
File "/home/peters/src-others/mypy/mypy/build.py", line 2310, in type_check_first_pass
self.type_checker().check_first_pass()
File "/home/peters/src-others/mypy/mypy/checker.py", line 481, in check_first_pass
self.accept(d)
File "/home/peters/src-others/mypy/mypy/checker.py", line 589, in accept
stmt.accept(self)
File "/home/peters/src-others/mypy/mypy/nodes.py", line 787, in accept
return visitor.visit_func_def(self)
File "/home/peters/src-others/mypy/mypy/checker.py", line 1000, in visit_func_def
self._visit_func_def(defn)
File "/home/peters/src-others/mypy/mypy/checker.py", line 1004, in _visit_func_def
self.check_func_item(defn, name=defn.name)
File "/home/peters/src-others/mypy/mypy/checker.py", line 1077, in check_func_item
self.check_func_def(defn, typ, name, allow_empty)
File "/home/peters/src-others/mypy/mypy/checker.py", line 1309, in check_func_def
self.accept(item.body)
File "/home/peters/src-others/mypy/mypy/checker.py", line 589, in accept
stmt.accept(self)
File "/home/peters/src-others/mypy/mypy/nodes.py", line 1223, in accept
return visitor.visit_block(self)
File "/home/peters/src-others/mypy/mypy/checker.py", line 2802, in visit_block
self.accept(s)
File "/home/peters/src-others/mypy/mypy/checker.py", line 589, in accept
stmt.accept(self)
File "/home/peters/src-others/mypy/mypy/nodes.py", line 1579, in accept
return visitor.visit_with_stmt(self)
File "/home/peters/src-others/mypy/mypy/checker.py", line 5033, in visit_with_stmt
self.accept(s.body)
File "/home/peters/src-others/mypy/mypy/checker.py", line 589, in accept
stmt.accept(self)
File "/home/peters/src-others/mypy/mypy/nodes.py", line 1223, in accept
return visitor.visit_block(self)
File "/home/peters/src-others/mypy/mypy/checker.py", line 2802, in visit_block
self.accept(s)
File "/home/peters/src-others/mypy/mypy/checker.py", line 589, in accept
stmt.accept(self)
File "/home/peters/src-others/mypy/mypy/nodes.py", line 1310, in accept
return visitor.visit_assignment_stmt(self)
File "/home/peters/src-others/mypy/mypy/checker.py", line 2850, in visit_assignment_stmt
self.check_assignment(s.lvalues[-1], s.rvalue, s.type is None, s.new_syntax)
File "/home/peters/src-others/mypy/mypy/checker.py", line 3058, in check_assignment
rvalue_type = self.expr_checker.accept(rvalue, type_context=type_context)
File "/home/peters/src-others/mypy/mypy/checkexpr.py", line 5760, in accept
typ = node.accept(self)
File "/home/peters/src-others/mypy/mypy/nodes.py", line 2763, in accept
return visitor.visit_await_expr(self)
File "/home/peters/src-others/mypy/mypy/checkexpr.py", line 5893, in visit_await_expr
actual_type = get_proper_type(self.accept(e.expr, expected_type))
File "/home/peters/src-others/mypy/mypy/checkexpr.py", line 5760, in accept
typ = node.accept(self)
^^^^^^^^^^^^^^^^^
File "/home/peters/src-others/mypy/mypy/nodes.py", line 1907, in accept
return visitor.visit_call_expr(self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peters/src-others/mypy/mypy/checkexpr.py", line 476, in visit_call_expr
return self.visit_call_expr_inner(e, allow_none_return=allow_none_return)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peters/src-others/mypy/mypy/checkexpr.py", line 605, in visit_call_expr_inner
ret_type = self.check_call_expr_with_callee_type(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peters/src-others/mypy/mypy/checkexpr.py", line 1456, in check_call_expr_with_callee_type
ret_type, callee_type = self.check_call(
^^^^^^^^^^^^^^^^
File "/home/peters/src-others/mypy/mypy/checkexpr.py", line 1550, in check_call
return self.check_callable_call(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peters/src-others/mypy/mypy/checkexpr.py", line 1735, in check_callable_call
callee = self.infer_function_type_arguments(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peters/src-others/mypy/mypy/checkexpr.py", line 2123, in infer_function_type_arguments
poly_inferred_args, free_vars = infer_function_type_arguments(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peters/src-others/mypy/mypy/infer.py", line 62, in infer_function_type_arguments
return solve_constraints(type_vars, constraints, strict, allow_polymorphic)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peters/src-others/mypy/mypy/solve.py", line 84, in solve_constraints
solutions, free_vars = solve_with_dependent(
^^^^^^^^^^^^^^^^^^^^^
File "/home/peters/src-others/mypy/mypy/solve.py", line 144, in solve_with_dependent
graph, lowers, uppers = transitive_closure(vars, constraints)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peters/src-others/mypy/mypy/solve.py", line 446, in transitive_closure
add_secondary_constraints(remaining, lt, c.target)
File "/home/peters/src-others/mypy/mypy/solve.py", line 470, in add_secondary_constraints
cs.update(set(infer_constraints(upper, lower, SUPERTYPE_OF)))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peters/src-others/mypy/mypy/constraints.py", line 314, in infer_constraints
return _infer_constraints(template, actual, direction, skip_neg_op)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peters/src-others/mypy/mypy/constraints.py", line 407, in _infer_constraints
return template.accept(ConstraintBuilderVisitor(actual, direction, skip_neg_op))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peters/src-others/mypy/mypy/types.py", line 1730, in accept
return visitor.visit_parameters(self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/peters/src-others/mypy/mypy/constraints.py", line 698, in visit_parameters
raise RuntimeError("Parameters cannot be constrained to")
RuntimeError: Parameters cannot be constrained to
aio_processes.py:30: : note: use --pdb to drop into pdb
Your Environment
$ pip freeze
-e file:///.../mypy
mypy-extensions==1.0.0
typing-extensions==4.11.0
- Mypy version used: mypy 1.10.0+dev.e2fc1f28935806ca04b18fab277217f583b51594 (compiled: no)
- This also fails on 1.9.0
- Mypy command-line flags:
--show-traceback
- Mypy configuration options from
mypy.ini
(and other config files): None - Python version used: 3.11.4