typeddjango / django-stubs

PEP-484 stubs for Django
MIT License
1.6k stars 449 forks source link

unknown import causes ModuleNotFoundError #329

Open leos opened 4 years ago

leos commented 4 years ago

Bug report

What's wrong

This plugin crashes mypy when there is an unknown import in a source file. Repro is super simple, add from foo import bar to source file, run mypy against it with this plugin.

Actual behavior: uncaught ModuleNotFoundError

Error constructing plugin instance of NewSemanalDjangoPlugin

Traceback (most recent call last):
  File "/Users/leo/Library/Caches/pypoetry/virtualenvs/sprinty-PROX8LVJ-py3.7/bin/mypy", line 10, in <module>
    sys.exit(console_entry())
  File "/Users/leo/Library/Caches/pypoetry/virtualenvs/sprinty-PROX8LVJ-py3.7/lib/python3.7/site-packages/mypy/__main__.py", line 8, in console_entry
    main(None, sys.stdout, sys.stderr)
  File "mypy/main.py", line 89, in main
  File "mypy/build.py", line 166, in build
  File "mypy/build.py", line 213, in _build
  File "mypy/build.py", line 451, in load_plugins
  File "mypy/build.py", line 429, in load_plugins_from_config
  File "/Users/leo/Library/Caches/pypoetry/virtualenvs/sprinty-PROX8LVJ-py3.7/lib/python3.7/site-packages/mypy_django_plugin/main.py", line 80, in __init__
    self.django_context = DjangoContext(django_settings_module)
  File "/Users/leo/Library/Caches/pypoetry/virtualenvs/sprinty-PROX8LVJ-py3.7/lib/python3.7/site-packages/mypy_django_plugin/django/context.py", line 88, in __init__
    apps, settings = initialize_django(self.django_settings_module)
  File "/Users/leo/Library/Caches/pypoetry/virtualenvs/sprinty-PROX8LVJ-py3.7/lib/python3.7/site-packages/mypy_django_plugin/django/context.py", line 72, in initialize_django
    apps.populate(settings.INSTALLED_APPS)
  File "/Users/leo/Library/Caches/pypoetry/virtualenvs/sprinty-PROX8LVJ-py3.7/lib/python3.7/site-packages/django/apps/registry.py", line 114, in populate
    app_config.import_models()
  File "/Users/leo/Library/Caches/pypoetry/virtualenvs/sprinty-PROX8LVJ-py3.7/lib/python3.7/site-packages/django/apps/config.py", line 211, in import_models
    self.models_module = import_module(models_module_name)
  File "/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/Users/leo/test.py", line 7, in <module>
    from foo import bar
ModuleNotFoundError: No module named 'foo'

How is that should be

Expected behavior: mypy works properly and plugin doesn't crash it.

System information

sobolevn commented 4 years ago

This is a known problem. This happens because we run django.setup() inside the plugin. And if your code is broken - the plugin will crash. https://github.com/typeddjango/django-stubs#mypy-crashes-when-i-run-it-with-this-plugin-installed

I guess the only thing we can do is to make better error messages. I will work on it!

leos commented 4 years ago

Thanks for looking at this. I haven't looked deeper at the code but could you just catch the exception, create a mypy warning/error and then simply continue on? The plugin would be effectively disabled until the error was fixed but it wouldn't crash mypy.

sobolevn commented 4 years ago

Yes, this is exactly my plan. By the way, @leos do you want to take this one? I can reassign the issue if you want.

leos commented 4 years ago

I appreciate the offer but I unfortunately don't have the time to dig in right now