Skip to content

internal error when inferring type of callable resulting from untyped ternary expression #9234

@e-dorigatti

Description

@e-dorigatti

Consider the following example:

import random
from typing import Union, Callable


class Wrapper:
    def __init__(self, x):
        self.x = x

def main() -> Union[Wrapper, int]:
    wrap = Wrapper if random.random() < 0.5 else lambda x: x
    return wrap(2)

Running mypy (from the master branch in the repo) on it crashes with the following stack trace:

mypytest.py:18: error: INTERNAL ERROR -- Please try using mypy master on Github:
https://mypy.rtfd.io/en/latest/common_issues.html#using-a-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 0.790+dev.cc46692020ef6b672b761512095fbba281fdefc7
Traceback (most recent call last):
  File "/home/edo/miniconda3/envs/abm2/bin/mypy", line 8, in <module>
    sys.exit(console_entry())
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/__main__.py", line 8, in console_entry
    main(None, sys.stdout, sys.stderr)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/main.py", line 89, in main
    res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/build.py", line 180, in build
    result = _build(
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/build.py", line 252, in _build
    graph = dispatch(sources, manager, stdout)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/build.py", line 2626, in dispatch
    process_graph(graph, manager)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/build.py", line 2949, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/build.py", line 3047, in process_stale_scc
    graph[id].type_check_first_pass()
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/build.py", line 2107, in type_check_first_pass
    self.type_checker().check_first_pass()
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/checker.py", line 294, in check_first_pass
    self.accept(d)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/checker.py", line 401, in accept
    stmt.accept(self)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/nodes.py", line 677, in accept
    return visitor.visit_func_def(self)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/checker.py", line 726, in visit_func_def
    self._visit_func_def(defn)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/checker.py", line 730, in _visit_func_def
    self.check_func_item(defn, name=defn.name)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/checker.py", line 792, in check_func_item
    self.check_func_def(defn, typ, name)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/checker.py", line 975, in check_func_def
    self.accept(item.body)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/checker.py", line 401, in accept
    stmt.accept(self)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/nodes.py", line 1005, in accept
    return visitor.visit_block(self)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/checker.py", line 1973, in visit_block
    self.accept(s)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/checker.py", line 401, in accept
    stmt.accept(self)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/nodes.py", line 1141, in accept
    return visitor.visit_return_stmt(self)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/checker.py", line 3156, in visit_return_stmt
    self.check_return_stmt(s)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/checker.py", line 3188, in check_return_stmt
    typ = get_proper_type(self.expr_checker.accept(
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/checkexpr.py", line 3768, in accept
    typ = node.accept(self)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/nodes.py", line 1545, in accept
    return visitor.visit_call_expr(self)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/checkexpr.py", line 263, in visit_call_expr
    return self.visit_call_expr_inner(e, allow_none_return=allow_none_return)
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/checkexpr.py", line 340, in visit_call_expr_inner
    ret_type = self.check_call_expr_with_callee_type(callee_type, e, fullname,
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/checkexpr.py", line 817, in check_call_expr_with_callee_type
    return self.check_call(callee_type, e.args, e.arg_kinds, e,
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/checkexpr.py", line 876, in check_call
    return self.check_callable_call(callee, args, arg_kinds, context, arg_names,
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/checkexpr.py", line 941, in check_callable_call
    if (callee.is_type_obj() and callee.type_object().is_abstract
  File "/home/edo/miniconda3/envs/abm2/lib/python3.8/site-packages/mypy/types.py", line 1094, in type_object
    assert isinstance(ret, Instance)
AssertionError:
mypytest.py:18: : note: use --pdb to drop into pdb

Where ret is Any and callee in the frame above is def (x: Any) -> Any.

The error can be prevented either by assigning the lambda to a variable

    identity = lambda x: x
    wrap = Wrapper if random.random() < 0.5 else identity

where in this case no issues are reported, or the wrapper:

class Wrapper:
    def __init__(self, x: int) -> None:
        self.x = x

def main() -> Union[Wrapper, int]:
     wrap = Wrapper if random.random() < 0.5 else lambda x: x

but in this case two errors are reported (line 12 is wrap = and line 14 is return

mypytest.py:12: error: Incompatible return value type (got "int", expected "Wrapper")
mypytest.py:14: error: Incompatible return value type (got "object", expected "Union[Wrapper, int]")

these erros do not occur when both fixes are applied.

expected behavior: no errors reported in all three cases, or at least no crash.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions