# Buggy code
def analyze_type_alias(
    node: Expression,
    lookup_func: Callable[[str, Context], SymbolTableNode],
    lookup_fqn_func: Callable[[str], SymbolTableNode],
    tvar_scope: TypeVarScope,
    fail_func: Callable[[str, Context], None],
    plugin: Plugin,
    options: Options,
    is_typeshed_stub: bool,
    allow_unnormalized: bool = False,
) -> Optional[Type]:
    """Return type if node is valid as a type alias rvalue.

    Return None otherwise. 'node' must have been semantically analyzed.
    """
    # Quickly return None if the expression doesn't look like a type. Note
    # that we don't support straight string literals as type aliases
    # (only string literals within index expressions).
    if isinstance(node, RefExpr):
        # Note that this misses the case where someone tried to use a
        # class-referenced type variable as a type alias.  It's easier to catch
        # that one in checkmember.py
        if node.kind == TVAR:
            fail_func(
                'Type variable "{}" is invalid as target for type alias'.format(
                    node.fullname
                ),
                node,
            )
            return None
        if not (
            isinstance(node.node, TypeInfo)
            or node.fullname == "typing.Any"
            or node.kind == TYPE_ALIAS
        ):
            return None
    elif isinstance(node, IndexExpr):
        base = node.base
        if isinstance(base, RefExpr):
            if not (
                isinstance(base.node, TypeInfo)
                or base.fullname in type_constructors
                or base.kind == TYPE_ALIAS
            ):
                return None
            # Enums can't be generic, and without this check we may incorrectly interpret indexing
            # an Enum class as creating a type alias.
            if isinstance(base.node, TypeInfo) and base.node.is_enum:
                return None
        else:
            return None
    elif isinstance(node, CallExpr):
        if (
            isinstance(node.callee, NameExpr)
            and len(node.args) == 1
            and isinstance(node.args[0], NameExpr)
        ):
            call = lookup_func(node.callee.name, node.callee)
            arg = lookup_func(node.args[0].name, node.args[0])
            if (
                call is not None
                and call.node
                and call.node.fullname() == "builtins.type"
                and arg is not None
                and arg.node
                and arg.node.fullname() == "builtins.None"
            ):
                return NoneTyp()
            return None
        return None
    else:
        return None

    # It's a type alias (though it may be an invalid one).
    try:
        type = expr_to_unanalyzed_type(node)
    except TypeTranslationError:
        fail_func("Invalid type alias", node)
        return None
    analyzer = TypeAnalyser(
        lookup_func,
        lookup_fqn_func,
        tvar_scope,
        fail_func,
        plugin,
        options,
        is_typeshed_stub,
        aliasing=True,
        allow_unnormalized=allow_unnormalized,
    )
    return type.accept(analyzer)


# Traceback (TypeError)
mypy --show-traceback Deduction.py
Deduction.py:102: error: The return type of "__init__" must be None
Deduction.py:103: error: INTERNAL ERROR -- please report a bug at https://github.com/python/mypy/issues version: 0.521-858f7512cf3b4e39c0f4e8de5a13eee0e1e138fb-dirty
Traceback (most recent call last):
File "/usr/local/Cellar/mypy/0.521/libexec/bin/mypy", line 11, in <module>
load_entry_point('mypy===0.521-858f7512cf3b4e39c0f4e8de5a13eee0e1e138fb-dirty', 'console_scripts', 'mypy')()
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/__main__.py", line 7, in console_entry
main(None)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/main.py", line 50, in main
res = type_check_only(sources, bin_dir, options)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/main.py", line 97, in type_check_only
options=options)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/build.py", line 196, in build
graph = dispatch(sources, manager)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/build.py", line 1801, in dispatch
process_graph(graph, manager)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/build.py", line 2044, in process_graph
process_stale_scc(graph, scc, manager)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/build.py", line 2147, in process_stale_scc
graph[id].type_check_first_pass()
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/build.py", line 1716, in type_check_first_pass
self.type_checker.check_first_pass()
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/checker.py", line 185, in check_first_pass
self.accept(d)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/checker.py", line 273, in accept
stmt.accept(self)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/nodes.py", line 754, in accept
return visitor.visit_class_def(self)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/checker.py", line 1109, in visit_class_def
self.accept(defn.defs)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/checker.py", line 273, in accept
stmt.accept(self)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/nodes.py", line 815, in accept
return visitor.visit_block(self)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/checker.py", line 1202, in visit_block
self.accept(s)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/checker.py", line 273, in accept
stmt.accept(self)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/nodes.py", line 565, in accept
return visitor.visit_func_def(self)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/checker.py", line 519, in visit_func_def
self.check_func_item(defn, name=defn.name())
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/checker.py", line 578, in check_func_item
self.check_func_def(defn, typ, name)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/checker.py", line 738, in check_func_def
self.accept(item.body)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/checker.py", line 273, in accept
stmt.accept(self)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/nodes.py", line 815, in accept
return visitor.visit_block(self)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/checker.py", line 1202, in visit_block
self.accept(s)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/checker.py", line 273, in accept
stmt.accept(self)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/nodes.py", line 974, in accept
return visitor.visit_if_stmt(self)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/checker.py", line 1977, in visit_if_stmt
if_map, else_map = self.find_isinstance_check(e)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/checker.py", line 2559, in find_isinstance_check
return find_isinstance_check(n, self.type_map)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/checker.py", line 2810, in find_isinstance_check
return conditional_type_map(expr, vartype, type)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/checker.py", line 2613, in conditional_type_map
and is_proper_subtype(current_type, proposed_type)):
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/subtypes.py", line 569, in is_proper_subtype
return left.accept(ProperSubtypeVisitor(right))
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/types.py", line 1114, in accept
return visitor.visit_union_type(self)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/subtypes.py", line 693, in visit_union_type
return all([is_proper_subtype(item, self.right) for item in left.items])
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/subtypes.py", line 693, in <listcomp>
return all([is_proper_subtype(item, self.right) for item in left.items])
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/subtypes.py", line 569, in is_proper_subtype
return left.accept(ProperSubtypeVisitor(right))
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/types.py", line 900, in accept
return visitor.visit_tuple_type(self)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/subtypes.py", line 671, in visit_tuple_type
if not is_proper_subtype(l, r):
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/subtypes.py", line 569, in is_proper_subtype
return left.accept(ProperSubtypeVisitor(right))
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/types.py", line 435, in accept
return visitor.visit_instance(self)
File "/usr/local/Cellar/mypy/0.521/libexec/lib/python3.6/site-packages/mypy/subtypes.py", line 605, in visit_instance
for base in left.type.mro:
TypeError: 'NoneType' object is not iterable
Deduction.py:103: note: use --pdb to drop into pdb

