# Buggy code
def create_dict_node_class(cls):
    """
    Create dynamic node class
    """

    class node_class(cls):
        """Node class created based on the input class"""

        def __init__(self, x, start_mark, end_mark):
            try:
                cls.__init__(self, x)
            except TypeError:
                cls.__init__(self)
            self.start_mark = start_mark
            self.end_mark = end_mark
            self.condition_functions = ["Fn::If"]

        def __deepcopy__(self, memo):
            cls = self.__class__
            result = cls.__new__(cls, self.start_mark, self.end_mark)
            memo[id(self)] = result
            for k, v in self.items():
                result[deepcopy(k)] = deepcopy(v, memo)

            return result

        def __copy__(self):
            return self

        def get_safe(self, key, default=None, path=None, type_t=()):
            """
            Get values in format
            """
            path = path or []
            value = self.get(key, default)
            if not isinstance(value, (dict)):
                if isinstance(value, type_t) or not type_t:
                    return [(value, (path[:] + [key]))]

            results = []
            for sub_v, sub_path in value.items_safe(path):
                if isinstance(sub_v, type_t) or not type_t:
                    results.append((sub_v, sub_path))

            return results

        def items_safe(self, path=None, type_t=()):
            """Get items while handling IFs"""
            path = path or []
            if len(self) == 1:
                for k, v in self.items():
                    if k == "Fn::If":
                        if isinstance(v, list):
                            if len(v) == 3:
                                for i, if_v in enumerate(v[1:]):
                                    if isinstance(if_v, dict):
                                        # yield from if_v.items_safe(path[:] + [k, i - 1])
                                        # Python 2.7 support
                                        for items, p in if_v.items_safe(
                                            path[:] + [k, i + 1]
                                        ):
                                            if isinstance(items, type_t) or not type_t:
                                                yield items, p
                                    elif isinstance(if_v, list):
                                        if isinstance(if_v, type_t) or not type_t:
                                            yield if_v, path[:] + [k, i + 1]
                                    else:
                                        if isinstance(if_v, type_t) or not type_t:
                                            yield if_v, path[:] + [k, i + 1]
                    elif k != "Ref" and v != "AWS::NoValue":
                        if isinstance(self, type_t) or not type_t:
                            yield self, path[:]
            else:
                if isinstance(self, type_t) or not type_t:
                    yield self, path[:]

        def __getattr__(self, name):
            raise TemplateAttributeError(
                "%s.%s is invalid" % (self.__class__.__name__, name)
            )

    node_class.__name__ = "%s_node" % cls.__name__
    return node_class


# Traceback (AttributeError)
Traceback (most recent call last):
File "/usr/local/bin/cfn-lint", line 11, in <module>
sys.exit(main())
File "/usr/local/lib/python2.7/site-packages/cfnlint/__main__.py", line 36, in main
args.regions, args.override_spec))
File "/usr/local/lib/python2.7/site-packages/cfnlint/core.py", line 46, in run_cli
return run_checks(filename, template, rules, regions)
File "/usr/local/lib/python2.7/site-packages/cfnlint/core.py", line 316, in run_checks
matches.extend(runner.transform())
File "/usr/local/lib/python2.7/site-packages/cfnlint/__init__.py", line 894, in transform
matches = transform.transform_template()
File "/usr/local/lib/python2.7/site-packages/cfnlint/transform.py", line 115, in transform_template
sam_translator.translate(sam_template=self._template, parameter_values={}))
File "/Users/eaddingtonwhite/Library/Python/2.7/lib/python/site-packages/samtranslator/translator/translator.py", line 71, in translate
translated = macro.to_cloudformation(**kwargs)
File "/Users/eaddingtonwhite/Library/Python/2.7/lib/python/site-packages/samtranslator/model/sam_resources.py", line 501, in to_cloudformation
rest_api, deployment, stage = api_generator.to_cloudformation()
File "/Users/eaddingtonwhite/Library/Python/2.7/lib/python/site-packages/samtranslator/model/api/api_generator.py", line 160, in to_cloudformation
rest_api = self._construct_rest_api()
File "/Users/eaddingtonwhite/Library/Python/2.7/lib/python/site-packages/samtranslator/model/api/api_generator.py", line 69, in _construct_rest_api
self._add_cors()
File "/Users/eaddingtonwhite/Library/Python/2.7/lib/python/site-packages/samtranslator/model/api/api_generator.py", line 212, in _add_cors
self.definition_body = editor.swagger
File "/Users/eaddingtonwhite/Library/Python/2.7/lib/python/site-packages/samtranslator/swagger/swagger.py", line 298, in swagger
return copy.deepcopy(self._doc)
File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy.py", line 174, in deepcopy
y = copier(memo)
File "/usr/local/lib/python2.7/site-packages/cfnlint/decode/node.py", line 75, in __deepcopy__
result = cls.__new__(cls, self.start_mark, self.end_mark)
AttributeError: 'dict_node' object has no attribute 'start_mark'

# Fixed code
def create_dict_node_class(cls):
    """
    Create dynamic node class
    """

    class node_class(cls):
        """Node class created based on the input class"""

        def __init__(self, x, start_mark, end_mark):
            try:
                cls.__init__(self, x)
            except TypeError:
                cls.__init__(self)
            self.start_mark = start_mark
            self.end_mark = end_mark
            self.condition_functions = ["Fn::If"]

        def __deepcopy__(self, memo):
            result = dict_node(self, self.start_mark, self.end_mark)
            memo[id(self)] = result
            for k, v in self.items():
                result[deepcopy(k)] = deepcopy(v, memo)

            return result

        def __copy__(self):
            return self

        def get_safe(self, key, default=None, path=None, type_t=()):
            """
            Get values in format
            """
            path = path or []
            value = self.get(key, default)
            if not isinstance(value, (dict)):
                if isinstance(value, type_t) or not type_t:
                    return [(value, (path[:] + [key]))]

            results = []
            for sub_v, sub_path in value.items_safe(path):
                if isinstance(sub_v, type_t) or not type_t:
                    results.append((sub_v, sub_path))

            return results

        def items_safe(self, path=None, type_t=()):
            """Get items while handling IFs"""
            path = path or []
            if len(self) == 1:
                for k, v in self.items():
                    if k == "Fn::If":
                        if isinstance(v, list):
                            if len(v) == 3:
                                for i, if_v in enumerate(v[1:]):
                                    if isinstance(if_v, dict):
                                        # yield from if_v.items_safe(path[:] + [k, i - 1])
                                        # Python 2.7 support
                                        for items, p in if_v.items_safe(
                                            path[:] + [k, i + 1]
                                        ):
                                            if isinstance(items, type_t) or not type_t:
                                                yield items, p
                                    elif isinstance(if_v, list):
                                        if isinstance(if_v, type_t) or not type_t:
                                            yield if_v, path[:] + [k, i + 1]
                                    else:
                                        if isinstance(if_v, type_t) or not type_t:
                                            yield if_v, path[:] + [k, i + 1]
                    elif k != "Ref" and v != "AWS::NoValue":
                        if isinstance(self, type_t) or not type_t:
                            yield self, path[:]
            else:
                if isinstance(self, type_t) or not type_t:
                    yield self, path[:]

        def __getattr__(self, name):
            raise TemplateAttributeError(
                "%s.%s is invalid" % (self.__class__.__name__, name)
            )

    node_class.__name__ = "%s_node" % cls.__name__
    return node_class