def cfn_json_object()

in src/cfnlint/decode/cfn_json.py [0:0]


    def cfn_json_object(self, s_and_end, strict, scan_once, object_hook, object_pairs_hook,
                        memo=None, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
        """ Custom Cfn JSON Object to store keys with start and end times """
        s, end = s_and_end
        orginal_end = end
        pairs = []
        pairs_append = pairs.append
        # Backwards compatibility
        if memo is None:
            memo = {}
        memo_get = memo.setdefault
        # Use a slice to prevent IndexError from being raised, the following
        # check will raise a more specific ValueError if the string is empty
        nextchar = s[end:end + 1]
        # Normally we expect nextchar == '"'
        if nextchar != '"':
            if nextchar in _ws:
                end = _w(s, end).end()
                nextchar = s[end:end + 1]
            # Trivial empty object
            if nextchar == '}':
                if object_pairs_hook is not None:
                    try:
                        beg_mark, end_mark = get_beg_end_mark(orginal_end, end + 1, self.newline_indexes)
                        result = object_pairs_hook(pairs, beg_mark, end_mark)
                        return result, end + 1
                    except DuplicateError as err:
                        raise JSONDecodeError(
                            doc=s,
                            pos=end,
                            errors=[
                                build_match_from_node(
                                    message='Duplicate found {}'.format(err),
                                    node=err.mapping,
                                    key=err.key,
                                ),
                                build_match(
                                    message='Duplicate found {}'.format(err),
                                    doc=s,
                                    pos=end,
                                ),
                            ]
                        )
                    except NullError as err:
                        raise JSONDecodeError(
                            doc=s,
                            pos=end,
                            errors=[
                                build_match(
                                    message='Null Error {}'.format(err),
                                    doc=s,
                                    pos=end,
                                ),
                            ]
                        )
                pairs = {}
                if object_hook is not None:
                    beg_mark, end_mark = get_beg_end_mark(orginal_end, end + 1, self.newline_indexes)
                    pairs = object_hook(pairs, beg_mark, end_mark)
                return pairs, end + 1

            if nextchar != '"':
                raise JSONDecodeError(
                    doc=s,
                    pos=end,
                    errors=[
                        build_match(
                            message='Expecting property name enclosed in double quotes',
                            doc=s,
                            pos=end,
                        ),
                    ]
                )
        end += 1
        while True:
            begin = end - 1
            key, end = py_scanstring(s, end, strict)
            # print(lineno, colno, obj)
            # print(key, lineno, colno)
            key = memo_get(key, key)
            # To skip some function call overhead we optimize the fast paths where
            # the JSON key separator is ": " or just ":".
            if s[end:end + 1] != ':':
                end = _w(s, end).end()
                if s[end:end + 1] != ':':
                    raise JSONDecodeError(
                        doc=s,
                        pos=end,
                        errors=[
                            build_match(
                                message='Expecting \':\' delimiter',
                                doc=s,
                                pos=end,
                            ),
                        ]
                    )
            end += 1

            try:
                if s[end] in _ws:
                    end += 1
                    if s[end] in _ws:
                        end = _w(s, end + 1).end()
            except IndexError:
                pass

            beg_mark, end_mark = get_beg_end_mark(begin, begin + len(key), self.newline_indexes)
            try:
                value, end = scan_once(s, end)
            except StopIteration as err:
                raise JSONDecodeError(
                    doc=s,
                    pos=str(err),
                    errors=[
                        build_match(
                            message='Expecting value',
                            doc=s,
                            pos=str(err),
                        ),
                    ]
                )
            key_str = str_node(key, beg_mark, end_mark)
            pairs_append((key_str, value))
            try:
                nextchar = s[end]
                if nextchar in _ws:
                    end = _w(s, end + 1).end()
                    nextchar = s[end]
            except IndexError:
                nextchar = ''
            end += 1

            if nextchar == '}':
                break
            if nextchar != ',':
                raise JSONDecodeError(
                    doc=s,
                    pos=end - 1,
                    errors=[
                        build_match(
                            message='Expecting \',\' delimiter',
                            doc=s,
                            pos=end - 1,
                        ),
                    ]
                )
            end = _w(s, end).end()
            nextchar = s[end:end + 1]
            end += 1
            if nextchar != '"':
                raise JSONDecodeError(
                    doc=s,
                    pos=end - 1,
                    errors=[
                        build_match(
                            message='Expecting property name enclosed in double quotes',
                            doc=s,
                            pos=end - 1,
                        ),
                    ]
                )
        if object_pairs_hook is not None:
            try:
                beg_mark, end_mark = get_beg_end_mark(orginal_end, end, self.newline_indexes)
                result = object_pairs_hook(pairs, beg_mark, end_mark)
            except DuplicateError as err:
                raise JSONDecodeError(
                    doc=s,
                    pos=end,
                    errors=[
                        build_match_from_node(
                            message='Duplicate found {}'.format(err),
                            node=err.mapping,
                            key=err.key,
                        ),
                        build_match(
                            message='Duplicate found {}'.format(err),
                            doc=s,
                            pos=end,
                        ),
                    ]
                )
            except NullError as err:
                raise JSONDecodeError(
                    doc=s,
                    pos=end,
                    errors=[
                        build_match(
                            message='Null Error {}'.format(err),
                            doc=s,
                            pos=end,
                        ),
                    ]
                )
            return result, end

        pairs = dict(pairs)
        if object_hook is not None:
            beg_mark, end_mark = get_beg_end_mark(orginal_end, end, self.newline_indexes)
            pairs = object_hook(pairs, beg_mark, end_mark)
        return pairs, end