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

crash on decorated method redefinition + circular imports #1972

Closed
dmoisset opened this issue Aug 1, 2016 · 6 comments
Closed

crash on decorated method redefinition + circular imports #1972

dmoisset opened this issue Aug 1, 2016 · 6 comments

Comments

@dmoisset
Copy link
Contributor

dmoisset commented Aug 1, 2016

Mypy crashes with an internal crash on this multi-file package. The example code doesn't make much sense (I arrived to it by trimming a much larger project that's crashing mypy), but I should probably just get errors. If I have the following three files:

# foo/__init__.py
from .derived import *

# foo/base.py
from . import *

class Base:
    @decorator
    def method(self) -> None:
        pass

# foo/derived.py
from .base import Base

class Derived(Base):
    def method(self) -> None:
        pass

And then I run mypy foo/base.py, I get the following

Traceback (most recent call last):
  File ".../bin/mypy", line 6, in <module>
    main(__file__)
  File ".../mypy/main.py", line 40, in main
    res = type_check_only(sources, bin_dir, options)
  File ".../mypy/main.py", line 81, in type_check_only
    options=options)
  File ".../mypy/build.py", line 177, in build
    dispatch(sources, manager)
  File ".../mypy/build.py", line 1323, in dispatch
    process_graph(graph, manager)
  File ".../mypy/build.py", line 1461, in process_graph
    process_stale_scc(graph, scc)
  File ".../mypy/build.py", line 1538, in process_stale_scc
    graph[id].type_check()
  File ".../mypy/build.py", line 1301, in type_check
    manager.type_checker.visit_file(self.tree, self.xpath)
  File ".../mypy/checker.py", line 152, in visit_file
    self.accept(d)
  File ".../mypy/checker.py", line 201, in accept
    typ = node.accept(self)
  File ".../mypy/nodes.py", line 660, in accept
    return visitor.visit_class_def(self)
  File ".../mypy/checker.py", line 802, in visit_class_def
    self.accept(defn.defs)
  File ".../mypy/checker.py", line 201, in accept
    typ = node.accept(self)
  File ".../mypy/nodes.py", line 723, in accept
    return visitor.visit_block(self)
  File ".../mypy/checker.py", line 897, in visit_block
    self.accept(s)
  File ".../mypy/checker.py", line 201, in accept
    typ = node.accept(self)
  File ".../mypy/nodes.py", line 475, in accept
    return visitor.visit_func_def(self)
  File ".../mypy/checker.py", line 325, in visit_func_def
    self.check_method_override(defn)
  File ".../mypy/checker.py", line 681, in check_method_override
    self.check_method_or_accessor_override_for_base(defn, base)
  File ".../mypy/checker.py", line 690, in check_method_or_accessor_override_for_base
    self.check_method_override_for_base_with_name(defn, name, base)
  File ".../mypy/checker.py", line 728, in check_method_override_for_base_with_name
    assert original_type is not None
AssertionError: 

*** INTERNAL ERROR ***

/home/machinalis/0/foo/derived.py:4: error: Internal error -- please report a bug at https://github.com/python/mypy/issues

@dmoisset
Copy link
Contributor Author

dmoisset commented Aug 1, 2016

Got it down to a 2 file version

# foo/__init__.py
import foo.base

class Derived(foo.base.Base):
    def method(self) -> None:
        pass

# foo/base.py
import foo

class Base:

    @decorator
    def method(self) -> None:
        pass

@gvanrossum
Copy link
Member

Where is @decorator defined? Or is its undefined-ness necessary to repro this case? Also, does it not repro if Derived and Base live in the same file?

@dmoisset
Copy link
Contributor Author

dmoisset commented Aug 1, 2016

On the original code it was imported from yet another module (which was unannotated), but it wasn't required to reproduce the crash (as I mentioned the code is silly and doesn't run). If I define a dummy implementation, the crash goes away.

I couldn't reproduce in a single file scenario, or even removing the (unused) import foo in base.py

@gvanrossum
Copy link
Member

gvanrossum commented Aug 1, 2016 via email

@dmoisset
Copy link
Contributor Author

dmoisset commented Aug 1, 2016

Let me clarify my previous message, it might have been confusing

  • Yes, the definition for "decorator" is intentionally missing in the code snippet, mypy crashes on the code as shown (i.e. with the missing definition)
  • If I add a decorator definition to the snippet and re-run mypy on that, mypy doesn't crash (it shows some type errors which are actual errors).

To clarify: I expect mypy here to just tell me that "decorator isn't defined" but the observed behaviour is the "*** INTERNAL ERROR ***" shown.

@gvanrossum
Copy link
Member

OK, I can repro, and I have one simplification: in foo/__init__.py it is sufficient to write from derived import Derived -- there's no import * needed here to repro the crash. But the rest is all needed. I suspect it's one of the many cases where due to a previous error message something is not fully initialized.

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

No branches or pull requests

3 participants