# Buggy code
def check_namedtuple(
    self, node: Expression, var_name: Optional[str], is_func_scope: bool
) -> Optional[TypeInfo]:
    """Check if a call defines a namedtuple.

    The optional var_name argument is the name of the variable to
    which this is assigned, if any.

    If it does, return the corresponding TypeInfo. Return None otherwise.

    If the definition is invalid but looks like a namedtuple,
    report errors but return (some) TypeInfo.
    """
    if not isinstance(node, CallExpr):
        return None
    call = node
    callee = call.callee
    if not isinstance(callee, RefExpr):
        return None
    fullname = callee.fullname
    if fullname == "collections.namedtuple":
        is_typed = False
    elif fullname == "typing.NamedTuple":
        is_typed = True
    else:
        return None
    items, types, defaults, ok = self.parse_namedtuple_args(call, fullname)
    if not ok:
        # Error. Construct dummy return value.
        return self.build_namedtuple_typeinfo("namedtuple", [], [], {})
    name = cast(StrExpr, call.args[0]).value
    if name != var_name or is_func_scope:
        # Give it a unique name derived from the line number.
        name += "@" + str(call.line)
    if len(defaults) > 0:
        default_items = {
            arg_name: default
            for arg_name, default in zip(items[-len(defaults) :], defaults)
        }
    else:
        default_items = {}
    info = self.build_namedtuple_typeinfo(name, items, types, default_items)
    # Store it as a global just in case it would remain anonymous.
    # (Or in the nearest class if there is one.)
    stnode = SymbolTableNode(GDEF, info)
    self.api.add_symbol_table_node(name, stnode)
    call.analyzed = NamedTupleExpr(info, is_typed=is_typed)
    call.analyzed.set_line(call.line, call.column)
    return info


# Traceback (AssertionError)
Traceback (most recent call last):
File "/usr/lib/python3.5/runpy.py", line 184, in _run_module_as_main
"__main__", mod_spec)
File "/usr/lib/python3.5/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/home/user/src/server/.mypy/venv/lib/python3.5/site-packages/mypy/__main__.py", line 11, in <module>
main(None)
File "/home/user/src/server/.mypy/venv/lib/python3.5/site-packages/mypy/main.py", line 66, in main
res = type_check_only(sources, bin_dir, options)
File "/home/user/src/server/.mypy/venv/lib/python3.5/site-packages/mypy/main.py", line 119, in type_check_only
options=options)
File "/home/user/src/server/.mypy/venv/lib/python3.5/site-packages/mypy/build.py", line 212, in build
graph = dispatch(sources, manager)
File "/home/user/src/server/.mypy/venv/lib/python3.5/site-packages/mypy/build.py", line 1939, in dispatch
process_graph(graph, manager)
File "/home/user/src/server/.mypy/venv/lib/python3.5/site-packages/mypy/build.py", line 2219, in process_graph
process_fresh_scc(graph, prev_scc, manager)
File "/home/user/src/server/.mypy/venv/lib/python3.5/site-packages/mypy/build.py", line 2296, in process_fresh_scc
graph[id].fix_cross_refs()
File "/home/user/src/server/.mypy/venv/lib/python3.5/site-packages/mypy/build.py", line 1656, in fix_cross_refs
self.manager.options.quick_and_dirty)
File "/home/user/src/server/.mypy/venv/lib/python3.5/site-packages/mypy/fixup.py", line 22, in fixup_module_pass_one
node_fixer.visit_symbol_table(tree.names)
File "/home/user/src/server/.mypy/venv/lib/python3.5/site-packages/mypy/fixup.py", line 84, in visit_symbol_table
self.quick_and_dirty)
File "/home/user/src/server/.mypy/venv/lib/python3.5/site-packages/mypy/fixup.py", line 284, in lookup_qualified_stnode
assert key in names, "Cannot find %s for %s" % (key, name)
AssertionError: Cannot find namedtuple for metaserver.lib.deletion_filter.namedtuple

# Fixed code
def check_namedtuple(
    self, node: Expression, var_name: Optional[str], is_func_scope: bool
) -> Optional[TypeInfo]:
    """Check if a call defines a namedtuple.

    The optional var_name argument is the name of the variable to
    which this is assigned, if any.

    If it does, return the corresponding TypeInfo. Return None otherwise.

    If the definition is invalid but looks like a namedtuple,
    report errors but return (some) TypeInfo.
    """
    if not isinstance(node, CallExpr):
        return None
    call = node
    callee = call.callee
    if not isinstance(callee, RefExpr):
        return None
    fullname = callee.fullname
    if fullname == "collections.namedtuple":
        is_typed = False
    elif fullname == "typing.NamedTuple":
        is_typed = True
    else:
        return None
    items, types, defaults, ok = self.parse_namedtuple_args(call, fullname)
    if not ok:
        # Error. Construct dummy return value.
        if var_name:
            name = var_name
        else:
            name = "namedtuple@" + str(call.line)
        info = self.build_namedtuple_typeinfo(name, [], [], {})
        self.store_namedtuple_info(info, name, call, is_typed)
        return info
    name = cast(StrExpr, call.args[0]).value
    if name != var_name or is_func_scope:
        # Give it a unique name derived from the line number.
        name += "@" + str(call.line)
    if len(defaults) > 0:
        default_items = {
            arg_name: default
            for arg_name, default in zip(items[-len(defaults) :], defaults)
        }
    else:
        default_items = {}
    info = self.build_namedtuple_typeinfo(name, items, types, default_items)
    # Store it as a global just in case it would remain anonymous.
    # (Or in the nearest class if there is one.)
    self.store_namedtuple_info(info, name, call, is_typed)
    return info