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 when overriding a generic variable in __init__ #5846

Closed
d-chambers opened this issue Oct 27, 2018 · 6 comments · Fixed by #7235
Closed

Internal Error when overriding a generic variable in __init__ #5846

d-chambers opened this issue Oct 27, 2018 · 6 comments · Fixed by #7235

Comments

@d-chambers
Copy link

This is a bug report.

I created a simple python file called breakmypy.py which has the following contents:

# contents of breakmypy.py
from collections import UserDict

class MyDict(UserDict):
    def __init__(self):
        self.data: dict = {}

When I run mypy breakmypy.py --show-traceback the following output is emitted:

breakmypy.py:14: error: INTERNAL ERROR -- please report a bug at https://github.com/python/mypy/issues version: 0.630

Traceback (most recent call last):
  File "/home/derrick_chambers/anaconda3/bin/mypy", line 11, in <module>
    sys.exit(console_entry())
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/__main__.py", line 7, in console_entry
    main(None)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/main.py", line 91, in main
    res = type_check_only(sources, bin_dir, options, flush_errors, fscache)  # noqa
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/main.py", line 148, in type_check_only
    fscache=fscache)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/build.py", line 183, in build
    flush_errors, fscache)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/build.py", line 356, in _build
    graph = dispatch(sources, manager)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/build.py", line 2543, in dispatch
    process_graph(graph, manager)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/build.py", line 2840, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/build.py", line 2963, in process_stale_scc
    graph[id].type_check_first_pass()
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/build.py", line 2103, in type_check_first_pass
    self.type_checker().check_first_pass()
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/checker.py", line 256, in check_first_pass
    self.accept(d)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/checker.py", line 355, in accept
    stmt.accept(self)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/nodes.py", line 820, in accept
    return visitor.visit_class_def(self)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/checker.py", line 1461, in visit_class_def
    self.accept(defn.defs)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/checker.py", line 355, in accept
    stmt.accept(self)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/nodes.py", line 885, in accept
    return visitor.visit_block(self)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/checker.py", line 1607, in visit_block
    self.accept(s)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/checker.py", line 355, in accept
    stmt.accept(self)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/nodes.py", line 603, in accept
    return visitor.visit_func_def(self)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/checker.py", line 666, in visit_func_def
    self._visit_func_def(defn)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/checker.py", line 670, in _visit_func_def
    self.check_func_item(defn, name=defn.name())
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/checker.py", line 732, in check_func_item
    self.check_func_def(defn, typ, name)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/checker.py", line 898, in check_func_def
    self.accept(item.body)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/checker.py", line 355, in accept
    stmt.accept(self)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/nodes.py", line 885, in accept
    return visitor.visit_block(self)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/checker.py", line 1607, in visit_block
    self.accept(s)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/checker.py", line 355, in accept
    stmt.accept(self)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/nodes.py", line 933, in accept
    return visitor.visit_assignment_stmt(self)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/checker.py", line 1614, in visit_assignment_stmt
    self.check_assignment(s.lvalues[-1], s.rvalue, s.type is None, s.new_syntax)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/checker.py", line 1663, in check_assignment
    if self.check_compatibility_all_supers(lvalue, lvalue_type, rvalue):
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/checker.py", line 1755, in check_compatibility_all_supers
    base_type, base_node = self.lvalue_type_from_base(lvalue_node, base)
  File "/home/derrick_chambers/anaconda3/lib/python3.7/site-packages/mypy/checker.py", line 1842, in lvalue_type_from_base
    assert self_type is not None, "Internal error: base lookup outside class"
AssertionError: Internal error: base lookup outside class
breakmypy.py:14: : note: use --pdb to drop into pdb
@ilevkivskyi
Copy link
Member

This still crashes on master, here is a bit more self-contained repro:

from typing import Generic, TypeVar, Any

T = TypeVar('T')

class B(Generic[T]):
    x: T

class C(B):
    def __init__(self) -> None:
        self.x: Any

It actually crashes in several similar scenarios, the only requirement is that the variable type in a base class is generic, and it is overridden in a method, I wonder how no one found this before.

This happens in the part of code that I never understood, there is a method called active_self_type(), but it always returns None at method scope.

@ilevkivskyi ilevkivskyi changed the title Internal Failure using UserDict subclass Internal Error when overriding a generic variable in __ini__ Oct 28, 2018
@ilevkivskyi ilevkivskyi changed the title Internal Error when overriding a generic variable in __ini__ Internal Error when overriding a generic variable in __init__ Nov 2, 2018
@ilevkivskyi
Copy link
Member

This crash appeared again in #6033

@Levitanus
Copy link

in addition
input_python_file.txt
traceback.txt

@wiml
Copy link

wiml commented Feb 20, 2019

I just hit this crash in version 0.670 (and 0.660); my minimized case is very similar to the one in ilevkivskyi's comment.

@mthuurne
Copy link
Contributor

I hit this error in mypy 0.701, also with a method that overrides the type of a base class member that was generic in the base class.

@mthuurne
Copy link
Contributor

I found a workaround:

from typing import Generic, TypeVar, TYPE_CHECKING

T = TypeVar('T')

class B(Generic[T]):
    x: T

class C(B[int]):

    if TYPE_CHECKING:
        @property
        def x(self) -> str: # type: ignore
            return self.x

reveal_type(C().x)

ilevkivskyi added a commit that referenced this issue Jul 18, 2019
Fixes #5846

The fix for crash is kind of straightforward. Previously `active_self_type()` always returned `None` at method scope (sic!)

While working on this I discovered couple other problems:
* Area around checking LSP is generally problematic (see also #5425 that I tried to fix earlier but failed). In particular, the are two ways to get current `TypeInfo`, one is from `lvalue.node.info` or `defn.info`, another is using `active_self_type()` (this is rather abusing it IMO). I don't try to fix this here (i.e. switch to always using one way) because this is a relatively large refactoring.
* Currently in type checker we defer nested functions instead of top-level ones. I believe this is not by design and is rather caused by absence of docstrings and unintuitive method names in `CheckerScope` class. Namely, there "top function" stays for "top of stack function", not "top-level function". I don't try to fix this here either because this is conceptually a big change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants