# Buggy code
def transform(self) -> None:
    """Apply all the necessary transformations to the underlying
    dataclass so as to ensure it is fully type checked according
    to the rules in PEP 557.
    """
    ctx = self._ctx
    info = self._ctx.cls.info
    attributes = self.collect_attributes()
    if attributes is None:
        # Some definitions are not ready, defer() should be already called.
        return
    for attr in attributes:
        if info[attr.name].type is None:
            ctx.api.defer()
            return
    decorator_arguments = {
        "init": _get_decorator_bool_argument(self._ctx, "init", True),
        "eq": _get_decorator_bool_argument(self._ctx, "eq", True),
        "order": _get_decorator_bool_argument(self._ctx, "order", False),
        "frozen": _get_decorator_bool_argument(self._ctx, "frozen", False),
    }

    # If there are no attributes, it may be that the new semantic analyzer has not
    # processed them yet. In order to work around this, we can simply skip generating
    # __init__ if there are no attributes, because if the user truly did not define any,
    # then the object default __init__ with an empty signature will be present anyway.
    if (
        decorator_arguments["init"]
        and ("__init__" not in info.names or info.names["__init__"].plugin_generated)
        and attributes
    ):
        add_method(
            ctx,
            "__init__",
            args=[attr.to_argument(info) for attr in attributes if attr.is_in_init],
            return_type=NoneType(),
        )

    if (
        decorator_arguments["eq"]
        and info.get("__eq__") is None
        or decorator_arguments["order"]
    ):
        # Type variable for self types in generated methods.
        obj_type = ctx.api.named_type("__builtins__.object")
        self_tvar_expr = TypeVarExpr(
            SELF_TVAR_NAME, info.fullname() + "." + SELF_TVAR_NAME, [], obj_type
        )
        info.names[SELF_TVAR_NAME] = SymbolTableNode(MDEF, self_tvar_expr)

    # Add an eq method, but only if the class doesn't already have one.
    if decorator_arguments["eq"] and info.get("__eq__") is None:
        for method_name in ["__eq__", "__ne__"]:
            # The TVar is used to enforce that "other" must have
            # the same type as self (covariant).  Note the
            # "self_type" parameter to add_method.
            obj_type = ctx.api.named_type("__builtins__.object")
            cmp_tvar_def = TypeVarDef(
                SELF_TVAR_NAME, info.fullname() + "." + SELF_TVAR_NAME, -1, [], obj_type
            )
            cmp_other_type = TypeVarType(cmp_tvar_def)
            cmp_return_type = ctx.api.named_type("__builtins__.bool")

            add_method(
                ctx,
                method_name,
                args=[
                    Argument(
                        Var("other", cmp_other_type), cmp_other_type, None, ARG_POS
                    )
                ],
                return_type=cmp_return_type,
                self_type=cmp_other_type,
                tvar_def=cmp_tvar_def,
            )

    # Add <, >, <=, >=, but only if the class has an eq method.
    if decorator_arguments["order"]:
        if not decorator_arguments["eq"]:
            ctx.api.fail("eq must be True if order is True", ctx.cls)

        for method_name in ["__lt__", "__gt__", "__le__", "__ge__"]:
            # Like for __eq__ and __ne__, we want "other" to match
            # the self type.
            obj_type = ctx.api.named_type("__builtins__.object")
            order_tvar_def = TypeVarDef(
                SELF_TVAR_NAME, info.fullname() + "." + SELF_TVAR_NAME, -1, [], obj_type
            )
            order_other_type = TypeVarType(order_tvar_def)
            order_return_type = ctx.api.named_type("__builtins__.bool")
            order_args = [
                Argument(
                    Var("other", order_other_type), order_other_type, None, ARG_POS
                )
            ]

            existing_method = info.get(method_name)
            if existing_method is not None and not existing_method.plugin_generated:
                assert existing_method.node
                ctx.api.fail(
                    "You may not have a custom %s method when order=True" % method_name,
                    existing_method.node,
                )

            add_method(
                ctx,
                method_name,
                args=order_args,
                return_type=order_return_type,
                self_type=order_other_type,
                tvar_def=order_tvar_def,
            )

    if decorator_arguments["frozen"]:
        self._freeze(attributes)

    self.reset_init_only_vars(info, attributes)

    info.metadata["dataclass"] = {
        "attributes": OrderedDict((attr.name, attr.serialize()) for attr in attributes),
        "frozen": decorator_arguments["frozen"],
    }


# Traceback (KeyError)
$ ~/src/mypy/venv/bin/mypy test.py --show-traceback
test.py:10: error: INTERNAL ERROR -- Please try using mypy master on Github:
https://mypy.rtfd.io/en/latest/common_issues.html#using-a-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 0.730+dev.c610a312853921d09083f7525c183810e4232056
Traceback (most recent call last):
File "/home/josh/src/mypy/venv/bin/mypy", line 10, in <module>
sys.exit(console_entry())
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/__main__.py", line 8, in console_entry
main(None, sys.stdout, sys.stderr)
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/main.py", line 83, in main
res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/build.py", line 162, in build
result = _build(sources, options, alt_lib_path, flush_errors, fscache, stdout, stderr)
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/build.py", line 224, in _build
graph = dispatch(sources, manager, stdout)
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/build.py", line 2559, in dispatch
process_graph(graph, manager)
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/build.py", line 2868, in process_graph
process_stale_scc(graph, scc, manager)
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/build.py", line 2961, in process_stale_scc
semantic_analysis_for_scc(graph, scc, manager.errors)
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/semanal_main.py", line 77, in semantic_analysis_for_scc
process_top_levels(graph, scc, patches)
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/semanal_main.py", line 202, in process_top_levels
patches)
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/semanal_main.py", line 330, in semantic_analyze_target
active_type=active_type)
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/semanal.py", line 376, in refresh_partial
self.refresh_top_level(node)
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/semanal.py", line 387, in refresh_top_level
self.accept(d)
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/semanal.py", line 4591, in accept
node.accept(self)
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/nodes.py", line 925, in accept
return visitor.visit_class_def(self)
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/semanal.py", line 1011, in visit_class_def
self.analyze_class(defn)
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/semanal.py", line 1082, in analyze_class
self.analyze_class_body_common(defn)
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/semanal.py", line 1091, in analyze_class_body_common
self.apply_class_plugin_hooks(defn)
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/semanal.py", line 1136, in apply_class_plugin_hooks
hook(ClassDefContext(defn, decorator, self))
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/plugins/dataclasses.py", line 352, in dataclass_class_maker_callback
transformer.transform()
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/plugins/dataclasses.py", line 84, in transform
if info[attr.name].type is None:
File "/home/josh/src/mypy/venv/lib/python3.7/site-packages/mypy/nodes.py", line 2428, in __getitem__
raise KeyError(name)
KeyError: '_dummy'
test.py:10: : note: use --pdb to drop into pdb

# Fixed code
def transform(self) -> None:
    """Apply all the necessary transformations to the underlying
    dataclass so as to ensure it is fully type checked according
    to the rules in PEP 557.
    """
    ctx = self._ctx
    info = self._ctx.cls.info
    attributes = self.collect_attributes()
    if attributes is None:
        # Some definitions are not ready, defer() should be already called.
        return
    for attr in attributes:
        node = info.get(attr.name)
        if node is None:
            # Nodes of superclass InitVars not used in __init__ cannot be reached.
            assert attr.is_init_var and not attr.is_in_init
            continue
        if node.type is None:
            ctx.api.defer()
            return
    decorator_arguments = {
        "init": _get_decorator_bool_argument(self._ctx, "init", True),
        "eq": _get_decorator_bool_argument(self._ctx, "eq", True),
        "order": _get_decorator_bool_argument(self._ctx, "order", False),
        "frozen": _get_decorator_bool_argument(self._ctx, "frozen", False),
    }

    # If there are no attributes, it may be that the new semantic analyzer has not
    # processed them yet. In order to work around this, we can simply skip generating
    # __init__ if there are no attributes, because if the user truly did not define any,
    # then the object default __init__ with an empty signature will be present anyway.
    if (
        decorator_arguments["init"]
        and ("__init__" not in info.names or info.names["__init__"].plugin_generated)
        and attributes
    ):
        add_method(
            ctx,
            "__init__",
            args=[attr.to_argument(info) for attr in attributes if attr.is_in_init],
            return_type=NoneType(),
        )

    if (
        decorator_arguments["eq"]
        and info.get("__eq__") is None
        or decorator_arguments["order"]
    ):
        # Type variable for self types in generated methods.
        obj_type = ctx.api.named_type("__builtins__.object")
        self_tvar_expr = TypeVarExpr(
            SELF_TVAR_NAME, info.fullname() + "." + SELF_TVAR_NAME, [], obj_type
        )
        info.names[SELF_TVAR_NAME] = SymbolTableNode(MDEF, self_tvar_expr)

    # Add an eq method, but only if the class doesn't already have one.
    if decorator_arguments["eq"] and info.get("__eq__") is None:
        for method_name in ["__eq__", "__ne__"]:
            # The TVar is used to enforce that "other" must have
            # the same type as self (covariant).  Note the
            # "self_type" parameter to add_method.
            obj_type = ctx.api.named_type("__builtins__.object")
            cmp_tvar_def = TypeVarDef(
                SELF_TVAR_NAME, info.fullname() + "." + SELF_TVAR_NAME, -1, [], obj_type
            )
            cmp_other_type = TypeVarType(cmp_tvar_def)
            cmp_return_type = ctx.api.named_type("__builtins__.bool")

            add_method(
                ctx,
                method_name,
                args=[
                    Argument(
                        Var("other", cmp_other_type), cmp_other_type, None, ARG_POS
                    )
                ],
                return_type=cmp_return_type,
                self_type=cmp_other_type,
                tvar_def=cmp_tvar_def,
            )

    # Add <, >, <=, >=, but only if the class has an eq method.
    if decorator_arguments["order"]:
        if not decorator_arguments["eq"]:
            ctx.api.fail("eq must be True if order is True", ctx.cls)

        for method_name in ["__lt__", "__gt__", "__le__", "__ge__"]:
            # Like for __eq__ and __ne__, we want "other" to match
            # the self type.
            obj_type = ctx.api.named_type("__builtins__.object")
            order_tvar_def = TypeVarDef(
                SELF_TVAR_NAME, info.fullname() + "." + SELF_TVAR_NAME, -1, [], obj_type
            )
            order_other_type = TypeVarType(order_tvar_def)
            order_return_type = ctx.api.named_type("__builtins__.bool")
            order_args = [
                Argument(
                    Var("other", order_other_type), order_other_type, None, ARG_POS
                )
            ]

            existing_method = info.get(method_name)
            if existing_method is not None and not existing_method.plugin_generated:
                assert existing_method.node
                ctx.api.fail(
                    "You may not have a custom %s method when order=True" % method_name,
                    existing_method.node,
                )

            add_method(
                ctx,
                method_name,
                args=order_args,
                return_type=order_return_type,
                self_type=order_other_type,
                tvar_def=order_tvar_def,
            )

    if decorator_arguments["frozen"]:
        self._freeze(attributes)

    self.reset_init_only_vars(info, attributes)

    info.metadata["dataclass"] = {
        "attributes": OrderedDict((attr.name, attr.serialize()) for attr in attributes),
        "frozen": decorator_arguments["frozen"],
    }