def _parseFetchPairs(self, fetchResponseList):
        """
        Given the result of parsing a single I{FETCH} response, construct a
        C{dict} mapping response keys to response values.

        @param fetchResponseList: The result of parsing a I{FETCH} response
            with L{parseNestedParens} and extracting just the response data
            (that is, just the part that comes after C{"FETCH"}).  The form
            of this input (and therefore the output of this method) is very
            disagreable.  A valuable improvement would be to enumerate the
            possible keys (representing them as structured objects of some
            sort) rather than using strings and tuples of tuples of strings
            and so forth.  This would allow the keys to be documented more
            easily and would allow for a much simpler application-facing API
            (one not based on looking up somewhat hard to predict keys in a
            dict).  Since C{fetchResponseList} notionally represents a
            flattened sequence of pairs (identifying keys followed by their
            associated values), collapsing such complex elements of this
            list as C{["BODY", ["HEADER.FIELDS", ["SUBJECT"]]]} into a
            single object would also greatly simplify the implementation of
            this method.

        @return: A C{dict} of the response data represented by C{pairs}.  Keys
            in this dictionary are things like C{"RFC822.TEXT"}, C{"FLAGS"}, or
            C{("BODY", ("HEADER.FIELDS", ("SUBJECT",)))}.  Values are entirely
            dependent on the key with which they are associated, but retain the
            same structured as produced by L{parseNestedParens}.
        """
        values = {}
        responseParts = iter(fetchResponseList)
        while True:
            try:
                key = responseParts.next()
            except StopIteration:
                break

            try:
                value = responseParts.next()
            except StopIteration:
                raise IllegalServerResponse(
                    "Not enough arguments", fetchResponseList)

            # The parsed forms of responses like:
            #
            # BODY[] VALUE
            # BODY[TEXT] VALUE
            # BODY[HEADER.FIELDS (SUBJECT)] VALUE
            # BODY[HEADER.FIELDS (SUBJECT)]<N.M> VALUE
            #
            # are:
            #
            # ["BODY", [], VALUE]
            # ["BODY", ["TEXT"], VALUE]
            # ["BODY", ["HEADER.FIELDS", ["SUBJECT"]], VALUE]
            # ["BODY", ["HEADER.FIELDS", ["SUBJECT"]], "<N.M>", VALUE]
            #
            # Here, check for these cases and grab as many extra elements as
            # necessary to retrieve the body information.
            if key in ("BODY", "BODY.PEEK") and isinstance(value, list) and len(value) < 3:
                if len(value) < 2:
                    key = (key, tuple(value))
                else:
                    key = (key, (value[0], tuple(value[1])))
                try:
                    value = responseParts.next()
                except StopIteration:
                    raise IllegalServerResponse(
                        "Not enough arguments", fetchResponseList)

                # Handle partial ranges
                if value.startswith('<') and value.endswith('>'):
                    try:
                        int(value[1:-1])
                    except ValueError:
                        # This isn't really a range, it's some content.
                        pass
                    else:
                        key = key + (value,)
                        try:
                            value = responseParts.next()
                        except StopIteration:
                            raise IllegalServerResponse(
                                "Not enough arguments", fetchResponseList)

            values[key] = value
        return values
dataset/ETHPy150Open nlloyd/SubliminalCollaborator/libs/twisted/mail/imap4.py/IMAP4Client._parseFetchPairs/original