def _p_fetch_atts(self):

        # Is this a list? If so, parse our list of flags.
        #
        if self._p_simple_string('(', silent = True, swallow = False):
            return self._p_paren_list_of(self._p_fetch_att)
        else:
            # See if we have one of the three defined fetch att macros.
            # If we do we will just by hand create our list of fetch atts
            #
            macro = self._p_re(_fetch_att_macros_re, silent = True)
            if macro is not None:
                # We had a macro.. so depending on which one we construct a
                # list of fetch atts.
                #
                macro = macro.lower()
                if macro == "all":
                    return [ FetchAtt("flags"), FetchAtt("internaldate"),
                             FetchAtt("rfc822.size"), FetchAtt("envelope") ]
                elif macro == "full":
                    return [ FetchAtt("flags"), FetchAtt("internaldate"),
                             FetchAtt("rfc822.size"), FetchAtt("envelope"),
                             FetchAtt("bodystructure", ext_data = False,
                                      actual_command = "BODY") ]
                elif macro == "fast":
                    return [ FetchAtt("flags"), FetchAtt("internaldate"),
                             FetchAtt("rfc822.size") ]
                else:
                    raise BadSyntax(value = "\"%s\" is not a valid fetch " \
                                    "attribute")
            else:
                # Otherwise we have what MUST be a single fetch attribute.
                return [ self._p_fetch_att() ]


    #######################################################################
    #
We have either a single fetch attribute or a list of fetch
dataset/ETHPy150Open scanner/asimap/asimap/parse.py/IMAPClientCommand._p_fetch_atts