# Fixed code
def analyze_type_alias(
    node: Expression,
    lookup_func: Callable[[str, Context], SymbolTableNode],
    lookup_fqn_func: Callable[[str], SymbolTableNode],
    tvar_scope: TypeVarScope,
    fail_func: Callable[[str, Context], None],
    note_func: Callable[[str, Context], None],
    plugin: Plugin,
    options: Options,
    is_typeshed_stub: bool,
    allow_unnormalized: bool = False,
    in_dynamic_func: bool = False,
    global_scope: bool = True,
) -> Optional[Type]:
    """Return type if node is valid as a type alias rvalue.

    Return None otherwise. 'node' must have been semantically analyzed.
    """
    # Quickly return None if the expression doesn't look like a type. Note
    # that we don't support straight string literals as type aliases
    # (only string literals within index expressions).
    if isinstance(node, RefExpr):
        # Note that this misses the case where someone tried to use a
        # class-referenced type variable as a type alias.  It's easier to catch
        # that one in checkmember.py
        if node.kind == TVAR:
            fail_func(
                'Type variable "{}" is invalid as target for type alias'.format(
                    node.fullname
                ),
                node,
            )
            return None
        if not (
            isinstance(node.node, TypeInfo)
            or node.fullname == "typing.Any"
            or node.kind == TYPE_ALIAS
        ):
            return None
    elif isinstance(node, IndexExpr):
        base = node.base
        if isinstance(base, RefExpr):
            if not (
                isinstance(base.node, TypeInfo)
                or base.fullname in type_constructors
                or base.kind == TYPE_ALIAS
            ):
                return None
            # Enums can't be generic, and without this check we may incorrectly interpret indexing
            # an Enum class as creating a type alias.
            if isinstance(base.node, TypeInfo) and base.node.is_enum:
                return None
        else:
            return None
    elif isinstance(node, CallExpr):
        if (
            isinstance(node.callee, NameExpr)
            and len(node.args) == 1
            and isinstance(node.args[0], NameExpr)
        ):
            call = lookup_func(node.callee.name, node.callee)
            arg = lookup_func(node.args[0].name, node.args[0])
            if (
                call is not None
                and call.node
                and call.node.fullname() == "builtins.type"
                and arg is not None
                and arg.node
                and arg.node.fullname() == "builtins.None"
            ):
                return NoneTyp()
            return None
        return None
    else:
        return None

    # It's a type alias (though it may be an invalid one).
    try:
        type = expr_to_unanalyzed_type(node)
    except TypeTranslationError:
        fail_func("Invalid type alias", node)
        return None
    analyzer = TypeAnalyser(
        lookup_func,
        lookup_fqn_func,
        tvar_scope,
        fail_func,
        note_func,
        plugin,
        options,
        is_typeshed_stub,
        aliasing=True,
        allow_unnormalized=allow_unnormalized,
    )
    analyzer.in_dynamic_func = in_dynamic_func
    analyzer.global_scope = global_scope
    return type.accept(analyzer)