Skip to content
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

INTERNAL ERROR RuntimeError in visit_erased_type with mypy 0.930 #11913

Closed
jstewmon opened this issue Jan 5, 2022 · 4 comments · Fixed by #11924
Closed

INTERNAL ERROR RuntimeError in visit_erased_type with mypy 0.930 #11913

jstewmon opened this issue Jan 5, 2022 · 4 comments · Fixed by #11924
Labels

Comments

@jstewmon
Copy link

jstewmon commented Jan 5, 2022

Crash Report

mypy 0.930 crashes while checking sources. mypy 0.921 passes for the same file.

Traceback

repro.py:26: 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: 0.930
Traceback (most recent call last):
  File "/usr/local/bin/mypy", line 8, in <module>
    sys.exit(console_entry())
  File "/usr/local/lib/python3.8/site-packages/mypy/__main__.py", line 12, in console_entry
    main(None, sys.stdout, sys.stderr)
  File "/usr/local/lib/python3.8/site-packages/mypy/main.py", line 96, in main
    res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
  File "/usr/local/lib/python3.8/site-packages/mypy/main.py", line 173, in run_build
    res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
  File "/usr/local/lib/python3.8/site-packages/mypy/build.py", line 180, in build
    result = _build(
  File "/usr/local/lib/python3.8/site-packages/mypy/build.py", line 256, in _build
    graph = dispatch(sources, manager, stdout)
  File "/usr/local/lib/python3.8/site-packages/mypy/build.py", line 2717, in dispatch
    process_graph(graph, manager)
  File "/usr/local/lib/python3.8/site-packages/mypy/build.py", line 3048, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/usr/local/lib/python3.8/site-packages/mypy/build.py", line 3146, in process_stale_scc
    graph[id].type_check_first_pass()
  File "/usr/local/lib/python3.8/site-packages/mypy/build.py", line 2185, in type_check_first_pass
    self.type_checker().check_first_pass()
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 314, in check_first_pass
    self.accept(d)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 420, in accept
    stmt.accept(self)
  File "/usr/local/lib/python3.8/site-packages/mypy/nodes.py", line 727, in accept
    return visitor.visit_func_def(self)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 770, in visit_func_def
    self._visit_func_def(defn)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 774, in _visit_func_def
    self.check_func_item(defn, name=defn.name)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 836, in check_func_item
    self.check_func_def(defn, typ, name)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 1021, in check_func_def
    self.accept(item.body)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 420, in accept
    stmt.accept(self)
  File "/usr/local/lib/python3.8/site-packages/mypy/nodes.py", line 1074, in accept
    return visitor.visit_block(self)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 2047, in visit_block
    self.accept(s)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 420, in accept
    stmt.accept(self)
  File "/usr/local/lib/python3.8/site-packages/mypy/nodes.py", line 1231, in accept
    return visitor.visit_return_stmt(self)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 3332, in visit_return_stmt
    self.check_return_stmt(s)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 3364, in check_return_stmt
    typ = get_proper_type(self.expr_checker.accept(
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 3962, in accept
    typ = node.accept(self)
  File "/usr/local/lib/python3.8/site-packages/mypy/nodes.py", line 1713, in accept
    return visitor.visit_call_expr(self)
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 288, in visit_call_expr
    return self.visit_call_expr_inner(e, allow_none_return=allow_none_return)
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 371, in visit_call_expr_inner
    ret_type = self.check_call_expr_with_callee_type(callee_type, e, fullname,
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 878, in check_call_expr_with_callee_type
    return self.check_call(callee_type, e.args, e.arg_kinds, e,
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 938, in check_call
    return self.check_callable_call(callee, args, arg_kinds, context, arg_names,
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 1047, in check_callable_call
    arg_types = self.infer_arg_types_in_context(
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 1146, in infer_arg_types_in_context
    res[ai] = self.accept(args[ai], callee.arg_types[i])
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 3962, in accept
    typ = node.accept(self)
  File "/usr/local/lib/python3.8/site-packages/mypy/nodes.py", line 1713, in accept
    return visitor.visit_call_expr(self)
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 288, in visit_call_expr
    return self.visit_call_expr_inner(e, allow_none_return=allow_none_return)
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 371, in visit_call_expr_inner
    ret_type = self.check_call_expr_with_callee_type(callee_type, e, fullname,
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 878, in check_call_expr_with_callee_type
    return self.check_call(callee_type, e.args, e.arg_kinds, e,
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 942, in check_call
    return self.check_overload_call(callee, args, arg_kinds, arg_names, callable_name,
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 1620, in check_overload_call
    inferred_result = self.infer_overload_return_type(plausible_targets, args, arg_types,
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 1762, in infer_overload_return_type
    ret_type, infer_type = self.check_call(
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 938, in check_call
    return self.check_callable_call(callee, args, arg_kinds, context, arg_names,
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 1025, in check_callable_call
    callee = self.infer_function_type_arguments(
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 1246, in infer_function_type_arguments
    arg_types = self.infer_arg_types_in_context(
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 1146, in infer_arg_types_in_context
    res[ai] = self.accept(args[ai], callee.arg_types[i])
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 3962, in accept
    typ = node.accept(self)
  File "/usr/local/lib/python3.8/site-packages/mypy/nodes.py", line 1957, in accept
    return visitor.visit_lambda_expr(self)
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 3564, in visit_lambda_expr
    self.chk.check_func_item(e, type_override=type_override)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 836, in check_func_item
    self.check_func_def(defn, typ, name)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 1021, in check_func_def
    self.accept(item.body)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 420, in accept
    stmt.accept(self)
  File "/usr/local/lib/python3.8/site-packages/mypy/nodes.py", line 1074, in accept
    return visitor.visit_block(self)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 2047, in visit_block
    self.accept(s)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 420, in accept
    stmt.accept(self)
  File "/usr/local/lib/python3.8/site-packages/mypy/nodes.py", line 1231, in accept
    return visitor.visit_return_stmt(self)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 3332, in visit_return_stmt
    self.check_return_stmt(s)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 3364, in check_return_stmt
    typ = get_proper_type(self.expr_checker.accept(
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 3960, in accept
    typ = self.visit_conditional_expr(node, allow_none_return=True)
  File "/usr/local/lib/python3.8/site-packages/mypy/checkexpr.py", line 3878, in visit_conditional_expr
    if_map, else_map = self.chk.find_isinstance_check(e.cond)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 4313, in find_isinstance_check
    if_map, else_map = self.find_isinstance_check_helper(node)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 4331, in find_isinstance_check_helper
    return self.conditional_type_map_with_intersection(
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 5294, in conditional_type_map_with_intersection
    initial_maps = conditional_type_map(expr, expr_type, type_ranges)
  File "/usr/local/lib/python3.8/site-packages/mypy/checker.py", line 5378, in conditional_type_map
    remaining_type = restrict_subtype_away(current_type, proposed_precise_type)
  File "/usr/local/lib/python3.8/site-packages/mypy/subtypes.py", line 1165, in restrict_subtype_away
    elif covers_at_runtime(t, s, ignore_promotions):
  File "/usr/local/lib/python3.8/site-packages/mypy/subtypes.py", line 1177, in covers_at_runtime
    if is_proper_subtype(erase_type(item), supertype, ignore_promotions=ignore_promotions,
  File "/usr/local/lib/python3.8/site-packages/mypy/erasetype.py", line 25, in erase_type
    return typ.accept(EraseTypeVisitor())
  File "/usr/local/lib/python3.8/site-packages/mypy/types.py", line 868, in accept
    return visitor.visit_erased_type(self)
  File "/usr/local/lib/python3.8/site-packages/mypy/erasetype.py", line 45, in visit_erased_type
    raise RuntimeError()
RuntimeError:
repro.py:26: : note: use --pdb to drop into pdb

To Reproduce

import typing as t
from enum import Enum


T = t.TypeVar("T", bound="DataType")
E = t.TypeVar("E", bound=Enum)
Coll = t.Collection


class DataType:

    @classmethod
    def from_dict(cls: t.Type[T], dictionary: t.Dict[str, t.Any]) -> T:
        return cls(**dictionary)

def collection_from_dict_value(
    collection_constructor: t.Callable[[t.Iterable[T]], t.Collection[T]],
    model: t.Type[T],
    key: str,
    dictionary: t.Dict[str, t.Any],
) -> t.Collection[T]:
    """Collect an iterable of models out of a dict key."""
    return collection_constructor(
        map(
            lambda i: i if isinstance(i, model) else model.from_dict(i),
            dictionary.get(key, ()),
        )
    )

Your Environment

  • Mypy version used: 0.930
  • Mypy command-line flags: n/a
  • Mypy configuration options from mypy.ini (and other config files):
     [mypy]
     check_untyped_defs = True
     follow_imports = silent
     ignore_missing_imports = True
     show_column_numbers = True
     warn_return_any = True
     warn_unused_ignores = True
  • Python version used: CPython 3.8.12
  • Operating system and version: python:3.8.12-slim-buster docker image Linux 651e14d4c89a 5.10.76-linuxkit #1 SMP PREEMPT Mon Nov 8 11:22:26 UTC 2021 aarch64 GNU/Linux
@hauntsaninja
Copy link
Collaborator

hauntsaninja commented Jan 6, 2022

Thanks for the great report!

Bisects to #11273, cc @sobolevn

@hauntsaninja
Copy link
Collaborator

Minimised the repro a little bit:

from typing import Callable, Iterable, TypeVar

class DataType: ...

T = TypeVar("T", bound=DataType)

def collection_from_dict_value(model: type[T]) -> None:
    map(
        lambda i: i if isinstance(i, model) else i,
        ["asdf"]
    )

@hauntsaninja
Copy link
Collaborator

hauntsaninja commented Jan 6, 2022

One mechanical fix is to just make sure t is never an ErasedType, e.g.:

diff --git a/mypy/subtypes.py b/mypy/subtypes.py
index b145745c3..d8e594bb7 100644
--- a/mypy/subtypes.py
+++ b/mypy/subtypes.py
@@ -1138,7 +1138,7 @@ def restrict_subtype_away(t: Type, s: Type, *, ignore_promotions: bool = False)
                      if (isinstance(get_proper_type(item), AnyType) or
                          not covers_at_runtime(item, s, ignore_promotions))]
         return UnionType.make_union(new_items)
-    elif covers_at_runtime(t, s, ignore_promotions):
+    elif not isinstance(t, ErasedType) and covers_at_runtime(t, s, ignore_promotions):
         return UninhabitedType()
     else:
         return t

But I don't yet understand the issue well enough to know if that's the right thing to do.

@sobolevn
Copy link
Member

sobolevn commented Jan 6, 2022

@hauntsaninja thanks for the minimal repro, I will check it out.

JukkaL pushed a commit that referenced this issue Jan 7, 2022
JukkaL pushed a commit that referenced this issue Jan 7, 2022
tushar-deepsource pushed a commit to DeepSourceCorp/mypy that referenced this issue Jan 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants