Repository: python/mypy

Issue:
Crash when passing non-existant directory as --custom-typeshed-dir
Run mypy 0.550:

`mypy --show-traceback --custom-typeshed-dir does_not_exist file.py`

Where `does_not_exist` is any nonexistant directory.

This results in the following traceback:

```
file.py: error: Name '__builtins__' is not defined
file.py:1: error: Cannot find module named 'builtins'
file.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
file.py:1: error: INTERNAL ERROR -- please report a bug at https://github.com/python/mypy/issues version: 0.550
Traceback (most recent call last):
  File "/Users/joshstaiger/anaconda/bin/mypy", line 11, in <module>
    sys.exit(console_entry())
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/__main__.py", line 7, in console_entry
    main(None)
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/main.py", line 66, in main
    res = type_check_only(sources, bin_dir, options)
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/main.py", line 119, in type_check_only
    options=options)
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/build.py", line 214, in build
    graph = dispatch(sources, manager)
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/build.py", line 1935, in dispatch
    process_graph(graph, manager)
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/build.py", line 2199, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/build.py", line 2327, in process_stale_scc
    graph[id].type_check_first_pass()
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/build.py", line 1836, in type_check_first_pass
    self.type_checker.check_first_pass()
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/checker.py", line 196, in check_first_pass
    self.accept(d)
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/checker.py", line 283, in accept
    stmt.accept(self)
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/nodes.py", line 764, in accept
    return visitor.visit_expression_stmt(self)
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/checker.py", line 2072, in visit_expression_stmt
    self.expr_checker.accept(s.expr, allow_none_return=True, always_allow_any=True)
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/checkexpr.py", line 2363, in accept
    typ = node.accept(self)
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/nodes.py", line 1024, in accept
    return visitor.visit_int_expr(self)
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/checkexpr.py", line 1320, in visit_int_expr
    return self.named_type('builtins.int')
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/checkexpr.py", line 2387, in named_type
    return self.chk.named_type(name)
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/checker.py", line 2636, in named_type
    sym = self.lookup_qualified(name)
  File "/Users/joshstaiger/anaconda/lib/python3.6/site-packages/mypy/checker.py", line 2702, in lookup_qualified
    n = self.modules[parts[0]]
KeyError: 'builtins'
file.py:1: : note: use --pdb to drop into pdb
```

This is on Mac OS El Capitan 10.11.6, if that happens to make a difference. 


Discussion:
On master I see a different traceback, but it still crashes:
```
tst23.py: error: Name '__builtins__' is not defined
tst23.py:1: error: No library stub file for standard library module 'typing'
tst23.py:1: note: (Stub files are from https://github.com/python/typeshed)
tst23.py:1: error: Cannot find module named 'builtins'
tst23.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
tst23.py:3: error: No library stub file for standard library module 'enum'
tst23.py:5: error: INTERNAL ERROR -- please report a bug at https://github.com/python/mypy/issues version: 0.560-dev-28a0e0a0f4dcf14e54846cba9348a3aee80aa791
Traceback (most recent call last):
  File "/usr/local/bin/mypy", line 11, in <module>
    load_entry_point('mypy===0.560-dev-28a0e0a0f4dcf14e54846cba9348a3aee80aa791', 'console_scripts', 'mypy')()
  File "/usr/local/lib/python3.4/dist-packages/mypy/__main__.py", line 7, in console_entry
    main(None)
  File "/usr/local/lib/python3.4/dist-packages/mypy/main.py", line 66, in main
    res = type_check_only(sources, bin_dir, options)
  File "/usr/local/lib/python3.4/dist-packages/mypy/main.py", line 119, in type_check_only
    options=options)
  File "/usr/local/lib/python3.4/dist-packages/mypy/build.py", line 216, in build
    graph = dispatch(sources, manager)
  File "/usr/local/lib/python3.4/dist-packages/mypy/build.py", line 1943, in dispatch
    process_graph(graph, manager)
  File "/usr/local/lib/python3.4/dist-packages/mypy/build.py", line 2230, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/usr/local/lib/python3.4/dist-packages/mypy/build.py", line 2397, in process_stale_scc
    graph[id].semantic_analysis()
  File "/usr/local/lib/python3.4/dist-packages/mypy/build.py", line 1817, in semantic_analysis
    self.manager.semantic_analyzer.visit_file(self.tree, self.xpath, self.options, patches)
  File "/usr/local/lib/python3.4/dist-packages/mypy/semanal.py", line 287, in visit_file
    self.accept(d)
  File "/usr/local/lib/python3.4/dist-packages/mypy/semanal.py", line 3860, in accept
    node.accept(self)
  File "/usr/local/lib/python3.4/dist-packages/mypy/nodes.py", line 690, in accept
    return visitor.visit_class_def(self)
  File "/usr/local/lib/python3.4/dist-packages/mypy/semanal.py", line 663, in visit_class_def
    with self.analyze_class_body(defn) as should_continue:
  File "/usr/lib/python3.4/contextlib.py", line 59, in __enter__
    return next(self.gen)
  File "/usr/local/lib/python3.4/dist-packages/mypy/semanal.py", line 712, in analyze_class_body
    self.analyze_base_classes(defn)
  File "/usr/local/lib/python3.4/dist-packages/mypy/semanal.py", line 1070, in analyze_base_classes
    base_types.append(self.object_type())
  File "/usr/local/lib/python3.4/dist-packages/mypy/semanal.py", line 1226, in object_type
    return self.named_type('__builtins__.object')
  File "/usr/local/lib/python3.4/dist-packages/mypy/semanal.py", line 1243, in named_type
    assert sym, "Internal error: attempted to construct unknown type"
AssertionError: Internal error: attempted to construct unknown type
```
I thought there was a check somewhere that verified typeshed is functional?
Or was that a plan that was never carried out?

(I first thought this could be avoided by checking that the directory
exists, but that doesn't help -- an empty directory is just as bad.)

> Or was that a plan that was never carried out?

There is an old related issue https://github.com/python/mypy/issues/1876, I think this is still only a plan.

Resolving patch:
diff --git a/mypy/build.py b/mypy/build.py
--- a/mypy/build.py
+++ b/mypy/build.py
@@ -651,12 +651,16 @@ def parse_file(self, id: str, path: str, source: str, ignore_errors: bool) -> My
         self.errors.set_file_ignored_lines(path, tree.ignored_lines, ignore_errors)
         return tree
 
-    def module_not_found(self, path: str, id: str, line: int, target: str) -> None:
-        self.errors.set_file(path, id)
+    def module_not_found(self, path: str, source: str, line: int, target: str) -> None:
+        self.errors.set_file(path, source)
         stub_msg = "(Stub files are from https://github.com/python/typeshed)"
-        if ((self.options.python_version[0] == 2 and moduleinfo.is_py2_std_lib_module(target)) or
-                (self.options.python_version[0] >= 3 and
-                 moduleinfo.is_py3_std_lib_module(target))):
+        if target == 'builtins':
+            self.errors.report(line, 0, "Cannot find 'builtins' module. Typeshed appears broken!",
+                               blocker=True)
+            self.errors.raise_error()
+        elif ((self.options.python_version[0] == 2 and moduleinfo.is_py2_std_lib_module(target))
+              or (self.options.python_version[0] >= 3
+                  and moduleinfo.is_py3_std_lib_module(target))):
             self.errors.report(
                 line, 0, "No library stub file for standard library module '{}'".format(target))
             self.errors.report(line, 0, stub_msg, severity='note', only_once=True)


Test patch: