# Buggy code
def write_cache(self) -> None:
    assert self.tree is not None, (
        "Internal error: method must be called on parsed file only"
    )
    if not self.path or self.options.cache_dir == os.devnull:
        return
    if self.manager.options.quick_and_dirty:
        is_errors = self.manager.errors.is_errors_for_file(self.path)
    else:
        is_errors = self.manager.errors.is_errors()
    if is_errors:
        return
    dep_prios = [self.priorities.get(dep, PRI_HIGH) for dep in self.dependencies]
    new_interface_hash = write_cache(
        self.id,
        self.path,
        self.tree,
        list(self.dependencies),
        list(self.suppressed),
        list(self.child_modules),
        dep_prios,
        self.interface_hash,
        self.source_hash,
        self.ignore_all,
        self.manager,
    )
    if new_interface_hash == self.interface_hash:
        self.manager.log("Cached module {} has same interface".format(self.id))
    else:
        self.manager.log("Cached module {} has changed interface".format(self.id))
        self.mark_interface_stale()
        self.interface_hash = new_interface_hash


# Traceback (AssertionError)
$ bin/mypy python/
Traceback (most recent call last):
File "bin/mypy", line 33, in <module>
sys.exit(console_entry())
File "dist/lib/python3.6/mypy/__main__.py", line 7, in console_entry
main(None)
File "dist/lib/python3.6/mypy/main.py", line 50, in main
res = type_check_only(sources, bin_dir, options)
File "dist/lib/python3.6/mypy/main.py", line 97, in type_check_only
options=options)
File "dist/lib/python3.6/mypy/build.py", line 196, in build
graph = dispatch(sources, manager)
File "dist/lib/python3.6/mypy/build.py", line 1801, in dispatch
process_graph(graph, manager)
File "dist/lib/python3.6/mypy/build.py", line 2037, in process_graph
process_fresh_scc(graph, prev_scc)
File "dist/lib/python3.6/mypy/build.py", line 2106, in process_fresh_scc
graph[id].fix_cross_refs()
File "dist/lib/python3.6/mypy/build.py", line 1547, in fix_cross_refs
self.manager.options.quick_and_dirty)
File "dist/lib/python3.6/mypy/fixup.py", line 22, in fixup_module_pass_one
node_fixer.visit_symbol_table(tree.names)
File "dist/lib/python3.6/mypy/fixup.py", line 105, in visit_symbol_table
self.visit_type_info(value.node)
File "dist/lib/python3.6/mypy/fixup.py", line 62, in visit_type_info
base.accept(self.type_fixer)
File "dist/lib/python3.6/mypy/types.py", line 435, in accept
return visitor.visit_instance(self)
File "dist/lib/python3.6/mypy/fixup.py", line 176, in visit_instance
assert self.quick_and_dirty, "Should never get here in normal mode"
AssertionError: Should never get here in normal mode

# Fixed code
def write_cache(self) -> None:
    assert self.tree is not None, (
        "Internal error: method must be called on parsed file only"
    )
    if not self.path or self.options.cache_dir == os.devnull:
        return
    if self.manager.options.quick_and_dirty:
        is_errors = self.manager.errors.is_errors_for_file(self.path)
    else:
        is_errors = self.manager.errors.is_errors()
    if is_errors:
        delete_cache(self.id, self.path, self.manager)
        self.mark_interface_stale(on_errors=True)
        return
    dep_prios = [self.priorities.get(dep, PRI_HIGH) for dep in self.dependencies]
    new_interface_hash = write_cache(
        self.id,
        self.path,
        self.tree,
        list(self.dependencies),
        list(self.suppressed),
        list(self.child_modules),
        dep_prios,
        self.interface_hash,
        self.source_hash,
        self.ignore_all,
        self.manager,
    )
    if new_interface_hash == self.interface_hash:
        self.manager.log("Cached module {} has same interface".format(self.id))
    else:
        self.manager.log("Cached module {} has changed interface".format(self.id))
        self.mark_interface_stale()
        self.interface_hash = new_interface_hash